Monday, November 23, 2009

Install Silverlight 3 Tools Offline

It seems quite stupid that the Silverlight 3 Tools installation will always look to download from internet even you have installed the Silverlight SDK by yourself. More absurdly, the download and installation will fail even you have connection to internet but by using a proxy, which is common in an office. The trick here is to extract them manually into the same folder:
  1. In cmd window, uncompress Silverlight SDK: silverlight_sdk.exe /x
  2. Uncompress Silverlight tools to the above chosen directory: Silverlight3_Tools.exe /x
  3. In the extracted folder, run VS_SilverlightTools_Setup.exe
  4. In the same folder, run VS90SP1-KB967143-enu.msp as well as VS90SP1-KB967144-enu.msp (ignore this failure)
The last 2 steps take a while, but eventually you should be able to open silverlight projects in Visual studio then.

Ref: Installing SilverLight 3 Visual Studio Tools Offline

Sunday, November 8, 2009

Simple way to invalidate SqlDataSource cache programmatically

EnableCaching and CacheDuration are the normal cache-related properties of the data source controls, but they don't give you the convenience to invalidate the cache on-demand. Some people use the SqlCacheDependency, where ASP.NET worker process will poll for changes in the SqlCacheTablesForChangeNotification when a change in monitored table triggers the "notification". This measure is somewhat clumsy in that:
  1. You have to use aspnet_regsql command line to enable notifications for the database;
  2. ASP.NET uses a polling mechanism, and you have to both write code and alter your web.config
There is a simpler way though: use CacheKeyDependency, where you make the data source cache dependent on another item in the data cache (CacheKeyDependency). Details follow:
  • Add CacheKeyDependency in aspx:
<asp:SqlDataSource ID="x" EnableCaching="True" CacheKeyDependency="MyCacheDependency" />
  • Add some code in aspx.cs:
protected void Page_Load(object sender, EventArgs e)
{ // Or somewhere else before the DataBind() takes place
  if (!IsPostBack)
  {
      ...
      if (Cache["MyCacheDependency"] == null)
      {
        Cache["MyCacheDependency"] = DateTime.Now;
      }
  }
}
  • Where you make changes to the database table and want to invalidate cache so that next time a data binding will see the changes:
// Evict cache items with an update in dependent cache:
Cache["MyCacheDependency"] = DateTime.Now;
You can use any value instead of DateTime.Now as long as they are different to trigger the refresh.
Ref: 1. ASP.NET Caching: SQL Cache Dependency With SQL Server 2000
2. Accessing and Updating Data in ASP.NET 2.0: Declaratively Caching Data

Sunday, November 1, 2009

Prevent IIS Session Timeout in ASP .NET

There are scenarios that a user may want to keep a long session alive. For example, a help desk operator logs into a web application and takes phone calls and in between submits changes to the backend systems. The phone call may last over an hour and the operator may stay in one web page and need that session to be valid when she submits the changes.
In ASP.NET, there are several common simple solutions for that. One of them is to set the session timeout attribute (minutes) in web.config.
<sessionState mode ="InProc" timeout="xxx"/>
Some people are confused at the timeout setting in web.config and another in IIS and ask which overwrites which. A simple experiment shows that the setting in web.config always overwrites the setting in IIS.
However, this is not complete for ASP .NET 2.0+. Open IIS->Application Pools->Select the Application pool for your application->Properties->Performance, set the idle timeout for "Shutdown worker processes after being idle for xxx minutes".
Otherwise, the worker process is still stopped after 20 minutes(default) and your session state will be lost.
Another way, if we do not want to rely on the settings in IIS, is to keep the session alive by ourselves in the application. Some people use an invisible frame and set auto refresh in http header, but if you are using a master page, that behavior will be propagated to all ASP pages. With .NET 2.0+ and a little bit Ajax, we have a simpler solution - add a timer in UpdatePanel. The timer will trigger a partial postback periodically, thus prods the session to be alive.
<asp:Content ID="ct" ContentPlaceHolderID="cphMain" runat="Server">
  <asp:ScriptManager ID="scriptMgr" runat="server" />

  <%-- Your content here --%>

  <%-- Heartbeat every 15min to keep session alive --%>
  <asp:UpdatePanel ID="updatePanel" runat="server">
    <ContentTemplate>
      <asp:Timer ID="timerPing" runat="server" Interval="900000">
      </asp:Timer>
    </ContentTemplate>
  </asp:UpdatePanel>
</asp:Content>
Ref:
1. Managing Session TimeOut using Web.Config
2. Preventing Session Timeouts in C# ASP .NET