I am seeing some very odd behavior when trying to do a redirect with .NET MVC. I read somewhere to not do the redirect in a subroutine so I changed that part of the code, but I am still having the problem. This only happens in production (particularly with bots), and I can't reproduce it in the dev environment. I added in some logging to try to help but still don't understand what is happening (it was a poor man's solution because I don't have access to put debug symbols on the production server). The call stack doesn't even make sense because it says there is a recursive call that doesn't exist. Thanks in advance for any help!
Error details:
Step Number: 16, LangID: 1033, Language: en, Culture: us -
System.NullReferenceException: Object reference not set to an instance of an object. at [REMOVED]_Web.Controllers.MVC.HomeController.setLanguage(String language, String _culture)User Name: Anonymous
URL: [REMOVED]'A=0
User Agent: 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)
Exception Details:System.Exception: Step Number: 16, LangID: 1033, Language: en, Culture: us - System.NullReferenceException: Object reference not set to an instance of an object.
at [REMOVED]_Web.Controllers.MVC.HomeController.setLanguage(String language, String _culture)
at [REMOVED]_Web.Controllers.MVC.HomeController.setLanguage(String language, String _culture)
at [REMOVED]_Web.Controllers.MVC.HomeController.Init(String language, String culture)
at [REMOVED]_Web.Controllers.MVC.HomeController.ProdCatSearch(String language, String culture)
at lambda_method(Closure , ControllerBase , Object[] )
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 parameters)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult2.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.b__3d()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.b__3f()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass33.b__32(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<>c__DisplayClass2b.b__1c()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.b__1e(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.b__5(IAsyncResult asyncResult, ProcessRequestState innerState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
Source code:
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
catchblock from earlier in the script, will it re-enter the inner finally block before leaving the function? I assume since the inner exception is only catching theCultureNotFoundExceptionthat the outer catch would have to be the one catching theNullReferenceException? If so, does that catch execute and then step back into the finally block? I'm not familiar enough with the execution path regarding .NET exceptions. - War10ck