.Net核心中间件-从请求中获取表单数据 [英] .Net Core Middleware - Getting Form Data from Request

查看:134
本文介绍了.Net核心中间件-从请求中获取表单数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在.NET Core Web应用程序中,我使用中间件(app.UseMyMiddleware)在每个请求上添加一些日志记录:

In a .NET Core Web Application I am using middleware (app.UseMyMiddleware) to add some logging on each request:

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler(MyMiddleware.GenericExceptionHandler);
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseMyMiddleware();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }

        public static void UseMyMiddleware(this IApplicationBuilder app)
        {
            app.Use(async (context, next) =>
            {
                await Task.Run(() => HitDetails.StoreHitDetails(context));
                await next.Invoke();
            });
        }

        public static void StoreHitDetails(HttpContext context)
        {
            var config = (IConfiguration)context.RequestServices.GetService(typeof(IConfiguration));
            var settings = new Settings(config);
            var connectionString = config.GetConnectionString("Common");
            var features = context.Features.Get<IHttpRequestFeature>();
            var url = $"{features.Scheme}://{context.Request.Host.Value}{features.RawTarget}";

            var parameters = new
            {
                SYSTEM_CODE = settings.SystemName,
                REMOTE_HOST = context.Connection.RemoteIpAddress.ToString(),
                HTTP_REFERER = context.Request.Headers["Referer"].ToString(),
                HTTP_URL = url,
                LOCAL_ADDR = context.Connection.LocalIpAddress.ToString(),
                AUTH_USER = context.User.Identity.Name
            };

            using (IDbConnection db = new SqlConnection(connectionString))
            {
                db.Query("StoreHitDetails", parameters, commandType: CommandType.StoredProcedure);
            }
        }

一切正常,我可以从请求中获取大部分需求,但接下来需要的是POST方法上的表单数据.

This all works fine and I can grab most of what I need from the request but what I need next is the Form Data on a POST method.

context.Request.Form是一个可用选项,但是在调试时,我将鼠标悬停在该选项上,请参阅函数评估要求所有线程都必须运行".如果我尝试使用它,应用程序将挂起.

context.Request.Form is an available option but when debugging I hover over it and see "The function evaluation requires all thread to run". If I try to use it the application just hangs.

我需要怎么做才能访问Request.Form,或者我没有看到带有POST数据的替代属性?

What do I need to do to access Request.Form or is there an alternative property with POST data that I'm not seeing?

推荐答案

您可以创建单独的中间件而不是嵌入式中间件,然后从此处调用 HitDetails.StoreHitDetails .

You can create a separate middleware rather than an inline one and then call the HitDetails.StoreHitDetails from there.

public class MyMiddleware
{
    private readonly RequestDelegate _next;

    public MyMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        HitDetails.StoreHitDetails(context);

        await _next(context);
    }
}

// Extension method used to add the middleware to the HTTP request pipeline.
public static class MiddlewareExtensions
{
    public static IApplicationBuilder UseMyMiddleware(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<MyMiddleware>();
    }
}

这样,您可以继续使用 app.UseMyMiddleware(); ,而不必像您提到的那样使用 Task.Run 运行它.

That way you can continue using app.UseMyMiddleware(); and you don't have to run it using Task.Run as you mentioned.

或者您可以尝试调用 HitDetails.StoreHitDetails(context)而不将其包装在 Task.Run

Or you can just try calling HitDetails.StoreHitDetails(context) without wrapping it in Task.Run

已编辑

检查您的 Request 是否具有正确的内容类型:

Check if your Request has a correct content type:

if (context.Request.HasFormContentType)
{
    IFormCollection form;
    form = context.Request.Form; // sync
    // Or
    form = await context.Request.ReadFormAsync(); // async

    string param1 = form["param1"];
    string param2 = form["param2"];
 }

这篇关于.Net核心中间件-从请求中获取表单数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆