【问题标题】:Elmah throws exception when accessing Context.Request.ServerVariablesElmah 在访问 Context.Request.ServerVariables 时抛出异常
【发布时间】:2010-09-22 18:01:05
【问题描述】:

我正在使用 Elmah 为我的网站记录异常,一切似乎都运行良好,直到有一天我注意到 500 个服务器错误没有被正确捕获。我正在使用以下脚本专门忽略 ScriptResource.axd 文件中的错误。

<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 触发此错误

想法?

【问题讨论】:

  • 我发现所有触发这个错误的ServerVariables都定义为System.Web.DynamicServerVariable。我不确定他们为什么会导致这个错误....

标签: elmah jscript.net


【解决方案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)

【讨论】:

    猜你喜欢
    • 2014-03-26
    • 2019-07-29
    • 1970-01-01
    • 1970-01-01
    • 2013-05-24
    • 2017-09-30
    • 2013-05-24
    • 2021-07-12
    • 1970-01-01
    相关资源
    最近更新 更多