In my ASP.NET MVC application, I do not want to report all exception messages to the user. But there are certain types of exceptions that I'd like to report to the user, so I created an action filter to decide if it's this particular type of exception, and if so then display the exception's message, otherwise display a generic message. So I created a custom exception called ClientException.
在我的ASP。NET MVC应用程序,我不想向用户报告所有的异常消息。但是我想向用户报告某些类型的异常,所以我创建了一个操作过滤器来确定它是否是这种特殊类型的异常,如果是,那么显示异常的消息,否则显示一个通用消息。因此,我创建了一个定制的异常,称为ClientException。
My filter looks something like this:
我的过滤器是这样的:
if (filterContext.Exception is ClientException)
message = filterContext.Exception.Message.Replace("\r", " ").Replace("\n", " ");
else
message = "An error occured while attemting to perform the last action. Sorry for the inconvenience.";
filterContext.HttpContext.Response.Status = "500 " + message;
I read this http://blogs.msdn.com/b/kcwalina/archive/2007/01/30/exceptionhierarchies.aspx where the author recommends using existing .NET exception types to report usage errors. However, by introducing my custom exception, I just have to do a single check in my filter. Is my approach okay?
我阅读了http://blogs.msdn.com/b/kcwalina/archive/2007/01/30/exceptionhierarchies.aspx,作者建议使用现有的。net异常类型报告使用错误。但是,通过引入自定义异常,我只需在过滤器中执行一次检查。是我的方法好吗?
5 个解决方案
#1
3
I like this approach for a couple of reasons.
我喜欢这种方法有几个原因。
First, it fails safely. If someone doesn't explicity throw a ClientException, then the exception details are not reported. Forgetting to display something is a lesser problem than accidently displaying something.
首先,它不安全。如果某人不明确抛出一个ClientException,则不会报告异常细节。忘记显示某样东西比不小心显示某样东西的问题要小。
Secondly, it allows the decision about whether to display the exception to be made at the proper place. Not all IOExceptions are displayed, for example. Some may be, and others wont be. The specific exceptions can be caught and transformed anywhere in the call stack, so that tranformation can be made at a place where it is known to be correct.
其次,它允许决定是否在适当的位置显示要执行的异常。例如,并不是显示所有ioexception。有些可能是,有些不会。可以在调用堆栈的任何地方捕获和转换特定的异常,以便在已知的正确位置进行转换。
Both of those things together mean that a future developer will not innappropriately change a whole class of exception to be displayed, or think that something won't be displayed when it actually will be.
这两件事结合在一起意味着未来的开发人员不会不恰当地更改要显示的整个异常类,或者认为某些东西在实际显示时不会显示。
Also, the purpose of the using a particular exception type is to determine later what action to take in response to that exception. "Display this message to the user" is a perfectly good action to specify. Once that decision has been made, then the exact nature of the exception is completely irrelivant. (The original problem may be put in the InnerException property, for logging purposes, of course.)
此外,使用特定异常类型的目的是为了稍后确定响应该异常应该采取什么操作。“向用户显示此消息”是一个非常好的行为。一旦做出了这个决定,那么异常的确切性质就完全不可靠了。(最初的问题可以放在InnerException属性中,当然是为了记录日志。)
So, in my opinion, this is a good design.
所以,在我看来,这是一个很好的设计。
#2
2
Your approach is fine IMO but there are alternatives. (We're software developers so there are always alternatives.)
你的方法在我看来很好,但是还有其他的选择。(我们是软件开发人员,所以总有其他选择。)
You could harness the Exception Data dictionary to store a flag indicating whether or not an exception is a client exception. Then you could have your filter check for the existence of the flag.
您可以利用异常数据字典来存储一个标志,指示异常是否为客户端异常。然后,您可以对标志的存在进行筛选。
#3
1
If your approach works for you then it is fine. And are you surprised that a Microsoft blog is recommending that you use their Exception class? ;)
如果你的方法对你有效,那就没问题。你对微软博客推荐你使用他们的异常类感到惊讶吗?,)
There are some .NET library features and 3rd party OSS stuff that will only work with .NET exceptions however.
有一些。net的库特性和第三方的OSS,只适用于。net异常。
To get the best of both worlds you could always extend the .NET Exception object into your own.
要充分利用这两种情况,您可以将. net异常对象扩展到您自己的。
#4
1
I would use different Threshold values based on the type of exceptions, and these Threshold values would be associated with the exception messages.
我将根据异常的类型使用不同的阈值,这些阈值将与异常消息相关联。
Based on the particular Threshold value logic you may want to decide whether or not to show exception.
基于特定的阈值逻辑,您可能需要决定是否显示异常。
#5
1
My concerns with this solution is that very likely these exceptions will typically be thrown by objects in a business layer (or model objects in MVC terminology). The usage you describe is really what I would consider to be a presentation concern.
我对这个解决方案的关注是,这些异常很可能是由业务层中的对象(或者MVC术语中的模型对象)抛出的。你所描述的用法正是我所考虑的一个表示问题。
Typically you'd need to rethrow whatever exception you have in your model, only to communicate whether or not the exception can be exposed to the user or not. What do you expect the user to do with the information? If the user can fix the situation perhaps there should not be an exception to signal the state to begin with?
通常,您需要重新抛出模型中存在的任何异常,只是为了交流该异常是否可以公开给用户。您希望用户如何处理这些信息?如果用户可以修复这种情况,那么是否应该有一个异常来通知状态开始?
I would stick to catching specific exceptions per case and do presentation decisions at the spot. You may send out an exception, as caught, used as model to a view though. I would still let the controller decide, not whomever throws the exception.
我将坚持捕获每个案例的特定异常,并当场做出表示决策。但是,您可能会发送一个异常,如被捕获的,作为模型使用的视图。我仍然会让控制器决定,而不是由谁抛出异常。
#1
3
I like this approach for a couple of reasons.
我喜欢这种方法有几个原因。
First, it fails safely. If someone doesn't explicity throw a ClientException, then the exception details are not reported. Forgetting to display something is a lesser problem than accidently displaying something.
首先,它不安全。如果某人不明确抛出一个ClientException,则不会报告异常细节。忘记显示某样东西比不小心显示某样东西的问题要小。
Secondly, it allows the decision about whether to display the exception to be made at the proper place. Not all IOExceptions are displayed, for example. Some may be, and others wont be. The specific exceptions can be caught and transformed anywhere in the call stack, so that tranformation can be made at a place where it is known to be correct.
其次,它允许决定是否在适当的位置显示要执行的异常。例如,并不是显示所有ioexception。有些可能是,有些不会。可以在调用堆栈的任何地方捕获和转换特定的异常,以便在已知的正确位置进行转换。
Both of those things together mean that a future developer will not innappropriately change a whole class of exception to be displayed, or think that something won't be displayed when it actually will be.
这两件事结合在一起意味着未来的开发人员不会不恰当地更改要显示的整个异常类,或者认为某些东西在实际显示时不会显示。
Also, the purpose of the using a particular exception type is to determine later what action to take in response to that exception. "Display this message to the user" is a perfectly good action to specify. Once that decision has been made, then the exact nature of the exception is completely irrelivant. (The original problem may be put in the InnerException property, for logging purposes, of course.)
此外,使用特定异常类型的目的是为了稍后确定响应该异常应该采取什么操作。“向用户显示此消息”是一个非常好的行为。一旦做出了这个决定,那么异常的确切性质就完全不可靠了。(最初的问题可以放在InnerException属性中,当然是为了记录日志。)
So, in my opinion, this is a good design.
所以,在我看来,这是一个很好的设计。
#2
2
Your approach is fine IMO but there are alternatives. (We're software developers so there are always alternatives.)
你的方法在我看来很好,但是还有其他的选择。(我们是软件开发人员,所以总有其他选择。)
You could harness the Exception Data dictionary to store a flag indicating whether or not an exception is a client exception. Then you could have your filter check for the existence of the flag.
您可以利用异常数据字典来存储一个标志,指示异常是否为客户端异常。然后,您可以对标志的存在进行筛选。
#3
1
If your approach works for you then it is fine. And are you surprised that a Microsoft blog is recommending that you use their Exception class? ;)
如果你的方法对你有效,那就没问题。你对微软博客推荐你使用他们的异常类感到惊讶吗?,)
There are some .NET library features and 3rd party OSS stuff that will only work with .NET exceptions however.
有一些。net的库特性和第三方的OSS,只适用于。net异常。
To get the best of both worlds you could always extend the .NET Exception object into your own.
要充分利用这两种情况,您可以将. net异常对象扩展到您自己的。
#4
1
I would use different Threshold values based on the type of exceptions, and these Threshold values would be associated with the exception messages.
我将根据异常的类型使用不同的阈值,这些阈值将与异常消息相关联。
Based on the particular Threshold value logic you may want to decide whether or not to show exception.
基于特定的阈值逻辑,您可能需要决定是否显示异常。
#5
1
My concerns with this solution is that very likely these exceptions will typically be thrown by objects in a business layer (or model objects in MVC terminology). The usage you describe is really what I would consider to be a presentation concern.
我对这个解决方案的关注是,这些异常很可能是由业务层中的对象(或者MVC术语中的模型对象)抛出的。你所描述的用法正是我所考虑的一个表示问题。
Typically you'd need to rethrow whatever exception you have in your model, only to communicate whether or not the exception can be exposed to the user or not. What do you expect the user to do with the information? If the user can fix the situation perhaps there should not be an exception to signal the state to begin with?
通常,您需要重新抛出模型中存在的任何异常,只是为了交流该异常是否可以公开给用户。您希望用户如何处理这些信息?如果用户可以修复这种情况,那么是否应该有一个异常来通知状态开始?
I would stick to catching specific exceptions per case and do presentation decisions at the spot. You may send out an exception, as caught, used as model to a view though. I would still let the controller decide, not whomever throws the exception.
我将坚持捕获每个案例的特定异常,并当场做出表示决策。但是,您可能会发送一个异常,如被捕获的,作为模型使用的视图。我仍然会让控制器决定,而不是由谁抛出异常。