我已经创建了一个Asp.Net核心MVC应用程序。我想处理两种类型的错误。
我创建了两个异常:UserFriendlyException和UserFriendlyViewException。
我已经尝试创建我需要根据以下规则处理这两个异常的ExceptionFilter:
如果调用了exception UserFriendlyViewException,那么我想返回带有原始ViewName和AddModelError的ViewResult,并返回原始模型。
如果调用了exception UserFriendlyException,那么我想重定向到Error视图。
这是我的ExceptionFilterAttribute
public class ControllerExceptionFilterAttribute : ExceptionFilterAttribute
{
private readonly ITempDataDictionaryFactory _tempDataDictionaryFactory;
private readonly IModelMetadataProvider _modelMetadataProvider;
public ControllerExceptionFilterAttribute(ITempDataDictionaryFactory tempDataDictionaryFactory,
IModelMetadataProvider modelMetadataProvider)
{
_tempDataDictionaryFactory = tempDataDictionaryFactory;
_modelMetadataProvider = modelMetadataProvider;
}
public override void OnException(ExceptionContext context)
{
if (!(context.Exception is UserFriendlyException) && !(context.Exception is UserFriendlyViewException)) return;
var tempData = _tempDataDictionaryFactory.GetTempData(context.HttpContext);
//CreateNotification(NotificationHelpers.AlertType.Error, tempData, context.Exception.Message);
if (!tempData.ContainsKey(NotificationHelpers.NotificationKey)) return;
if (context.Exception is UserFriendlyViewException userFriendlyViewException)
{
context.ModelState.AddModelError(userFriendlyViewException.ErrorKey, userFriendlyViewException.Message);
}
if (context.ActionDescriptor is ControllerActionDescriptor controllerActionDescriptor)
{
//How pass here Model from context??
//If exists more views with same name but in another controller how pass correct ViewName?
var result = new ViewResult
{
ViewName = context.Exception is UserFriendlyViewException ?
controllerActionDescriptor.ActionName
: "Error",
TempData = tempData,
ViewData = new ViewDataDictionary(_modelMetadataProvider, context.ModelState)
{
{"Notifications", tempData[NotificationHelpers.NotificationKey] },
}
};
context.ExceptionHandled = true;
context.Result = result;
}
tempData.Remove(NotificationHelpers.NotificationKey);
}
}我有两个问题:
1.)如何将原始Model从ExceptionContext传递到ViewResult
2.)如果在另一个控制器中存在更多同名的视图,如何为UserFriendlyViewException返回正确的ViewName?
发布于 2017-11-23 23:45:18
如何将原始模型从ExceptionContext传递到ViewResult?
您可以使用context.ModelState集合。
foreach(var item in context.ModelState)
{
string parameter = item.Key;
object rawValue = item.Value.RawValue;
string attemptedValue = item.Value.AttemptedValue;
System.Console.WriteLine($"Parameter: {parameter}, value: {attemptedValue}");
}注意,集合将只包含绑定的参数。
如果在另一个控制器中存在更多具有相同名称的视图,如何为UserFriendlyViewException返回正确的ViewName?
框架将使用与控制器操作相同的View discovery进程,因此您可以指定路径,而不是视图名称:
可以提供视图文件路径,而不是视图名称。如果使用从应用程序根目录开始的绝对路径(可选以"/“或”~/“开头),则必须指定.cshtml扩展名:
return View("Views/Home/About.cshtml");
您还可以使用相对路径指定不同目录中的视图,而不使用.cshtml扩展名。在HomeController中,您可以使用相对路径返回Manage视图的索引视图:
return View("../Manage/Index");
类似地,您可以使用"./“前缀来指示当前特定于控制器的目录:
返回视图(“./About”);
发布于 2021-09-09 11:13:39
通过ViewData传递内容
public class UIFriendlyExceptionFilter : IExceptionFilter
{
public void OnException(ExceptionContext context)
{
if (context.Exception is UIFriendlyException uex)
{
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), context.ModelState);
//here we go
viewData.Add("Message", MY_CUSTOM_MESSAGE);
var res = new ViewResult() {
ViewName = "Error",
ViewData = viewData
};
context.Result = res;
}
context.ExceptionHandled = true;
}
}然后在启动中注册
services.AddControllersWithViews(options =>
{
options.Filters.Add(typeof(UIFriendlyException.UIFriendlyExceptionFilter));
});https://stackoverflow.com/questions/47454921
复制相似问题