Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在.NET5中间件中读取请求正文_C#_Asp.net_.net_Asp.net Mvc_Asp.net Core Middleware - Fatal编程技术网

C# 在.NET5中间件中读取请求正文

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

我正在尝试读取从客户端发送到后端的请求正文。内容以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);
        }

    }
}
这是我的中间件类

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,或者没有请求正文,此方法将不起作用。