Elmah выдает исключение при доступе к Context.Request.ServerVariables

Я использую 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 БУДУТ вызывать эту ошибку.

Мысли?


person BlueFox    schedule 22.09.2010    source источник
comment
Я обнаружил, что все ServerVariables, вызывающие эту ошибку, определены как System.Web.DynamicServerVariable. Я не уверен, почему они вызывают эту ошибку, хотя....   -  person BlueFox    schedule 02.10.2010


Ответы (1)


Хорошо! После дальнейшего копания кажется, что вы НЕ сможете получить доступ ни к одной из DynamicServerVariable из ServerVariables["XXX"] при использовании JScriptAssertion от Elmah. Тем не менее, я нашел обходной путь, похоже, что эти 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)
person BlueFox    schedule 02.10.2010