MVC ActionResult重定向

时间:2016-01-27 19:35:45

标签: asp.net-mvc vb.net

在尝试使用.NET MVC进行重定向时,我看到了一些非常奇怪的行为。我在某处读到了不在子程序中进行重定向所以我改变了部分代码,但我仍然遇到了问题。这只发生在生产中(特别是机器人),我无法在开发环境中重现它。我添加了一些日志记录试图帮助但仍然不明白发生了什么(这是一个穷人的解决方案,因为我没有权限在生产服务器上放置调试符号)。调用堆栈甚至没有意义,因为它说有一个不存在的递归调用。在此先感谢您的帮助!

错误详情:

  

步骤编号:16,LangID:1033,语言:en,文化:我们 -

System.NullReferenceException:对象引用未设置为对象的实例。      at [REMOVED] _Web.Controllers.MVC.HomeController.setLanguage(String language,String _culture)

     

用户名:匿名

     

网址: [已删除] 'A = 0
用户代理:Mozilla / 5.0(Windows; U; Windows NT 5.1; pt-PT; rv:1.9.1.2)Gecko / 20090729 Firefox / 3.5.2(.NET CLR 3.5.30729)

异常详情:

     

System.Exception:步骤编号:16,LangID:1033,语言:en,文化:我们 - System.NullReferenceException:对象引用未设置为对象的实例。
[REMOVED] _Web.Controllers.MVC.HomeController.setLanguage(String language,String _culture)
[REMOVED] _Web.Controllers.MVC.HomeController.setLanguage(String language,String _culture) ) [REMOVED] _Web.Controllers.MVC.HomeController.Init(String language,String culture)
[REMOVED] _Web.Controllers .MVC.HomeController.ProdCatSearch(String language,String culture)
在lambda_method(Closure,ControllerBase,Object [])
在System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext,IDictionary2 parameters)< System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext,ActionDescriptor actionDescriptor,IDictionary2)参数)
在System.Web.Mvc.Async.AsyncControllerActionInvoker.b__39(IAsyncResult asyncResult,ActionInvocation innerInvokeState)
在System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult2.CallEndDelegate(IAsyncResult asyncResult)
在System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.b__3d()
在System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters。&lt;&gt; c__DisplayClass46.b__3f()
在System。 Web.Mvc.Async.AsyncControllerActionInvoker。&lt;&gt; c__DisplayClass33.b__32(IAsyncResult asyncResult)
在System.Web.Mvc.Async.AsyncControllerActionInvoker。&lt;&gt; c__DisplayClass21。&lt;&gt; c__DisplayClass2b.b__1c()<在System.Web.Mvc.Async.AsyncControllerActionInvoker。&lt;&gt; c__DisplayClass21.b__1e(IAsyncResult asyncResult)
在System.Web.Mvc.Controller.b__1d(IAsyncResult asyncResult,ExecuteCoreState innerState)
在System.Web.Mvc.Async.Asy ncResultWrapult.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
在System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)
在System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) )在System.Web.Mvc.MvcHandler.b__5(IAsyncResult asyncResult,ProcessRequestState innerState)
在System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult)
在系统System.Web.HttpApplication.ExecuteStep中的.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
(IExecutionStep step,Boolean&amp; completedSynchronously)

源代码:

Private Sub setLanguage(language As String, _culture As String)
    Dim stepNumber As Integer = 0
    Try
        Dim langCookie As HttpCookie
        Dim hasException As Boolean = False

        Try
            If (String.IsNullOrEmpty(language) OrElse String.IsNullOrEmpty(_culture)) Then
                language = "en"
                _culture = "us"
            End If

            stepNumber = 1
            Dim languages = clsAppSettings.Instance.GetAppSettingTable(Of String)("Language")

            For Each lang In languages
                supportedLangs.Add(New LanguageInfo(lang))
            Next
            supportedLangs.Sort(Function(x, y) x.SortOrder.CompareTo(y.SortOrder))

            langCookie = HttpContext.Request.Cookies.Get("langID")
            stepNumber = 2
            If langCookie IsNot Nothing AndAlso Not String.IsNullOrWhiteSpace(langCookie.Value) Then
                stepNumber = 3
                LangId = langCookie.Value
                CultureInfo.CreateSpecificCulture(language + "-" + _culture)
                stepNumber = 4
            Else
                stepNumber = 5
                Dim culture As CultureInfo
                If language.ToLower = "en" And _culture.ToLower = "us" Then
                    stepNumber = 6
                    Dim langIdFromBrowser As String = String.Empty
                    Dim browserLangs = Request.UserLanguages
                    For Each browserLang In browserLangs
                        culture = CultureInfo.CreateSpecificCulture(browserLang.ToLowerInvariant().Trim())
                        langIdFromBrowser = culture.LCID.ToString
                        If Not String.IsNullOrWhiteSpace(langIdFromBrowser) Then
                            If (From items In supportedLangs Where items.Id = CInt(langIdFromBrowser)).Any Then
                                LangId = langIdFromBrowser
                                Exit For
                            End If
                        End If
                    Next
                    stepNumber = 7
                    If String.IsNullOrEmpty(LangId) Then
                        LangId = "1033"
                    End If
                Else
                    stepNumber = 8
                    culture = CultureInfo.CreateSpecificCulture(language + "-" + _culture)
                    LangId = culture.LCID.ToString
                    If Not String.IsNullOrWhiteSpace(LangId) Then
                        If Not (From items In supportedLangs Where items.Id = CInt(LangId)).Any Then
                            LangId = "1033"
                        End If
                    End If
                    stepNumber = 9
                End If

                ' Correct for the fact that SharePoint uses Spanish Traditional vs Spanish Modern Sort
                If LangId = "1034" Then
                    LangId = "3082"
                End If
                stepNumber = 10

            End If

        Catch ex As CultureNotFoundException

            stepNumber = 11
            If String.IsNullOrEmpty(LangId) Then
                LangId = "1033"
            End If
            hasException = True

        Finally

            ' Final check to ensure NO empty value ever makes it past this point.
            If String.IsNullOrWhiteSpace(LangId) Then
                LangId = "1033"
            End If

            langCookie = New HttpCookie("langID", LangId)
            langCookie.Expires = Date.Now().AddYears(1)
            Web.HttpContext.Current.Response.Cookies.Add(langCookie)
            stepNumber = 12
            If hasException OrElse CultureInfo.CreateSpecificCulture(language + "-" + _culture).LCID.ToString() <> LangId Then
                stepNumber = 13
                Dim newCulture As New CultureInfo(CInt(LangId))
                stepNumber = 14
                Dim cultureValues As String() = newCulture.Name.Split("-"c)
                Dim rUrl As String = Request.Url().OriginalString()
                Dim replacement As String = (cultureValues(0) + "-" + cultureValues(1)).ToLower()
                rUrl = rUrl.Replace((language + "-" + _culture), replacement)
                'Response.Redirect(rUrl, False)
                'HttpContext.ApplicationInstance.CompleteRequest()
            End If

            stepNumber = 15
            ViewData("SelectedLang") = LangId
            ViewData("SupportedLangs") = supportedLangs
            transObj = Translations.GetTranslations(LangId)
            ViewData("Translations") = New JavaScriptSerializer().Serialize(transObj)

            stepNumber = 16
        End Try

    Catch ex As Exception
        Throw New Exception(String.Format("Step Number: {0}, LangID: {1}, Language: {2}, Culture: {3} - {4}", stepNumber, LangId, language, _culture, ex.ToString()))
    End Try

End Sub

1 个答案:

答案 0 :(得分:2)

要解决这篇文章,所以没有人可能浪费时间阅读这个庞大的方法并可能帮助某人,我会写出解决方案。

首先,@ b.pell建议修复日志,从右脚开始。我将stepNumber更改为一个int列表然后只是String.Join(" ", steps)将其打印到日志中。

其次,这是对Finally的不当使用。 Finally应该只用于清理。在这种情况下,抛出异常时,Finally块中的代码不应该运行。

另一个障碍是这种方法很庞大,难以隔离,特别是在没有调试符号的情况下运行并且只有堆栈跟踪时。

最终,这行代码创建了导致NullReferenceException的null。所以修复只是一个简单的空检查。

culture = CultureInfo.CreateSpecificCulture(language + "-" + _culture)

如果我们能够在生产服务器上删除调试符号或完成我提到的其他一些事情,那么可以非常快速地跟踪它。