首页 > 解决方案 > 如何在 ExceptionFilter 中填充 ViewDataDictionary

问题描述

如何从异常过滤器中检索 ViewModel?

我有一个 ExceptionFilter,我将它用于 asp .net core 3.1 MVC 应用程序中的全局错误处理程序。我试图让异常过滤器在出现错误时重定向回视图并显示验证错误,即相当于说:

return View(viewModel)

在控制器中

我可以重定向到视图,但是对于如何在 ViewResult 中填充模型有点卡住

异常过滤器代码

public void OnException(ExceptionContext context)
    {
        string controller = context.RouteData.Values["controller"].ToString();
        string action = context.RouteData.Values["action"].ToString();       

        if (context.Exception is WebServiceException && context.Exception.IsUnauthorized())
        {
            context.Result =  new  RedirectToActionResult("fetchtoken", "Home", new { path = $"/{controller}/{action}" });
        }
        //other type of exception, return the view displaying errors
        else
        {
            context.ModelState.Clear();
            context.ModelState.AddModelError(action, $"error in {action}");
            m_Logger.LogError(context.Exception, $"error in {action}");
            context.ExceptionHandled = true;
            context.ModelState
            context.Result = new ViewResult{
                ViewName = action,
                ViewData = // ??????????????
            };
            
        }
        
    }

在控制器中:

  [Authorize]
    [HttpPost]
    public async Task<IActionResult> AuthoriseApiUser(AuthoriseApiViewModel viewModel)
    {
        await m_ApiUserService.AuthoriseUser(viewModel.TenantId, viewModel.UserId); //error thrown here
        return View(viewModel);
    }

标签: asp.netasp.net-mvcasp.net-core

解决方案


通过获取表单数据中每个键的值,将该值与模型的属性进行比较。然后,为模型赋值。例如。

public void OnException(ExceptionContext context)
    {
        string controller = context.RouteData.Values["controller"].ToString();
        string action = context.RouteData.Values["action"].ToString();
        
        //start
        var viewModel = new ViewModel();
        var list = context.HttpContext.Request.Form.AsEnumerable();
        foreach (var meta in list)
        {
            if (meta.Key == "addr")
            {
                viewModel.addr = meta.Value;
            }
        }
        //end
        if (context.Exception is WebServiceException && context.Exception.IsUnauthorized())
        {
            context.Result = new RedirectToActionResult("fetchtoken", "Home", new { path = $"/{controller}/{action}" });
        }
        //other type of exception, return the view displaying errors
        else
        {
            //...
            var modelMetadata = new EmptyModelMetadataProvider();
            context.Result = new ViewResult
            {
                ViewName = action,
                ViewData = ViewData = new ViewDataDictionary(modelMetadata, context.ModelState)
                {
                    Model = viewModel
                }
            };

        }

    }

模型

public class ViewModel
{
    public int id { get; set; }
    [MinLength(2)]
    public string addr { get; set; }
}

推荐阅读