如果您自己的代码抛出了异常,那么从控制器中的某个动作调用该异常应如何处理?我看到很多最佳实践的例子,其中根本没有try-catch语句。例如,从存储库访问数据:
public ViewResult Index()
{
IList<CustomModel> customModels = _customModelRepository.GetAll();
return View(customModels);
}
显然,如果对无法访问的数据库进行调用,并且我们正在使用像Entity Framework这样的ORM,则此代码可能会抛出异常。
然而,我能看到的所有事情都会发生异常,并且会向用户显示一条令人讨厌的错误消息。
我知道HandleError属性,但据我所知,如果发生未处理的异常,它主要用于将您重定向到错误页面。
当然,这段代码可以包含在try-catch中,但不能很好地分离,特别是如果你有更多的逻辑:
public ViewResult Index()
{
if (ValidationCheck())
{
IList<CustomModel> customModels = new List<CustomModel>();
try
{
customModels = _customModelRepository.GetAll();
}
catch (SqlException ex)
{
// Handle exception
}
if (CustomModelsAreValid(customModels))
// Do something
else
// Do something else
}
return View();
}
以前我已经提取出所有可能会将数据库调用等异常引入DataProvider类的代码,该类处理错误并返回消息以向用户显示消息。
我想知道处理这个问题的最佳方法是什么?我并不总是希望返回错误页面,因为一些例外不应该这样做。相反,应该以正常视图显示给用户的错误消息。我以前的方法是否正确或是否有更好的解决方案?
答案 0 :(得分:23)
我做了三件事来显示更多用户友好的消息:
修改强> 我想我会提到ASP.NET Web API,因为它密切相关。因为Web API端点的使用者不一定是浏览器,所以我喜欢稍微处理错误。我仍然使用“FriendlyException”(上面的#2),但不是重定向到ErrorController,而是让我的所有端点返回某种包含Error属性的基类型。因此,如果异常一直到Web API控制器,我确保将该错误粘贴在API响应的Error属性中。此错误消息将是从API控制器所依赖的类中冒出的友好消息,或者如果异常类型不是FriendlyException,则它将是通用消息。这样,消费客户端可以简单地检查API响应的Error属性是否为空。如果错误存在则显示消息,否则照常进行。好消息是,由于友好的消息概念,消息对于用户而言可能比通用的“错误!”更有意义。信息。我在使用Xamarin编写移动应用程序时使用此策略,我可以在我的Web服务和iOS / Android应用程序之间共享我的C#类型。
答案 1 :(得分:18)
使用Asp.Net MVC,您还可以为您的控制器覆盖OnException方法。
protected override void OnException(ExceptionContext filterContext)
{
if (filterContext.ExceptionHandled)
{
return;
}
filterContext.Result = new ViewResult
{
ViewName = ...
};
filterContext.ExceptionHandled = true;
}
这允许您重定向到自定义错误页面,如果您愿意,可以使用引用该异常的消息。
答案 2 :(得分:1)
我使用了OnException覆盖,因为我有几个项目引用一个具有处理错误的Controller的项目:
Security / HandleErrors Controller.csp>
protected override void OnException(ExceptionContext filterContext)
{
MyLogger.Error(filterContext.Exception); //method for log in EventViewer
if (filterContext.ExceptionHandled)
return;
filterContext.HttpContext.Response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;
filterContext.Result = new JsonResult
{
Data = new
{
Success = false,
Error = "Please report to admin.",
ErrorText = filterContext.Exception.Message,
Stack = filterContext.Exception.StackTrace
},
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
filterContext.ExceptionHandled = true;
}
答案 3 :(得分:0)
这样的所有问题都不是很有建设性,因为答案总是“取决于”,因为有很多方法可以处理错误处理。
许多人喜欢使用HandleError方法,因为任何异常基本上都是不可恢复的。我的意思是,如果你不能归还物体,你打算做什么?无论如何你都会向他们展示错误,对吗?
问题变成了,你想如何向他们展示错误。如果显示错误页面是可以接受的,那么HandleError工作正常,并提供了一个记录错误的简单位置。如果您正在使用Ajax或想要更高级的东西,那么您需要开发一种方法来实现这一点。
您谈论的是DataProvider类。这基本上就是你的存储库。为什么不将它构建到您的存储库中?