c# - .Net Core Middleware - 从请求中获取表单数据
问题描述
在 .NET Core Web 应用程序中,我使用中间件 (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 数据的替代属性?
解决方案
您可以创建一个单独的中间件而不是内联中间件,然后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"];
}
推荐阅读
- reactjs - Cypress_Test_Automation:如何为运行时创建的组件触发事件
- python - NDArray 的这种行为是否正确?
- docker - 从另一个容器访问一个容器的端口
- c# - 如何在 ASP.Net Core 中为唯一的电子邮件地址添加 IdentityUser IdentityResult 错误
- javascript - 需要在foreach循环中运行不同时区的实时时钟
- sql - 尝试插入表 A 并链接表 B 和 C,但如果不存在则添加到所有表
- swift - 收到警告消息
在 getter setter 方法中 - java - Java HTMLUnit WebClient ScriptException 错误
- angular - 如何在静态类中注入服务而不在 Angular 7 的子类中传递服务?
- regex - 环回 3 字符串与和条件不匹配