有没有办法直接在操作中读取请求正文而无需中间件?

问题描述 投票:0回答:1

我希望能够在操作中读取请求正文,同时仍然使用默认的 MVC 行为,其中涉及使用 [FromBody] 参数进行发布。据我所知,我需要中间件来完成此任务。我的行动是:

[HttpPost]
public async Task<JsonResult> ValidateTestFormAsync([FromBody] ValidationRequest<PersonModel> personValidationRequest)
{   
    Request.EnableBuffering();
    Request.Body.Seek(0, SeekOrigin.Begin);
    string requestContent;
    using (var reader = new StreamReader(Request.Body, Encoding.UTF8, true, 1024, true))
    {
        requestContent = await reader.ReadToEndAsync();
    }

     return Json(requestContent);
}

这不起作用,requestContent 始终为 null,因为一旦请求已经在操作内,请求正文流已被读取并且无法再次读取。如果我删除 [FromBody],它就会起作用。我知道我可以在program.cs中编写一个中间件,如下所示:

app.Use((context, next) =>
{
    context.Request.EnableBuffering();
    return next();
});

但是这样做有什么考虑呢?我不希望每个请求都是可缓冲的,并且我仍然想通过 [FromBody] 传递模型以坚持 MVC 标准。

我基本上只是尝试运行自定义验证,在其中删除未在帖子中发送的字段/属性的任何错误消息,因为 MVC 始终验证完整模型,并且我尝试逐个字段进行 POST。我以为我可以通过请求正文将

ModelState
错误与发布的值键进行比较,但这似乎不符合我的要求。

c# asp.net-core .net-core asp.net-core-mvc middleware
1个回答
0
投票

如果不需要

ValidationRequest<PersonModel>
对象,则可以完全删除该参数,然后主体将可读,因为 ASP.NET Core 不会读取它。

如果您确实需要,但希望有选择地启用缓冲,则可以使用带有

IAsyncResourceFilter
:

的自定义属性
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class EnableBufferingAttribute : Attribute, IAsyncResourceFilter
{
    private readonly Action<HttpRequest> _apply;

    public EnableBufferingAttribute()
    {
        _apply = r => r.EnableBuffering();
    }

    public EnableBufferingAttribute(int bufferThreshold)
    {
        _apply = r => r.EnableBuffering(bufferThreshold: bufferThreshold);
    }

    public EnableBufferingAttribute(int bufferThreshold, long bufferLimit)
    {
        _apply = r => r.EnableBuffering(bufferThreshold: bufferThreshold, bufferLimit: bufferLimit);
    }

    public EnableBufferingAttribute(long bufferLimit)
    {
        _apply = r => r.EnableBuffering(bufferLimit: bufferLimit);
    }

    public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
    {
        _apply(context.HttpContext.Request);
        await next();
    }
}

用途:

[EnableBuffering]
[HttpPost]
public async Task<JsonResult> ValidateTestFormAsync([FromBody] ValidationRequest<PersonModel> personValidationRequest)
{   
}
© www.soinside.com 2019 - 2024. All rights reserved.