在自定义InvalidModelStateResponseFactory asp.net核心2.2中读取请求正文

时间:2019-03-30 09:39:06

标签: c# asp.net-core .net-core

我想在我的自定义InvalidModelStateResponseFactory处理程序中获取HTTP请求正文,并且始终返回空。
我在SO和其他网站上尝试了许多解决方案,但似乎在EnableRewind内部使用InvalidModelStateResponseFactory无效。
那么,我可以在InvalidModelStateResponseFactory内获取请求正文吗?

我在Startup.cs中的代码

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

    services.Configure<ApiBehaviorOptions>(options =>
    {
        options.InvalidModelStateResponseFactory = actionContext =>
        {
            actionContext.HttpContext.Request.EnableRewind();
            using(StreamReader stream = new StreamReader(actionContext.HttpContext.Request.Body))
            {
                string body = stream.ReadToEnd();    //body is always empty
            }

            return new BadRequestObjectResult(/*Some Error Model*/);
        };
    });
}

1 个答案:

答案 0 :(得分:2)

通过替换以下内容,我可以对您提供的示例进行简单的更改:

actionContext.HttpContext.Request.EnableRewind();

具有:

actionContext.HttpContext.Request.Body.Position = 0;

一旦(通过MVC本身)读取了正文,就需要在尝试再次读取流之前将流的位置重置为开头。

在测试中,我发现根本不需要调用EnableRewind ,但是如果您需要这样做,我希望它被称为太迟了。如果如我所示将Position设置为0不能单独工作,则可能需要添加一个自定义中间件来设置倒带:

app.Use(async (ctx, next) =>
{
    ctx.Request.EnableRewind();
    await next();
});

这需要在UseMvc之前添加,但是正如我已经说过的那样,我在测试中发现并不需要,但是我希望并非总是如此。