ASP.NET Core 3.1:ExceptionFilter中如何操作ViewModel与ViewDataDictionary
在ASP.NET Core 3.1 MVC的ExceptionFilter中返回带ViewModel的视图
要实现和控制器中return View(viewModel)等效的效果,关键是从ExceptionContext中获取绑定后的ViewModel,再把它和ModelState错误一起传递给ViewResult。下面是具体的解决方案:
步骤1:获取Action中的ViewModel
当Action执行抛出异常时,ASP.NET Core已经完成了请求参数的绑定,ViewModel会被保存在ExceptionContext.ActionArguments集合中。你可以根据类型直接提取:
// 获取当前Action中绑定的AuthoriseApiViewModel实例 var viewModel = context.ActionArguments.Values .FirstOrDefault(v => v is AuthoriseApiViewModel); // 处理ViewModel为null的情况(比如绑定失败),可以实例化一个空对象 if (viewModel == null) { viewModel = new AuthoriseApiViewModel(); }
步骤2:构建ViewDataDictionary并传递给ViewResult
接下来需要创建包含ViewModel和ModelState的ViewDataDictionary,这样视图既能显示原来的用户输入,也能展示错误信息:
else { context.ModelState.Clear(); context.ModelState.AddModelError(action, $"error in {action}"); m_Logger.LogError(context.Exception, $"error in {action}"); context.ExceptionHandled = true; // 获取ViewModel,为空时实例化新对象 var viewModel = context.ActionArguments.Values .FirstOrDefault(v => v is AuthoriseApiViewModel) ?? new AuthoriseApiViewModel(); // 创建ViewDataDictionary,传入当前的ModelMetadata和ModelState var viewData = new ViewDataDictionary(context.ModelMetadata, context.ModelState) { Model = viewModel // 将ViewModel设置为ViewData的Model }; // 设置ViewResult context.Result = new ViewResult{ ViewName = action, ViewData = viewData, // 如果需要使用TempData,可通过依赖注入获取 TempData = context.HttpContext.RequestServices.GetRequiredService<ITempDataDictionary>() }; }
关键说明
ActionArguments:存储了Action执行时的所有参数,包括绑定后的ViewModel,这是我们获取用户原始输入的核心来源。ViewDataDictionary:必须传入当前的ModelMetadata和ModelState,这样视图中的ModelState.IsValid、ValidationSummary等验证标签才能正常读取错误信息。- 空ViewModel处理:如果参数绑定失败导致ViewModel为null,实例化空对象可以避免视图出现空引用异常。
这样处理后,当异常发生时,页面会回到原来的Action视图,保留用户之前输入的内容,同时显示你添加的错误信息,和控制器中return View(viewModel)的效果完全一致。
内容的提问来源于stack exchange,提问作者jazza1000
相关产品推荐
相关产品推荐

