.Net Core Middleware - Получение данных формы из запроса - PullRequest
2 голосов
/ 09 мая 2019

В веб-приложении .NET Core я использую промежуточное программное обеспечение (app.UseMyMiddleware), чтобы добавить некоторые записи в журнал для каждого запроса:

        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.

context.Request.Form - доступная опция, но при отладке я нахожу на нее курсор и вижу «Оценка функции»требует, чтобы весь поток работал ".Если я пытаюсь использовать его, приложение просто зависает.

Что мне нужно сделать, чтобы получить доступ к Request.Form или есть альтернативное свойство с данными POST, которое я не вижу?

1 Ответ

1 голос
/ 09 мая 2019

Вы можете создать отдельное промежуточное программное обеспечение, а не встроенное, а затем вызвать оттуда HitDetails.StoreHitDetails.

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, как вы упомянули.

Или вы можете просто попробовать позвонить HitDetails.StoreHitDetails(context), не заключая его в Task.Run

Отредактировано

Проверьте, имеет ли Request правильный тип контента:

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"];
 }
...