2010-09-22 90 views
1

我正在使用Elmah为我的网站记录异常,似乎一切正常,直到有一天我注意到500服务器错误没有被正确捕获。我正在使用以下脚本来特别忽略来自ScriptResource.axd文件的错误。Elmah在访问Context.Request.ServerVariables时抛出异常

<errorFilter> 
     <test> 
      <or> 
       <and> 
        <regex binding="FilterSourceType.Name" pattern="mail" /> 
        <jscript> 
         <expression> 
          <![CDATA[ 
          // @assembly mscorlib 
          // @assembly System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 
          // @import System.IO 
          // @import System.Web 
          (Context.Request.ServerVariables["URL"].match(/ScriptResource\.axd/i) && BaseException instanceof System.FormatException) 
          ]]> 
         </expression> 
        </jscript> 
       </and> 
      </or> 
     </test> 

当第一个错误被触发时,它似乎工作正常。但是,下次发生此错误时,Elmah会停止过滤并且无法发送电子邮件。我能够在本地重现这个问题,这里的问题的根源:

Microsoft.JScript.JScriptException: Object reference not set to an instance of an object. ---> System.NullReferenceException: Object reference not set to an instance of an object. 
    at System.Web.HttpServerVarsCollection.Get(String name) 
    at invoker2.Invoke(Object , Object[]) 
    at Microsoft.JScript.JSMethodInfo.Invoke(Object obj, BindingFlags options, Binder binder, Object[] parameters, CultureInfo culture) 
    at Microsoft.JScript.LateBinding.CallOneOfTheMembers(MemberInfo[] members, Object[] arguments, Boolean construct, Object thisob, Binder binder, CultureInfo culture, String[] namedParameters, VsaEngine engine, Boolean& memberCalled) 
    at Microsoft.JScript.LateBinding.Call(Binder binder, Object[] arguments, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters, Boolean construct, Boolean brackets, VsaEngine engine) 
    at Microsoft.JScript.LateBinding.Call(Object[] arguments, Boolean construct, Boolean brackets, VsaEngine engine) 
    at Microsoft.JScript.Call.Evaluate() 
    --- End of inner exception stack trace --- 
    at Microsoft.JScript.Block.Evaluate() 
    at Microsoft.JScript.FunctionObject.CallASTFunc(Object[] args, Object thisob, ScriptObject enclosing_scope, Closure calleeClosure, Binder binder, CultureInfo culture) 
    at Microsoft.JScript.FunctionObject.Call(Object[] args, Object thisob, ScriptObject enclosing_scope, Closure calleeClosure, Binder binder, CultureInfo culture) 
    at Microsoft.JScript.Closure.Call(Object[] args, Object thisob, Binder binder, CultureInfo culture) 
    at Microsoft.JScript.LateBinding.CallValue(Object val, Object[] arguments, Boolean construct, Boolean brackets, VsaEngine engine, Object thisob, Binder binder, CultureInfo culture, String[] namedParameters) 
    at Microsoft.JScript.LateBinding.CallValue(Object thisob, Object val, Object[] arguments, Boolean construct, Boolean brackets, VsaEngine engine) 
    at Elmah.Assertions.JScriptAssertion.FullTrustEvaluationStrategy.Eval(Object context) in C:\workspace\v2_psp\Elmah\src\Elmah\Assertions\JScriptAssertion.cs:line 312 

我不明白的是如何和为什么发生这种情况。我也试过其他ServerVariables,到目前为止我发现了HTTPS,HTTP_REFERER 不会触发此错误当第二次发生同样的异常。虽然URL,SCRIPT_NAME,PATH_INFO,PATH_TRANSLATED 触发此错误

想法?

+0

我发现触发这个错误的所有ServerVariables被定义为System.Web.DynamicServerVariable。我不知道他们为什么导致这个错误,但.... – BlueFox 2010-10-01 23:01:51

回答

1

好吧!进一步挖掘之后,在使用Elmah的JScriptAssertion时,似乎无法访问ServerVariables [“XXX”]中的任何DynamicServerVariable。但是,我确实找到了一个解决方法,看起来像这些DynamicServerVariable在HttpRequest对象上有公共属性映射!

因此,在我的情况下,我想访问Context.Request.ServerVariables [“URL”],我可以替换Context.Request.FilePath的代码,这是多么“URL”,在被映射到HttpRequest对象。这样,当第二次抛出异常时,JScriptAssertion不会抛出异常。

以下是DynamicServerVariable及其在HttpRequest中的属性映射。

ServerVariables  HttpRequest Property 
URL     FilePath 
SCRIPT_NAME   FilePath (Same as URL) 
PATH_INFO   Path 
PATH_TRANSLATED  PhysicalPathInternal 
QUERY_STRING  QueryStringText 
AUTH_TYPE   if (_context.User != null && _context.User.Identity.IsAuthenticated) Context.User.Identity.AuthenticationType, otherwise String.empy 
AUTH_USER   if (_context.User != null && _context.User.Identity.IsAuthenticated) Context.User.Identity.Name, otherwise String.empty 
REMOTE_USER   if (_context.User != null && _context.User.Identity.IsAuthenticated) Context.User.Identity.Name, otherwise String.empty (Same as AUTH_USER)