Elmah 访问 Context.Request.ServerVariables 时抛出异常

发布于 2024-09-24 08:54:16 字数 3445 浏览 1 评论 0原文

我正在使用 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将会触发此错误

想法?

I'm using Elmah to log exceptions for my website, everything seems to be all working fine until one day I noticed that the 500 server errors are not being caught properly. I'm using following script to specifically ignore errors from ScriptResource.axd file.

<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>

It seems to be working fine when the first error is triggered. However, the next time this error is triggered Elmah stopped filtering and fails to send email. I was able to reproduce this problem locally and here's the source of the problem:

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

What I don't understand is how and why this occurs. I also tried other ServerVariables and so far I found out that HTTPS, HTTP_REFERER will NOT trigger this error when the same exception happen the second time. While URL, SCRIPT_NAME, PATH_INFO, PATH_TRANSLATED WILL trigger this error.

Thoughts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

叹沉浮 2024-10-01 08:54:17

好的!经过进一步挖掘,使用 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)

Okay! After further digging, it seems like you will NOT be able to access any of the DynamicServerVariable from ServerVariables["XXX"] when using Elmah's JScriptAssertion. However, I did found a workaround, seems like these DynamicServerVariable have public properties mapping on the HttpRequest object!!

Therefore, in my case where I'd like to access Context.Request.ServerVariables["URL"], I can replace the code with Context.Request.FilePath, which is how "URL" is mapped to in the HttpRequest object. This way, the JScriptAssertion would not throw exception when the exception is thrown the second time around.

Following are DynamicServerVariable and their properties mapping in 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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文