Thursday, February 4, 2010

Fix “WPSC is undefined” javascript error in FBA web application in Sharepoint

Recently we encountered with strange error: after reconfiguration of Sharepoint application on the farm with 2 WFEs we got a javascript error “WPSC is undefined”. It was strange that this error appeared only for Internet zone with FBA. Although on Default zone with windows authentication there were no any errors. And it was not very clear what exactly configuration change caused this error.

After brief investigation of “WPSC is undefined” error I found that WPSC is defined in ie55up.js script. Several people wrote that they just added this script into theirs page and error disappeared. But it was not the way for us as this script existed in resulting html source (with several other core Sharepoint scripts):

   1: <script src="/_layouts/1035/init.js?rev=Fe8dn%2BZZbvb0W8rvYQjCLg%3D%3D"></script>
   2: <script type="text/javascript" language="javascript"
   3: src="/_layouts/1035/core.js?rev=e9C8lOHH8ryn9GXIlvHzqg%3D%3D" defer></script>
   4: <script type="text/javascript" language="javascript"
   5: src="/_layouts/1035/ie55up.js?rev=Ni7%2Fj2ZV%2FzCvd09XYSSWvA%3D%3D"></script>
   6: <script type="text/javascript" language="javascript"
   7: src="/_layouts/1035/search.js?rev=fo2j0xkK9jgYuNMH2DwaRg%3D%3D" defer></script>

I turned on script debugging in IE8 developer tools and it showed that there were errors during loading of several of these scripts (init.js and ie55up.js). It showed “Invalid character at position 1” error. I looked on the exact response of the server and result was surprising: instead of content of .js files server returned html page with the following error message:

   1: Value cannot be null. 
   2: Parameter name: value
   3:  at System.String.EndsWith(String value, StringComparison comparisonType) 
   4:  at Microsoft.SharePoint.ApplicationRuntime.
   5: SPRequestModule.PostAuthenticateRequestHandler(Object oSender, EventArgs ea) 
   6:  at System.Web.HttpApplication.
   7: SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 
   8:  at System.Web.HttpApplication.
   9: ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 

I.e. String.EndsWith() call inside SPRequestModule.PostAuthenticateRequestHandler() raised exception “Value cannot be null”. So initial error “WPSC is undefined” was just side effect of SPRequestModule’s failure during processing of request to ie55up.js script.

There were not much search results for this error. And no one of them contained neither the explanation of the reason nor the solution. As temporary fix people tried to change <compilation batch=”false”> on <compilation batch=”true”> in web.config located in 12/template/layouts folder – but it just expanded time between errors. I tried it also – and error really disappeared on short time but only on 1 of 2 WFEs in the farm. After several requests error occurred again (similar behavior is described for example here).

After that I decided to investigate error from other side – using Reflector. First of all I opened SPRequestModule.PostAuthenticateRequestHandler() and checked all occurrences of String.EndsWith()  calls. There are only 3 calls:

   1: private void PostAuthenticateRequestHandler(object oSender,
   2: EventArgs ea)
   3: {
   4: ...
   5: if (absolutePath.EndsWith(LoginUrl, StringComparison.OrdinalIgnoreCase) &&
   6:     (filePath.EndsWith(".css", StringComparison.OrdinalIgnoreCase) ||
   7:     filePath.EndsWith(".js", StringComparison.OrdinalIgnoreCase)))
   8:     {
   9:         context.SkipAuthorization = true;
  10:     }
  11: }
  12: ...
  13: }

As 2 calls contained constants as 1st parameter of String.EndsWith()  then only one of these 3 calls could cause “Value cannot be null” exception:

   1: absolutePath.EndsWith(LoginUrl, StringComparison.OrdinalIgnoreCase)

So LoginUrl was null because of some reasons. There is only 1 assignement of non null value to SPRequestModule.LoginUrl variable – in SPRequestModule.EnsureInitialize() method:

   1: private void EnsureInitialize(HttpRequest request)
   2: {
   3: ...
   4: application = SPWebApplication.Lookup(SPFarm.Local,
   5:     request.Url, true, out url, out info, out flag);
   6: if (null != application)
   7: {
   8:     LoginUrl = FormsAuthentication.LoginUrl;
   9:     ...
  10: }
  11: ...
  12: }

I checked that FormsAuthentication.LoginUrl contains valid non null value (just traced it in simple application layout page). So the only reason of having LoginUrl non initialized was returning of null in the following call:

   1: application = SPWebApplication.Lookup(SPFarm.Local,
   2:     request.Url, true, out url, out info, out flag);

After looking inside SPWebApplication.Lookup() method I’ve found that it uses host headers somehow:

   1: internal static SPWebApplication Lookup(...)
   2: {
   3: ...
   4: hostHeaderSiteInfo = SPSite.LookupHostHeaderSite(requestUri, farm);
   5: if (hostHeaderSiteInfo == null)
   6: {
   7:     ...
   8: }
   9: else
  10: {
  11:     contextWebApplication = (SPWebApplication)
  12:         farm.GetObject(hostHeaderSiteInfo.ApplicationId);
  13:     alternateUrl = null;
  14: }
  15: ...
  16: return contextWebApplication;
  17: }

And now I got it – one of the configuration change was removing host headers from IIS web sites on both WFEs on farm (there were some technical reasons for this). So I recover host headers of web sites in IIS settings, remove temporary files from Temporary ASP.Net files folder and restarted IIS. After that error disappeared.

PS. This is not 1st time when Reflector greatly helped me. In one of my previous posts I described how Sharepoint sets CurrentThread.CurrentUICulture depending on Language of SPWeb. And it was investigated also with help of Reflector.

4 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. I have a same problem and I did play with host headers. How do I recover host headers? I am not sure what was there before.

    I am also getting 'hierarchicalListBox' is undefined on my navigation settings page. Because it is my temporary box I initially was able to reinstall MOSS but that did not help. If I reinstall IIS will that fix a problem?


    Thanks a lot.

    ReplyDelete
  3. In most cases host headers contain domain name of your site:
    www.mysite.com
    mysite.com

    1. In server 2003 go to IIS settings
    2. Click on your web site and select Properties
    3. Select Web Site tab
    4. Click Advanced button
    5. Click Add
    6. In IP address select "All unassigned", TCP port (most probably is 80), Host Header Value = www.mysite.com (where www.mysite.com is domain name of your site)

    ReplyDelete
  4. Thanks for your prompt answer.

    To fix 'hierarchicalListBox' undefined on my navigation settings page I followed another suggestion.

    .js has to be included in the mime types under IIS. Added it and then restarted IIS

    ReplyDelete