Tuesday, March 27, 2007

Taking Advantage of SharePoint Session State Management

Knowing that the custom web application (which sits on top of SharePoint) that I am developing will be hosted by two web servers for high availability, I have designated a less-loaded back-end server as the State Server to host the session state of both web servers. Having gone through all the ropes on how to setup the State Server, at the end I found out that actually, nothing needs to be done. SharePoint 2007's Shared Services Provider has configured the web frontend to make use of SQL Server for state management. By default, state management using SQL Server is turned on when SSP is configured. It still can be turned on/off at SharePoint 3.0 Central Administration --> Application Management --> Office SharePoint Servers Shared Services --> Configure session state. A quick test shows that the session variables stored by the custom web application were indeed stored and retrieved successfully in between requests from different web servers. I guess that is another plus point for developing application on top of SharePoint. More information about MOSS state at http://technet2.microsoft.com/Office/en-us/library/ffa4a256-6885-4295-a712-537ce82b9a0c1033.mspx?mfr=true.

Sunday, March 18, 2007

Be cautious of web.config settings during deployments

A colleague of mine just solved a SharePoint performance issue that pondered our project team for days. The discovery was by accident and the cause is quite classic. I decided to put in as much detail as possible to make this an interesting read. And the story goes... We are building a custom web application that sits on top of SharePoint 2007. Not having enough servers for different phases of the development, a box is allocated for two purpose, training and SIT. Training was installed on the host machine, while SIT is installed as a virtual server on the same box. All went well until suddenly the SIT SharePoint pages were loading at crawling speed. What's funny was that shutting down the SIT would cause the Training instance to slow down as well, but only at MySite. Eventually, the infra team configured their ISA and DNS settings and both servers are working normally again. Weeks gone by until the issue resurfaces when SIT were shutdown again and causes the Training environment to crawling speed. Wouldn't want to bring impact to training, we started back SIT immediately, and decided to look into it later when we have the time (That never happen). By chance, a colleague of mine were setting up a VPC version of the SharePoint application and faces the same performance issue on the VPC. Again, only on happens to MySite. After going through all the web.config settings, making the changes that seems logical, MySite is running at top speed again. What actually causes the problem is due to the Enterprice Library configuration in web.config. One of the parameter of the configuration settings were machineName, which is set to the machine name of the SIT server. This means when the application tries to write logs, it tries to write to the SIT server's Application log. MySite is where enterprise library's logging were used heavily. This explains why:
  1. Infra team has to configure ISA and DNS pointing properly so that Training server can write event logs to SIT server. If training server can't find SIT server to write log, it waits until timeout occurs.
  2. SIT server shutdown will cause slow down in Training server.
  3. VPC version is slow because it was seperated from the LAN and has no access to SIT server.

The moral of the story So why does this happen in the first place? Often we copy web.config for deployment instead of making manual changes to the target environment's web.config files. Copying the settings from SIT server to Training server without making all the necessary changes is the root of this issue.

Therefore, one should go through the whole web.config settings throughly to ensure that the settings are meant for the target deployment environment.

Ajax Bandwidth Overhead

Although Ajax reduces the postback size for ASP.NET applications, it does have a little drawback. Ajax rely on a suite of javascript library to perform its magic. Those javascript files such as ScriptResource.axd and WebResource.axd needs to be downloaded to the client browser. First I would thought, web browsers would cache these files. So the users would only need to download these files once only, right? A close inspection to the requests sent to the servers for these files show that they were requested with query strings at the back e.g. .../WebResource.axd?d=2KPNGySHzRkl024_lWT1Qg2&t=633052587689473359. Usually browsers will not cache such files. The more Ajax features you implement into your ASP.NET application, more js files need to be downloaded. However, the size of these javascript files can be reduced by:
  1. Ensure debug mode is set to off in the web.config. For my case, the reduction of the *.axd files went from over 300+kb to 128kb. That's 60% size reduction.
  2. Making use of IIS compression. Although I suspect this wouldn't help much.

Therefore, one should consider this size factor when implementing Ajax into their web application. Some similar functionalities still can be achieved without using Ajax.

Saturday, March 17, 2007

Building Ajax-enabled custom web application on top of SharePoint

Ajax seems to be the in-thing for any web application nowadays. It is easy to implement into to existing ASP.NET application and bring huge improvement in the total user experience of a web application.

However, building an Ajax-enabled custom web application on top of SharePoint requires some tweaking before you get the wow effect of Ajax.

  1. If the Ajax-enabled custom application uses the SharePoint master pages, such as default.master master page, remove this SharePoint tag from it: <wssuc:Welcome id="IdWelcome" runat="server" EnableViewState="false"></wssuc:Welcome>. This affects Ajax postbacks. Removing it will partially fix the problem, e.g. one Ajax postback can be made, but subsequently no postbacks.
  2. Open LAYOUTS\1033\init.js file and look for javascript function _spFormOnSubmitWrapper. Under “if (_spFormOnSubmitCalled)” code block, remove/comment the “return false;” code. Not sure what is the effect of removing this bit though thus do it on your own risk!

Alternatively, the javascript function _spFormOnSubmitWrapper can be overwritten only on the pages that uses Ajax. This can be done by puting the modified version of the js function to a seperate .js file and reference it right after the line where reference to init.js were made.

Thanx to the post from Vincent Rothwell and comment by Phillip Lanier.

Turn on SharePoint error messages

Building application on top of SharePoint would be easier if exceptions thrown from the custom application are shown on the SharePoint error page. By default, SharePoint only shows the generic error message, "Unknown error occured". It does not show the cause of the error and it is difficult to debug the custom application.

Fortunately, found a posting from Shane Perran and Andrew Connell that shows how to give more sense to the errors thrown by modifying the default SharePoint web.config file:

  • Turn the call stack on by searching for the SafeMode element and set CallStack="true".
  • Turn off the SharePoint error pages by turning off custom error pages: search for customErrors tag and set mode="Off".
  • And also, search compilation tag and set debug="true".

Wednesday, March 7, 2007

SQL Server login failed due to "The password of the account must be changed"

After deploying an ASP.NET application to the production server, I encoutnered this error: Login failed for user 'db_user'. Reason: The password of the account must be changed. The application is using SQL user authentication to logon to SQL server. Therefore, a close inspection on the user account is warranted. It appears that the application user account has set the Enforce password policy, Enforce password expiration and User must change password at next login were turned on. Therefore the password must be modified before the application could access the database. I've got hold of the the DBA login to logon to the database server, and try to remove the checks mentioned above on the application user account, but an error says MUST_CHANGE constraint, and the checks cannot be removed. Therefore, I login into the SQL Server again using the application user account in question, and then I get a prompt to modify the password. Once the password is changed, the checks can be removed, and I change the password back to the previous password that was meant to be used for production. That seems to solve the problem as the application is able to load the data drom DB without error.