C# 在.NET5中间件中读取请求正文
我正在尝试读取从客户端发送到后端的请求正文。内容以JSON格式发送,并由用户从表单输入。如何在为控制器路由设置的中间件中读取请求主体 这是我的模型C# 在.NET5中间件中读取请求正文,c#,asp.net,.net,asp.net-mvc,asp.net-core-middleware,C#,Asp.net,.net,Asp.net Mvc,Asp.net Core Middleware,我正在尝试读取从客户端发送到后端的请求正文。内容以JSON格式发送,并由用户从表单输入。如何在为控制器路由设置的中间件中读取请求主体 这是我的模型 namespace ChatboxApi.Models { public class User { public string Login { get; set; } = default; public string Password { get; set; } = default; p
namespace ChatboxApi.Models
{
public class User
{
public string Login { get; set; } = default;
public string Password { get; set; } = default;
public string Email { get; set; } = default;
public string FullName { get; set; } = default;
public int Phone { get; set; } = default;
public string Website { get; set; } = default;
}
}
这是我的控制器
namespace ChatboxApi.Controllers
{
[ApiController]
[Route("api/signup")]
public class SignupController : ControllerBase
{
[HttpPost]
public ActionResult SignUp([FromBody] User user)
{
return Ok(user);
}
}
}
这是我的中间件类
namespace ChatboxApi.Middleware
{
public class CreateSession
{
private readonly RequestDelegate _next;
public CreateSession(RequestDelegate next)
{
this._next = next;
}
public async Task Invoke(HttpContext httpContext)
{
//I want to get the request body here and if possible
//map it to my user model and use the user model here.
}
}
通常
Request.Body
不支持倒带,因此只能读取一次。临时解决方法是在调用EnableBuffering
后立即拉出主体,然后将流倒带到0,而不处理它:
public class CreateSession
{
private readonly RequestDelegate _next;
public CreateSession(RequestDelegate next)
{
this._next = next;
}
public async Task Invoke(HttpContext httpContext)
{
var request = httpContext.Request;
request.EnableBuffering();
var buffer = new byte[Convert.ToInt32(request.ContentLength)];
await request.Body.ReadAsync(buffer, 0, buffer.Length);
//get body string here...
var requestContent = Encoding.UTF8.GetString(buffer);
request.Body.Position = 0; //rewinding the stream to 0
await _next(httpContext);
}
}
注册服务:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//...
app.UseHttpsRedirection();
app.UseMiddleware<CreateSession>();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
public void配置(IApplicationBuilder应用程序,IWebHostEnvironment环境)
{
//...
app.UseHttpsRedirection();
app.UseMiddleware();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(端点=>
{
endpoints.MapControllers();
});
}
在我看来,您不应该将中间件用于这种情况。理想情况下,您的请求路由应该只依赖于请求路径,或者最多依赖于HTTP请求头。您不应该基于请求正文的内容进行路由。这只是自找麻烦——尤其是因为ASP.NET会在收到请求正文之前路由请求——这就解释了您所遇到的问题。因此,您是说在控制器中进行工作比在中间件中进行工作更好?是的。“工作”不应在中间件中完成-中间件应用于设置请求处理环境或向实际处理程序提供服务(例如,设置失败的请求日志记录、解压缩gzip压缩请求体等)。Hi@championq45,有更新吗?我的回答是否有助于您解决问题?如果有,您能否接受我的回答?如果没有,请继续告诉我。请参阅:。谢谢。如果请求正文超过2GB,或者没有请求正文,此方法将不起作用。