在 .Net 5 的中间件中读取请求正文
Reading request body in middleware for .Net 5
我正在尝试读取从客户端发送到我的后端的请求正文。内容以 JSON 格式发送,并让用户从表单输入。如何在我为控制器路由设置的中间件中读取请求主体。
这是我的模型
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);
}
}
}
这是我的中间件class
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();
});
}
我创建了中间件来记录每个请求并保存在数据库中。希望这段代码对你有帮助。
using Newtonsoft.Json;
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.
var req = httpContext.Request;
var xbody = await ReadBodyAsync(req);
var bodyRaw = JsonConvert.SerializeObject(xbody);
var param = JsonConvert.SerializeObject(req.Query);
var header = JsonConvert.SerializeObject(req.Headers);
var originalUrl = JsonConvert.SerializeObject(req.Path);
}
}
我正在尝试读取从客户端发送到我的后端的请求正文。内容以 JSON 格式发送,并让用户从表单输入。如何在我为控制器路由设置的中间件中读取请求主体。
这是我的模型
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);
}
}
}
这是我的中间件class
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();
});
}
我创建了中间件来记录每个请求并保存在数据库中。希望这段代码对你有帮助。
using Newtonsoft.Json;
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.
var req = httpContext.Request;
var xbody = await ReadBodyAsync(req);
var bodyRaw = JsonConvert.SerializeObject(xbody);
var param = JsonConvert.SerializeObject(req.Query);
var header = JsonConvert.SerializeObject(req.Headers);
var originalUrl = JsonConvert.SerializeObject(req.Path);
}
}