【问题标题】:PageResult always returns null in IAsyncPageFilter - OnPageHandlerExecutionAsync in Asp.Net Core 2.0 Razor PagesPageResult 在 IAsyncPageFilter 中始终返回 null - Asp.Net Core 2.0 Razor 页面中的 OnPageHandlerExecutionAsync
【发布时间】:2019-05-27 20:08:03
【问题描述】:

我正在使用 ModelValidationFilter 来处理我所有的 post 或 put 请求的模型验证错误。我正在使用 IAsyncPageFilter 并注册为全局过滤器。在 OnPageHandlerExecutionAsync 方法中,我能够处理 ajax 请求的验证错误并发回 json 响应。但是对于非ajax请求,

var result = (PageResult)context.Result;

请问您能帮我解决这个问题吗?

我正在实现这一点,因此我不需要在所有帖子中编写模型验证或将处理程序放在我的应用程序的任何剃须刀页面中。

这是我的实现:

if (context.HttpContext.Request.Method.Equals("POST") || context.HttpContext.Request.Method.Equals("PUT"))
{
    if (!context.ModelState.IsValid)
    {
        if (context.HttpContext.Request.IsAjaxRequest())
        {
            var errorModel = context.ModelState.Keys.Where(x => context.ModelState[x].Errors.Count > 0)
                .Select(x => new
                {
                    key = x,
                    errors = context.ModelState[x].Errors.Select(y => y.ErrorMessage).ToArray()
                });

            context.Result = new JsonResult(new AjaxResultHelper<IEnumerable<object>>
            {
                Response = errorModel,
                Message = "_InvalidData_"
            });
        }
        else
        {
            var result = (PageResult)context.Result;

            context.Result = new PageResult
            {
                ViewData = result.ViewData,
                ContentType = result.ContentType,
                StatusCode = 400,
            };
        }
    }
}
else
{
    await next.Invoke();
}

【问题讨论】:

  • 你应该可以做到context.Result = new PageResult();。
  • @KirkLarkin: 需要传递给PageResult 的ViewData 和ContentType 怎么样

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


【解决方案1】:

根据documentation

OnPageHandlerExecutionAsync :在模型绑定完成后在调用处理程序方法之前异步调用。

这意味着在调用 OnGet/OnPost 处理程序之前,您没有可用的 Result。您需要做的是从上下文中获取底层HandlerInstance 并将其转换为PageModel。您现在可以访问ViewData 和ContentType。

然后创建您的 PageResult,如下所示:

var result = context.HandlerInstance as PageModel;
context.Result = new PageResult
{
    ViewData = result.ViewData,
    ContentType = result.Request.ContentType,
    StatusCode = 400,
};

如果ModelState 无效,则可能返回BadRequestObjectResult。

if (context.HandlerInstance is PageModel result) //using pattern matching
{
    result.Response.StatusCode = 400;
    context.Result = result.Page();
}

await Task.CompletedTask;

您收到site can't be reached 错误的原因是在创建PageResult 时没有设置页面。相反,您可以设置Response.StatusCode = 400,然后调用将返回PageResult 的result.Page()。我已经测试了上面的代码并且它可以工作。我希望这会有所帮助。

【讨论】:

  • 此返回站点无法访问错误。这个想法是避免在每个处理程序中检查模型状态。现在模型状态无效,控件进入 else 部分,因为它不是 ajax 请求,然后站点无法到达错误。 :(请帮忙
  • 奇怪,能不能把样例上传到 GitHub 上?
  • 这里是存储库ModelValidation 的链接。请检查并分享您的观点
  • @Abdul 抱歉回复晚了。我已经用解释编辑了我的答案。它现在应该可以工作了。如果您还有其他问题,请告诉我。
  • @Abdul 我的日程现在很忙。我会尽快回复您。关于学习,我也会给你一些建议。
猜你喜欢
  • 1970-01-01
  • 2023-03-22
  • 1970-01-01
  • 2020-10-29
  • 2018-11-24
  • 2019-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多