在我的ASP.NET MVC应用程序中,我有一个非常具体的操作,我不想让Elmah处理,因为它可以发出500响应状态代码作为其正常功能的一部分。
我不希望被此路由中发生的错误发送垃圾邮件,但我也不想在其他任何地方关闭Elmah记录500个错误。
有没有办法在web.config中以声明方式执行此操作,还是必须编写自己的Assertion? 或者,重新说一下,有没有办法在测试断言中获得带有绑定的路由?
PS:对于那些想知道为什么我会允许我的行为生成500的人,这是因为它是客户定义代码的包装器,我希望我的客户立即知道他们的自定义代码是否有错误。答案 0 :(得分:2)
看起来你正在让那个特定的动作引发未处理的异常。我想是的,因为如果你只是返回500错误代码而没有例外,Elmah没有记录它:
public ActionResult ThrowError()
{
//your wrapper calling customer code
return new HttpStatusCodeResult(500, "Buggy code");
}
所以我假设您的操作是抛出未处理的异常(可能因此您的客户可以看到异常详细信息?)。假设您的操作方法位于HomeController
,如下所示:
public ActionResult ThrowError()
{
//your wrapper calling customer code
// the customer code throws an exception:
throw new Exception("Buggy code");
}
每次你去/Home/ThrowError
,你都会得到一个未处理的异常,结果是500,并由Elmah记录。所以你需要从Elmah过滤掉它,它会给你the following options
您可以在global.asax
上为Elmah添加以下过滤器,告诉Elmah忽略该特定网址上的例外情况:
void ErrorLog_Filtering(object sender, ExceptionFilterEventArgs e)
{
var httpContext = HttpContext.Current;
if(httpContext == null) return;
if (httpContext.Request.Url.AbsolutePath == "/home/throwerror") e.Dismiss();
}
如果您已启用ErrorFilter
模块,则可以在web.config中执行相同操作:
<system.web>
<httpModules>
<add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" />
</httpModules>
</system.web>
<system.webServer>
<modules>
<add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" />
</modules>
</system.webServer>
<elmah>
<errorFilter>
<test>
<and>
<equal binding="Context.Request.ServerVariables['URL']" value="/home/throwerror" type="String" />
<!--You could also use a regex for the url-->
<!--<regex binding="Context.Request.ServerVariables['URL']"
pattern="/home/throwerror\d*" />-->
</and>
</test>
</errorFilter>
</elmah>
我真的不喜欢这种方法,它取决于列出你想要过滤异常的所有网址(或者确保所有这些网址遵循你可以在正则表达式上表达的模式)。如果您可以将从客户代码抛出的异常包装到特定异常中,则可以过滤掉该类型的所有未处理异常,无论它们是从哪个URL中抛出。
因此,您可以创建一个新的异常类型并在代码包装客户代码中使用它:
public class CustomerException : Exception
{
public CustomerException(Exception e)
: base(e.Message, e)
{
}
}
public ActionResult ThrowError()
{
try
{
//your wrapper calling customer code
// the customer code throws an exception:
throw new Exception("Buggy code");
}
catch (Exception e)
{
throw new CustomerException(e);
}
}
现在,您可以在global.asax
或web.config
中过滤掉Elmah中的这些例外:
void ErrorLog_Filtering(object sender, ExceptionFilterEventArgs e)
{
var httpContext = HttpContext.Current;
if(httpContext == null) return;
if (e.Exception is CustomerException) e.Dismiss();
}
<errorFilter>
<test>
<jscript>
<expression>
<![CDATA[
// @assembly mscorlib
// @assembly WebApplication3
// @import WebApplication3.Controllers
// In my dummy project, CustomerException is located in WebApplication3.Controllers
$.Exception instanceof CustomerException
]]>
</expression>
</jscript>
</test>
</errorFilter>
现在使用最后一种方法,你不依赖于动作网址。
希望这有帮助!