<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8000715364570585519</id><updated>2024-08-30T06:48:22.210-07:00</updated><category term="C#"/><category term="IIS"/><category term="JavaScript"/><title type='text'>C# Tips And Tricks - Shaji</title><subtitle type='html'>Some tips and tricks in ASP.NET either implemented or tried by me.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://csharp-tipsandtricks.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8000715364570585519/posts/default'/><link rel='alternate' type='text/html' href='http://csharp-tipsandtricks.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Shaji PM</name><uri>http://www.blogger.com/profile/00372646697520630840</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRwC8OSkyqcFwvpE1bHxB2tKhSr5-NzQpRp2mxu6LlaFZHgEZgz6KtJcuHvNGLpoa_G0eL1dyBFiA--HnD6vNylFGFvonpscRhtAlvkcixkPMTWyQwJNa0DUG3cYryJg/s220/blog.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>8</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8000715364570585519.post-3366593111302380107</id><published>2010-01-13T23:37:00.000-08:00</published><updated>2010-01-20T02:56:21.502-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>Identifying whether execution context is win or web</title><content type='html'>When writing components which targets both web and desktop applications, there might be instances where there is need to check under which context the code is running.&lt;br /&gt;
&lt;br /&gt;
Checking &lt;i&gt;System.Web.HttpContext.Current&lt;/i&gt; won&#39;t work always. If the code is running under the context of main thread this always works. But if a thread is spawn, in the new thread &lt;i&gt;System.Web.HttpContext.Current&lt;/i&gt; will return null even if it is running under web context.&lt;br /&gt;
&lt;br /&gt;
Some debugging showed me that &lt;i&gt;System.Web.HttpRuntime.AppDomainId&lt;/i&gt; is the right candidate for checking this. &lt;i&gt;System.Web.HttpRuntime.AppDomainId&lt;/i&gt; returns null when the code is running under windows context, but always returns a non-null string value while running under web context regardless of whether the code is running under main thread or a spawned thread.&lt;br /&gt;
&lt;br /&gt;
So the below piece of code can be used to check whether the code is running under web context.&lt;br /&gt;
&lt;pre class=&quot;brush: csharp;&quot;&gt;/// &amp;lt;summary&amp;gt;
/// Specifies whether the current execution context is Web.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;returns&amp;gt;True if current context is Web.&amp;lt;/returns&amp;gt;
public bool IsWebApplicationContext()
{
    return !string.IsNullOrEmpty(System.Web.HttpRuntime.AppDomainId);
}
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharp-tipsandtricks.blogspot.com/feeds/3366593111302380107/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharp-tipsandtricks.blogspot.com/2010/01/identifying-whether-execution-context.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8000715364570585519/posts/default/3366593111302380107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8000715364570585519/posts/default/3366593111302380107'/><link rel='alternate' type='text/html' href='http://csharp-tipsandtricks.blogspot.com/2010/01/identifying-whether-execution-context.html' title='Identifying whether execution context is win or web'/><author><name>Shaji PM</name><uri>http://www.blogger.com/profile/00372646697520630840</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRwC8OSkyqcFwvpE1bHxB2tKhSr5-NzQpRp2mxu6LlaFZHgEZgz6KtJcuHvNGLpoa_G0eL1dyBFiA--HnD6vNylFGFvonpscRhtAlvkcixkPMTWyQwJNa0DUG3cYryJg/s220/blog.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8000715364570585519.post-158806901195943102</id><published>2010-01-12T04:04:00.000-08:00</published><updated>2010-01-12T06:10:45.671-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>Simple WCF Service, Host and Client</title><content type='html'>We will create a simple WCF service which will be hosted in a custom console application. A win form application is used as the WCF client.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;WCF Service&lt;/b&gt;&lt;br /&gt;
We will start with a &lt;i&gt;ServiceContract&lt;/i&gt; interface which will be implemented by a &lt;i&gt;ServiceBehavior&lt;/i&gt; class.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp;&quot;&gt;[ServiceContract()]
public interface IUserService
{
    [OperationContract]
    void AddUser(UserDataContract user);
    [OperationContract]
    void RemoveUser(int userId);
    [OperationContract]
    List&amp;lt;UserDataContract&amp;gt; GetUsers();
    [OperationContract]
    string Echo(string msg);
}

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class UserService : IUserService
{
    List&amp;lt;UserDataContract&amp;gt; users = new List&amp;lt;UserDataContract&amp;gt;();

    public void AddUser(UserDataContract user)
    {
        users.Add(user);
        Console.WriteLine(string.Format(&quot;User {0} {1} added&quot;, user.FirstName, user.LastName));
    }
    public void RemoveUser(int userId)
    {
        for (int i = 0; i &amp;lt; users.Count; i++)
        {
            if (users[i].Id == userId)
            {
                Console.WriteLine(string.Format(&quot;User {0} {1} removed&quot;, users[i].FirstName, users[i].LastName));
                users.Remove(users[i]);
                return;
            }
        }
        Console.WriteLine(string.Format(&quot;User {0} does not exist&quot;, userId));
    }
    public List&amp;lt;UserDataContract&amp;gt; GetUsers()
    {
        Console.WriteLine(string.Format(&quot;User list returned. {0} users&quot;, users.Count));
        return users;
    }
    public string Echo(string msg)
    {
        Console.WriteLine(&quot;Invoked with &quot; + msg);
        return &quot;Haaalo, &quot; + msg;
    }
}&lt;/pre&gt;&lt;br /&gt;
Here the service InstanceContextMode is declared as InstanceContextMode.Single to have a singleton behavior.&lt;br /&gt;
&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.servicemodel.instancecontextmode.aspx&quot;&gt;Please click here for more details for InstanceContextMode in msdn.&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Now a &lt;i&gt;DataContract&lt;/i&gt; can be created which is the agreement between service and client that abstractly describes the data to be exchanged.&lt;br /&gt;
&lt;br /&gt;
&lt;pre  class=&quot;brush: csharp;&quot;&gt;[DataContract]
public class UserDataContract
{
    int id;
    string firstName;
    string lastName;

    [DataMember]
    public int Id
    {
        get { return id; }
        set { id = value; }
    }

    [DataMember]
    public string FirstName
    {
        get { return firstName; }
        set { firstName = value; }
    }

    [DataMember]
    public string LastName
    {
        get { return lastName; }
        set { lastName = value; }
    }
}
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;WCF Service Host&lt;/b&gt;&lt;br /&gt;
A Service Host is needed to host the service just created. A simple console application is used as a host here. The below configuration specifies the end points exposed by the service. Different endpoint can be created for different binding.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp;&quot;&gt;&amp;lt;configuration&amp;gt;
    &amp;lt;system.serviceModel&amp;gt;
        &amp;lt;services&amp;gt;
            &amp;lt;service name=&quot;UserServiceLibrary.UserService&quot;&amp;gt;
                &amp;lt;endpoint address=&quot;http://localhost:8080/userservice/svc&quot; binding=&quot;basicHttpBinding&quot;
                    bindingConfiguration=&quot;&quot; contract=&quot;UserServiceLibrary.IUserService&quot; /&amp;gt;
    &amp;lt;endpoint address=&quot;net.tcp://localhost:8081/userservice/svc&quot; binding=&quot;netTcpBinding&quot;
                    bindingConfiguration=&quot;&quot; contract=&quot;UserServiceLibrary.IUserService&quot; /&amp;gt;
            &amp;lt;/service&amp;gt;
        &amp;lt;/services&amp;gt;
    &amp;lt;/system.serviceModel&amp;gt;
&amp;lt;/configuration&amp;gt;

class Program
{
    static void Main(string[] args)
    {
        using (ServiceHost host = new ServiceHost(
        typeof(UserService), new Uri(&quot;http://localhost:8085/userservice&quot;)))
        {
            host.Open();

            Console.WriteLine(&quot;{0} is open and has the following endpoints:\n&quot;,
                host.Description.ServiceType);

            int i = 1;
            foreach (ServiceEndpoint end in host.Description.Endpoints)
            {
                Console.WriteLine(&quot;Endpoint #{0}&quot;, i++);
                Console.WriteLine(&quot;Address: {0}&quot;, end.Address.Uri.AbsoluteUri);
                Console.WriteLine(&quot;Binding: {0}&quot;, end.Binding.Name);
                Console.WriteLine(&quot;Contract: {0}\n&quot;, end.Contract.Name);
            }
            Console.ReadLine();
        }
    }
}
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;WCF Win Client&lt;/b&gt;&lt;br /&gt;
An interactive win form application is used as the client. The below configuration defines the named endpoint configurations used by the ChannelFactory. These addresses should match with the addresses specified earlier with the host configuration.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp;&quot;&gt;&amp;lt;configuration&amp;gt;
 &amp;lt;system.serviceModel&amp;gt;
  &amp;lt;client&amp;gt;
   &amp;lt;endpoint name=&quot;usHttpEndpoint&quot;
     address=&quot;http://localhost:8080/userservice/svc&quot;
     binding=&quot;basicHttpBinding&quot;
     contract=&quot;UserServiceLibrary.IUserService&quot;/&amp;gt;
   &amp;lt;endpoint name=&quot;usTcpEndpoint&quot;
     address=&quot;net.tcp://localhost:8081/userservice/svc&quot;
     binding=&quot;netTcpBinding&quot;
     contract=&quot;UserServiceLibrary.IUserService&quot;/&amp;gt;
  &amp;lt;/client&amp;gt;
 &amp;lt;/system.serviceModel&amp;gt;
&amp;lt;/configuration&amp;gt;

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void btnAdd_Click(object sender, EventArgs e)
    {
        try
        {
            using (ChannelFactory&amp;lt;IUserService&amp;gt; httpFactory = new ChannelFactory&amp;lt;IUserService&amp;gt;(&quot;usHttpEndpoint&quot;))
            {
                IUserService svc = httpFactory.CreateChannel();
                UserDataContract user = new UserDataContract();
                user.Id = int.Parse(userId.Text);
                user.FirstName = firstName.Text;
                user.LastName = lastName.Text;
                svc.AddUser(user);
            }
        }
        catch (Exception ex)
        {
            output.Text = ex.Message;
        }
    }

    private void btnDelete_Click(object sender, EventArgs e)
    {
        try
        {
            using (ChannelFactory&amp;lt;IUserService&amp;gt; httpFactory = new ChannelFactory&amp;lt;IUserService&amp;gt;(&quot;usHttpEndpoint&quot;))
            {
                IUserService svc = httpFactory.CreateChannel();
                svc.RemoveUser(int.Parse(userId.Text));
            }
        }
        catch (Exception ex)
        {
            output.Text = ex.Message;
        }
    }

    private void btnShowAll_Click(object sender, EventArgs e)
    {
        try
        {
            using (ChannelFactory&amp;lt;IUserService&amp;gt; httpFactory = new ChannelFactory&amp;lt;IUserService&amp;gt;(&quot;usHttpEndpoint&quot;))
            {
                IUserService svc = httpFactory.CreateChannel();
                List&amp;lt;UserDataContract&amp;gt; users = svc.GetUsers();
                StringBuilder sb = new StringBuilder();
                foreach (UserDataContract user in users)
                {
                    sb.AppendFormat(&quot;{0} {1}/{2}\r\n&quot;, user.FirstName, user.LastName, user.Id);
                }
                output.Text = sb.ToString();
            }
        }
        catch (Exception ex)
        {
            output.Text = ex.Message;
        }
    }
}
&lt;/pre&gt;&lt;br /&gt;
Below is a snapshot of the client form where in we can add, delete and list the users.&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-lfxEaqi8L3sTpLUNDouYXS6h4rMjaU-LDBa835uccDvNLZnDtYux1pGRTw29C0AAaGAbfZoYK5DIzMRXblzkVmZHvqKFnjvs_aonni1xKRZpp3GQcWBnTUfuwcO-1xkmfzxIWjzSaKnv/s1600-h/Service+Client+UI.JPG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; ps=&quot;true&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-lfxEaqi8L3sTpLUNDouYXS6h4rMjaU-LDBa835uccDvNLZnDtYux1pGRTw29C0AAaGAbfZoYK5DIzMRXblzkVmZHvqKFnjvs_aonni1xKRZpp3GQcWBnTUfuwcO-1xkmfzxIWjzSaKnv/s320/Service+Client+UI.JPG&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Now the service is ready to be tested. Start the host console application and once ready, start the client to communicate with the service.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Output&lt;/b&gt;&lt;br /&gt;
After adding 2 users and retrieving the list of users the output will look as below.&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgw_HCGlQE5ykk8d9gFwkYsaEuoyqys6cNfF3qe9U0O1YmozGom_7xXnAWYjL2sjW_0-khgdSl8m-GLpQYYx4qrGTbNuqvxONx5s9K_dDKf3DlBF_UpatjtCxFVqZZLfScyq0iuzE8BRdfv/s1600-h/Service+Host.JPG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; ps=&quot;true&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgw_HCGlQE5ykk8d9gFwkYsaEuoyqys6cNfF3qe9U0O1YmozGom_7xXnAWYjL2sjW_0-khgdSl8m-GLpQYYx4qrGTbNuqvxONx5s9K_dDKf3DlBF_UpatjtCxFVqZZLfScyq0iuzE8BRdfv/s320/Service+Host.JPG&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTzXm9qb58_4XjLt6nkRjt3dthSiinsHklnhYzKQ9pbcjPp7tzHHUK4RkHlVwTzT-tIcfySjqqBNFJ-Hj_3VGsbfvEy8Bw-C9WMEw0ye1eZNSjIAmW7rHCKt6rrSzi_5k608xuUJR6NPlc/s1600-h/Service+Client.JPG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; ps=&quot;true&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTzXm9qb58_4XjLt6nkRjt3dthSiinsHklnhYzKQ9pbcjPp7tzHHUK4RkHlVwTzT-tIcfySjqqBNFJ-Hj_3VGsbfvEy8Bw-C9WMEw0ye1eZNSjIAmW7rHCKt6rrSzi_5k608xuUJR6NPlc/s320/Service+Client.JPG&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharp-tipsandtricks.blogspot.com/feeds/158806901195943102/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharp-tipsandtricks.blogspot.com/2010/01/simple-wcf-service-host-and-client.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8000715364570585519/posts/default/158806901195943102'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8000715364570585519/posts/default/158806901195943102'/><link rel='alternate' type='text/html' href='http://csharp-tipsandtricks.blogspot.com/2010/01/simple-wcf-service-host-and-client.html' title='Simple WCF Service, Host and Client'/><author><name>Shaji PM</name><uri>http://www.blogger.com/profile/00372646697520630840</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRwC8OSkyqcFwvpE1bHxB2tKhSr5-NzQpRp2mxu6LlaFZHgEZgz6KtJcuHvNGLpoa_G0eL1dyBFiA--HnD6vNylFGFvonpscRhtAlvkcixkPMTWyQwJNa0DUG3cYryJg/s220/blog.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-lfxEaqi8L3sTpLUNDouYXS6h4rMjaU-LDBa835uccDvNLZnDtYux1pGRTw29C0AAaGAbfZoYK5DIzMRXblzkVmZHvqKFnjvs_aonni1xKRZpp3GQcWBnTUfuwcO-1xkmfzxIWjzSaKnv/s72-c/Service+Client+UI.JPG" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8000715364570585519.post-3797429208343014558</id><published>2009-12-31T06:52:00.000-08:00</published><updated>2010-01-03T19:42:31.445-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="IIS"/><title type='text'>Getting list of applications in a site from IIS metabase</title><content type='html'>We will start with creating a class for storing the application details.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp;&quot;&gt;public class IisWebApplication
{
   private string _Name = &quot;&quot;;
   public string Name
   {
      get { return _Name; }
      set { _Name = value; }
   }

   private string _AspNetFrameworkVersion = &quot;&quot;;
   public string AspNetFrameworkVersion
   {
      get { return _AspNetFrameworkVersion; }
      set { _AspNetFrameworkVersion = value; }
   }

   private string _Description = &quot;&quot;;
   public string Description
   {
      get { return _Description; }
      set { _Description = value; }
   }

   private string _FolderPath;
   public string FolderPath
   {
      get { return _FolderPath; }
      set { _FolderPath = value; }
   }
}&lt;/pre&gt;&lt;br /&gt;
As specified in my earlier post, each web site is assigned a unique integer value. The path for accessing a site will look like IIS://localhost/W3SVC/{site number}. The below method can help in getting the application details associated with a website passed as siteId. You can also specify whether to get details of sub applications.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp;&quot;&gt;public List&amp;lt;IisWebApplication&amp;gt; GetWebApplications(int siteId, bool showSubApplications)
{
   _ApplicationPools = GetApplicationPools();

   List&amp;lt;IisWebApplication&amp;gt; webApps = new List&amp;lt;IisWebApplication&amp;gt;();
   string MetabaseRootPath = @&quot;IIS://localhost/W3SVC/&quot; + siteId.ToString() + &quot;/ROOT&quot;;
   DirectoryEntry appEntry = null;
   try
   {
      appEntry = new DirectoryEntry(MetabaseRootPath);
      foreach (DirectoryEntry s in appEntry.Children)
      {
         CheckAndAddWebApplication(s, webApps, showSubApplications);
      }
   }
   catch { }
   finally
   {
      if (appEntry != null)
         appEntry.Close();
   }
   return webApps;
}

private void CheckAndAddWebApplication(DirectoryEntry entry, List&amp;lt;IisWebApplication&amp;gt; webApps, bool addSubApplications)
{
   bool reserved = true;
   if (IsWebApplicationEntry(entry))
   {
      reserved = IsReservedWebApplication(entry.Name);
      if (!reserved)
         webApps.Add(GetWebApplication(entry));
   }
   if (entry.Children != null &amp;amp;&amp;amp; addSubApplications &amp;amp;&amp;amp; !reserved)
   {
      foreach (DirectoryEntry s in entry.Children)
      {
         CheckAndAddWebApplication(s, webApps, addSubApplications);
      }
   }
}

private IisWebApplication GetWebApplication(DirectoryEntry entry)
{
   IisWebApplication webApp = new IisWebApplication();
   webApp.Name = GetApplicationName(entry);
   webApp.AspNetFrameworkVersion = GetAspNetVersion(entry);
   webApp.FolderPath = GetApplicationFolderPath(entry);
   if (_ApplicationPools != null)
   {
      string appPoolName = entry.Properties[&quot;AppPoolId&quot;].Value.ToString();
      webApp.ApplicationPool = GetApplicationPoolFromList(appPoolName);
   }
   return webApp;
}

private bool IsWebApplicationEntry(DirectoryEntry entry)
{
   string keyType = entry.Properties[&quot;KeyType&quot;].Value.ToString();
   if (keyType == &quot;IIsWebDirectory&quot; || (keyType == &quot;IIsWebVirtualDir&quot; &amp;amp;&amp;amp; entry.Properties[&quot;Path&quot;].Value != null))
   {
      string[] appNames = GetApplicationName(entry).Split(&quot;/&quot;.ToCharArray());
      if (appNames[appNames.Length - 1] == entry.Name)
         return true;
   }
   return false;
}

private string GetApplicationName(DirectoryEntry entry)
{
   string appRoot = entry.Properties[&quot;AppRoot&quot;].Value.ToString();
   string matchString = &quot;/ROOT/&quot;;
   int index = appRoot.ToUpper().IndexOf(matchString);
   if (index &amp;gt; -1)
      return appRoot.Substring(index + matchString.Length);

   return entry.Name;
}

private bool IsReservedWebApplication(string appName)
{
   if (appName.StartsWith(&quot;_vti_&quot;) || appName == &quot;_private&quot; || appName == &quot;bin&quot; || appName == &quot;Printers&quot;
      || appName == &quot;aspnet_client&quot;)
      return true;
   return false;
}

private string GetApplicationFolderPath(DirectoryEntry entry)
{
   string keyType = entry.Properties[&quot;KeyType&quot;].Value.ToString();
   if (keyType == &quot;IIsWebDirectory&quot;)
   {
      string path = entry.Path;
      string matchString = &quot;/ROOT/&quot;;
      int index = path.IndexOf(matchString);
      return &quot;/&quot; + path.Substring(index + matchString.Length);
   }
   else if (keyType == &quot;IIsWebVirtualDir&quot;)
   {
      return entry.Properties[&quot;Path&quot;].Value.ToString();
   }
   return &quot;&quot;;
}&lt;/pre&gt;&lt;br /&gt;
Getting ASP.Net version for this application depends on the version of IIS you are using. In version 7, the runtime version is set for the App Pool. In earlier versions, runtime version is set for individual applications.&lt;br /&gt;
&lt;br /&gt;
If you are using IIS 7, use the following method.&lt;br /&gt;
&lt;pre class=&quot;brush: csharp;&quot;&gt;private string GetAspNetVersion(DirectoryEntry entry)
{
   string appPool = s.Properties[&quot;AppPoolId&quot;].Value.ToString();
   string metabaseAppPoolPath = &quot;IIS://localhost/W3SVC/AppPools/&quot; + appPool;
   DirectoryEntry appPoolEntry = new DirectoryEntry(metabaseAppPoolPath);
   return appPoolEntry.Properties[&quot;ManagedRuntimeVersion&quot;].Value.ToString();
}&lt;/pre&gt;&lt;br /&gt;
The below method can be used for earlier versions.&lt;br /&gt;
&lt;pre class=&quot;brush: csharp;&quot;&gt;private string GetAspNetVersion(DirectoryEntry entry)
{
   PropertyValueCollection vals = entry.Properties[&quot;ScriptMaps&quot;];
   if (vals == null)
      return &quot;Could not read the frame work version&quot;;
   foreach (string val in vals)
   {
      if (val.StartsWith(&quot;.aspx&quot;))
      {
         int startIndex = val.ToLower().IndexOf(&quot;framework&quot;) + 10;
         int endIndex = val.IndexOf(&quot;\\&quot;, startIndex);
         string version = val.Substring(startIndex, endIndex - startIndex);
         return version;
      }
   }
   return &quot;No version for .aspx files.&quot;;
}&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharp-tipsandtricks.blogspot.com/feeds/3797429208343014558/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharp-tipsandtricks.blogspot.com/2009/12/getting-list-of-applications-in-site.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8000715364570585519/posts/default/3797429208343014558'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8000715364570585519/posts/default/3797429208343014558'/><link rel='alternate' type='text/html' href='http://csharp-tipsandtricks.blogspot.com/2009/12/getting-list-of-applications-in-site.html' title='Getting list of applications in a site from IIS metabase'/><author><name>Shaji PM</name><uri>http://www.blogger.com/profile/00372646697520630840</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRwC8OSkyqcFwvpE1bHxB2tKhSr5-NzQpRp2mxu6LlaFZHgEZgz6KtJcuHvNGLpoa_G0eL1dyBFiA--HnD6vNylFGFvonpscRhtAlvkcixkPMTWyQwJNa0DUG3cYryJg/s220/blog.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8000715364570585519.post-5918927420330739599</id><published>2009-12-30T22:02:00.000-08:00</published><updated>2010-01-03T19:45:48.195-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="IIS"/><title type='text'>Getting list of web sites from IIS metabase</title><content type='html'>Here we are going to see how we can get the list of web sites available using IIS metabase.&lt;br /&gt;
We will start with defining the types we are going to use. Class WebSite is used to hold information about a web site and enum ServerState specifies its state. The states are self explanatory.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp;&quot;&gt;public class WebSite
{
   private int _Id;
   public int Id
   {
      get { return _Id; }
      set { _Id = value; }
   }

   private string _Name;
   public string Name
   {
      get { return _Name; }
      set { _Name = value; }
   }

   private string _Description;
   public string Description
   {
      get { return _Description; }
      set { _Description = value; }
   }

   private string _ApplicationPool;
   public string ApplicationPool
   {
      get { return _ApplicationPool; }
      set { _ApplicationPool = value; }
   }

   private string _FolderPath;
   public string FolderPath
   {
      get { return _FolderPath; }
      set { _FolderPath = value; }
   }

   private ServerState _ServerState;
   public ServerState ServerState
   {
      get { return _ServerState; }
      set { _ServerState = value; }
   }
}

public enum ServerState
{
   Unknown = 0,
   Starting = 1,
   Started = 2,
   Stopping = 3,
   Stopped = 4,
   Pausing = 5,
   Paused = 6,
   Continuing = 7
}&lt;/pre&gt;&lt;br /&gt;
We can use System.DirectoryServices.DirectoryEntry for accessing IIS metabase. For getting the registered web sites, we need to iterate through the child nodes of &quot;IIS://localhost/W3SVC&quot;. A childer is identified as a web site if the SchemaClassName property is IIsWebServer. IIS assigns unique integer number to each websites which typically starts from 1. The Name property provides this value.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp;&quot;&gt;public List&amp;lt;WebSite&amp;gt; GetWebSites()
{
   string metabasePath = &quot;IIS://localhost/W3SVC&quot;;
   DirectoryEntry root = null;
   List&amp;lt;WebSite&amp;gt; webSites = new List&amp;lt;WebSite&amp;gt;();
   try
   {
      root = new DirectoryEntry(metabasePath);
      bool hasAppPools = HasApplicationPools();
      foreach (DirectoryEntry s in root.Children)
      {
         int siteId;
         if (s.SchemaClassName == &quot;IIsWebServer&quot; &amp;amp;&amp;amp; Int32.TryParse(s.Name, out siteId))
         {
            WebSite webSite = new WebSite();
            webSite.Id = siteId;
            webSite.Name = s.Properties[&quot;ServerComment&quot;].Value.ToString();
            webSite.Description = s.Properties[&quot;ServerComment&quot;].Value.ToString();
            webSite.FolderPath = GetFolderPath(s);
            webSite.ServerState = GetServerState(s.Properties[&quot;ServerState&quot;].Value.ToString());
            if (hasAppPools)
            {
               webSite.ApplicationPool = s.Properties[&quot;AppPoolId&quot;].Value.ToString();
            }
            webSites.Add(webSite);
         }
      }
   }
   catch { }
   finally
   {
      if (root != null)
         root.Close();
   }
   return webSites;
}

public bool IsValidMetabasePath(DirectoryEntry entry)
{
   try
   {
      if (entry != null &amp;amp;&amp;amp; !string.IsNullOrEmpty(entry.SchemaClassName))
         return true;
   }
   catch { }
   return false;
}

public bool HasApplicationPools()
{
   string metabaseAppPoolsPath = &quot;IIS://localhost/W3SVC/AppPools&quot;;
   DirectoryEntry appPoolsEntry = new DirectoryEntry(metabaseAppPoolsPath);
   return IsValidMetabasePath(appPoolsEntry);
}&lt;/pre&gt;&lt;br /&gt;
For getting the website root path, we need to read the Path property of its child named ROOT.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp;&quot;&gt;private string GetFolderPath(DirectoryEntry server)
{
   foreach (DirectoryEntry s in server.Children)
      if (s.Name.ToUpper() == &quot;ROOT&quot;)
         return s.Properties[&quot;Path&quot;].Value.ToString();
   return &quot;&quot;;
}

private ServerState GetServerState(string serverStatePropertyValue)
{
   switch (serverStatePropertyValue)
   {
      case &quot;1&quot;: return ServerState.Starting;
      case &quot;2&quot;: return ServerState.Started;
      case &quot;3&quot;: return ServerState.Stopping;
      case &quot;4&quot;: return ServerState.Stopped;
      case &quot;5&quot;: return ServerState.Pausing;
      case &quot;6&quot;: return ServerState.Paused;
      case &quot;7&quot;: return ServerState.Continuing;
   }
   return ServerState.Unknown;
}
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharp-tipsandtricks.blogspot.com/feeds/5918927420330739599/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharp-tipsandtricks.blogspot.com/2009/12/getting-list-of-web-sites-from-iis.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8000715364570585519/posts/default/5918927420330739599'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8000715364570585519/posts/default/5918927420330739599'/><link rel='alternate' type='text/html' href='http://csharp-tipsandtricks.blogspot.com/2009/12/getting-list-of-web-sites-from-iis.html' title='Getting list of web sites from IIS metabase'/><author><name>Shaji PM</name><uri>http://www.blogger.com/profile/00372646697520630840</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRwC8OSkyqcFwvpE1bHxB2tKhSr5-NzQpRp2mxu6LlaFZHgEZgz6KtJcuHvNGLpoa_G0eL1dyBFiA--HnD6vNylFGFvonpscRhtAlvkcixkPMTWyQwJNa0DUG3cYryJg/s220/blog.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8000715364570585519.post-2701086044485398749</id><published>2009-12-29T23:12:00.000-08:00</published><updated>2010-01-03T19:49:02.347-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>Loading assemblies from a shared location</title><content type='html'>Recently we had a restriction on deploying assemblies to GAC. Our application structure is quite complex where in my team owns the root website and the framework and lots of applications are configured as sub applications (or even multi level sub applications). It is impossible to release the assemblies to individual teams and coordinate. So for solving this issue we have decided to deploy the shared assemblies to a common location and load it dynamically from there.&lt;br /&gt;
&lt;br /&gt;
The approach we have taken is as follows.&lt;br /&gt;
Create an http module called SharedAssemblyLauncher. This assembly will be released to all teams and they have to define this module in their web.config.&lt;br /&gt;
The root web.config will define a key &quot;SharedAssemblyBaseDirectory&quot; to specify the base shared assembly location from where the probing starts. Each application web.config can override this too. For supporting multiple versions, you can create folders with the version number and then copy the assemblies to that folder. The probling rule is as follows&lt;br /&gt;
1. Look under the folder with version number.&lt;br /&gt;
2. Look under folder Common.&lt;br /&gt;
3. Base directory&lt;br /&gt;
&lt;br /&gt;
We start with creating a new handler for AssemblyResolve for current domain.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp;&quot;&gt;public class SharedAssemblyLauncher : IHttpModule
{
   private static string _BaseAssemblyFolder = &quot;&quot;;

   static SharedAssemblyLauncher()
   {
      if (HttpContext.Current != null)
      {
         string appRoot = HttpContext.Current.Server.MapPath(&quot;~/&quot;);
         string webRoot = HttpContext.Current.Server.MapPath(&quot;/&quot;);
         if (appRoot != webRoot)
            _BaseAssemblyFolder = GetSharedAssemblyBaseDirectoryFromConfigFile(GetSlashEndedFolder(appRoot) + &quot;web.config&quot;);
         if (_BaseAssemblyFolder.Trim() == &quot;&quot;)
            _BaseAssemblyFolder = GetSharedAssemblyBaseDirectoryFromConfigFile(GetSlashEndedFolder(webRoot) + &quot;web.config&quot;);
      }
      AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
   }

   public void Dispose()
   {
   }

   public void Init(HttpApplication context)
   {
   }
}
&lt;/pre&gt;&lt;br /&gt;
In assembly resolve handler, the first thing what we will do is loop through the loaded assemblies to look for a match. We&#39;ve noticed that, in case for a request for embedded resource the version number was not passed, only the assembly name is passed. So if we probe, we might not&amp;nbsp;find any matching&amp;nbsp;assembly. So it is very important to loop through and find a match before the actual probing starts.&amp;nbsp;If no match found on loaded assemblies, probe based on the sequence defined earlier. If no match found while probing, return null so that the framework does its own probing.&lt;br /&gt;
&lt;pre class=&quot;brush: csharp;&quot;&gt;static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
   Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
   foreach (Assembly assembly in loadedAssemblies)
   {
      if (assembly.FullName == args.Name || assembly.FullName.Contains(args.Name))
         return assembly;
   }

   if (_BaseAssemblyFolder.Trim() == &quot;&quot;)
      return null;

   string assemblyFileName = GetAssemblyFileName(args.Name);
   string assemblyVersion = GetAssemblyVersion(args.Name);
   try
   {
      string fileName = string.Format(&quot;{0}{1}\\{2}.dll&quot;, _BaseAssemblyFolder, assemblyVersion, assemblyFileName);
      if (File.Exists(fileName))
         return GetAssemblyFromPath(fileName);
      fileName = string.Format(&quot;{0}Common\\{1}.dll&quot;, _BaseAssemblyFolder, assemblyFileName);
      if (File.Exists(fileName))
         return GetAssemblyFromPath(fileName);
      fileName = string.Format(&quot;{0}{1}.dll&quot;, _BaseAssemblyFolder, assemblyFileName);
      if (File.Exists(fileName))
         return GetAssemblyFromPath(fileName);
   }
   catch { }
   return null;
}

private static string GetSlashEndedFolder(string baseFolder)
{
   return (baseFolder.Trim().EndsWith(&quot;\\&quot;) ? baseFolder.Trim() : baseFolder.Trim() + &quot;\\&quot;);
}

private static string GetSharedAssemblyBaseDirectoryFromConfigFile(string configPath)
{
   XmlDocument configXmlDoc = new XmlDocument();
   if (!File.Exists(configPath))
      return &quot;&quot;;
   configXmlDoc.Load(configPath);
   XmlNode baseDirectoryNode = configXmlDoc.SelectSingleNode(&quot;/configuration/appSettings/add[@key=\&quot;SharedAssemblyBaseDirectory\&quot;]&quot;);
   if (baseDirectoryNode == null)
      return &quot;&quot;;
   return baseDirectoryNode.Attributes[&quot;value&quot;].Value;
}

private static string GetAssemblyFileName(string assemblyName)
{
   return assemblyName.Split(&quot;,&quot;.ToCharArray())[0];
}

private static string GetAssemblyVersion(string assemblyName)
{
   string[] parts = assemblyName.Split(&quot;,&quot;.ToCharArray());
   for (int i = 0; i &amp;lt; parts.Length; i++)
   {
      if (parts[i].Trim().StartsWith(&quot;Version=&quot;))
      {
         string[] versionParts = parts[i].Split(&quot;=&quot;.ToCharArray());
         return versionParts[1].Trim();
      }
   }
   return &quot;&quot;;
}

private static Assembly GetAssemblyFromPath(string assemblyPath)
{
   return Assembly.LoadFile(assemblyPath);
}
&lt;/pre&gt;&lt;br /&gt;
One important thing to remeber here is that never try to read configuration values using ConfigurationManager in this module.&lt;br /&gt;
&lt;br /&gt;
Happy sharing!!!</content><link rel='replies' type='application/atom+xml' href='http://csharp-tipsandtricks.blogspot.com/feeds/2701086044485398749/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharp-tipsandtricks.blogspot.com/2009/12/loading-assemblies-from-shared-location.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8000715364570585519/posts/default/2701086044485398749'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8000715364570585519/posts/default/2701086044485398749'/><link rel='alternate' type='text/html' href='http://csharp-tipsandtricks.blogspot.com/2009/12/loading-assemblies-from-shared-location.html' title='Loading assemblies from a shared location'/><author><name>Shaji PM</name><uri>http://www.blogger.com/profile/00372646697520630840</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRwC8OSkyqcFwvpE1bHxB2tKhSr5-NzQpRp2mxu6LlaFZHgEZgz6KtJcuHvNGLpoa_G0eL1dyBFiA--HnD6vNylFGFvonpscRhtAlvkcixkPMTWyQwJNa0DUG3cYryJg/s220/blog.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8000715364570585519.post-3773190739991736958</id><published>2009-12-28T23:29:00.000-08:00</published><updated>2010-01-03T19:51:02.173-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript"/><title type='text'>Use POST instead of GET</title><content type='html'>Why do we use POST instead of GET?&lt;br /&gt;
GET shows lots of ugly names and values in url. Most browsers have some restrictions on the size of url string. The above 2 points make POST a better choice over GET.&lt;br /&gt;
&lt;br /&gt;
We will quickly see, how can we convert our existing GETs to POSTs.&lt;br /&gt;
&lt;br /&gt;
When a new page is to be called we will create a form dynamically, create hidden fields for all the values to be passed and submit it. The following script can help you in achieving this.&lt;br /&gt;
Assume that valuesToPost is a javascript array of objects which has fields Name and Value.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: js;&quot;&gt;function PostIt(valuesToPost, targetUrl)
{
   var form = document.createElement(&quot;form&quot;);
   form.setAttribute(&quot;method&quot;, &quot;post&quot;);
   form.setAttribute(&quot;action&quot;, targetUrl);
   for (var i=0; i&amp;lt;valuesToPost.length; i++)
   {
      var hiddenField = document.createElement(&quot;input&quot;);
      hiddenField.setAttribute(&quot;type&quot;, &quot;hidden&quot;);
      hiddenField.setAttribute(&quot;name&quot;, valuesToPost[i].Name);
      hiddenField.setAttribute(&quot;value&quot;, valuesToPost[i].Value);
      form.appendChild(hiddenField);
   }
   document.body.appendChild(form);
   form.submit();
}&lt;/pre&gt;&lt;br /&gt;
We can read these passed values from the page as follows. These dynamically posted values will be available only when IsPostback is false.&lt;br /&gt;
So on page_load, the following code can read these posted values.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp;&quot;&gt;if(!IsPostback)
{
   string id = GetPostedValue(&quot;Id&quot;);
   Dictionary&amp;lt;string, string&amp;gt; postedValues = GetPostedValues();
}

public string GetPostedValue(string key)
{
   return Request.Form[key];
}

public Dictionary&amp;lt;string, string&amp;gt; GetPostedValues()
{
   Dictionary&amp;lt;string, string&amp;gt; postedVals = new Dictionary&amp;lt;string, string&amp;gt;();
   foreach (string key in Request.Form.AllKeys)
      postedVals.Add(key, Request.Form[key]);
   return postedVals;
}&lt;/pre&gt;&lt;br /&gt;
Now bye bye to ugly URLs.&lt;br /&gt;
Happy POSTing!!!</content><link rel='replies' type='application/atom+xml' href='http://csharp-tipsandtricks.blogspot.com/feeds/3773190739991736958/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharp-tipsandtricks.blogspot.com/2009/12/use-post-instead-of-get.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8000715364570585519/posts/default/3773190739991736958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8000715364570585519/posts/default/3773190739991736958'/><link rel='alternate' type='text/html' href='http://csharp-tipsandtricks.blogspot.com/2009/12/use-post-instead-of-get.html' title='Use POST instead of GET'/><author><name>Shaji PM</name><uri>http://www.blogger.com/profile/00372646697520630840</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRwC8OSkyqcFwvpE1bHxB2tKhSr5-NzQpRp2mxu6LlaFZHgEZgz6KtJcuHvNGLpoa_G0eL1dyBFiA--HnD6vNylFGFvonpscRhtAlvkcixkPMTWyQwJNa0DUG3cYryJg/s220/blog.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8000715364570585519.post-8314399532382367405</id><published>2009-12-28T21:26:00.000-08:00</published><updated>2010-01-03T19:52:51.440-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>Secure values stored in hidden fields</title><content type='html'>It is a common practice to store values in hidden fields when items are edited. Value like id are a common candidate for these operations.&amp;nbsp;Most times modifying these values from client side by script can be dangerous. Here we will look for a solution where in the complete set of values which we have to store and avail on postbacks be saved in a secure way.&lt;br /&gt;
&lt;br /&gt;
The suggested solution is as follows.&lt;br /&gt;
&lt;br /&gt;
First we will define a dictionary which can hold string key value pairs. We will also provide methods for storing and retrieving these values.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp;&quot;&gt;private string _KeyStoreName = &quot;__KeyValueStore__&quot;;
private Dictionary&amp;lt;string, string&amp;gt; _KeyValues = new Dictionary&amp;lt;string, string&amp;gt;();
public void SetKeyValue(string name, string value)
{
   if (_KeyValues.ContainsKey(name))
    _KeyValues[name] = value;
   else
    _KeyValues.Add(name, value);
}
public string GetValue(string name)
{
   if (_KeyValues.ContainsKey(name))
    return _KeyValues[name];
   return &quot;&quot;;
}

public Dictionary&amp;lt;string, string&amp;gt; GetKeyValues()
{
   Dictionary&amp;lt;string, string&amp;gt; keyVals = new Dictionary&amp;lt;string, string&amp;gt;();
   foreach (string key in _KeyValues.Keys)
    keyVals.Add(key, _KeyValues[key]);
   return keyVals;
}&lt;/pre&gt;&lt;br /&gt;
On pre-render, we will serialize the dictionary and encrypt it. This value will be stored in a hidden field which will be generated dynamically.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp;&quot;&gt;protected override void OnPreRender(EventArgs e)
{
   StringWriter sw = new StringWriter();
   los.Serialize(sw, _KeyValues);
   string valueToStore = sw.GetStringBuilder().ToString();
   // Encrypt valueToStore to make it secured.
   HtmlInputHidden hid = new HtmlInputHidden();
   hid.ID = _KeyStoreName;
   hid.Name = _KeyStoreName;
   hid.Value = valueToStore;
   Page.Form.Controls.Add(hid);
   base.OnPreRender(e);
}&lt;/pre&gt;&lt;br /&gt;
On pre-init, we will retrieve the hidden field value, decrypt it and deserialize it.&lt;br /&gt;
&lt;pre class=&quot;brush: csharp;&quot;&gt;protected override void OnPreInit(EventArgs e)
{
   string storedValue = Request.Form[_KeyStoreName];
   if (!string.IsNullOrEmpty(storedValue))
   {
    // Decrypt storedValue, if you have encrypted it.
    LosFormatter los = new LosFormatter();
    _KeyValues = los.Deserialize(storedValue) as Dictionary&amp;lt;string, string&amp;gt;;
   }
   base.OnPreInit(e);
}&lt;/pre&gt;&lt;br /&gt;
Happy coding!!!</content><link rel='replies' type='application/atom+xml' href='http://csharp-tipsandtricks.blogspot.com/feeds/8314399532382367405/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharp-tipsandtricks.blogspot.com/2009/12/secure-values-stored-in-hidden-fields.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8000715364570585519/posts/default/8314399532382367405'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8000715364570585519/posts/default/8314399532382367405'/><link rel='alternate' type='text/html' href='http://csharp-tipsandtricks.blogspot.com/2009/12/secure-values-stored-in-hidden-fields.html' title='Secure values stored in hidden fields'/><author><name>Shaji PM</name><uri>http://www.blogger.com/profile/00372646697520630840</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRwC8OSkyqcFwvpE1bHxB2tKhSr5-NzQpRp2mxu6LlaFZHgEZgz6KtJcuHvNGLpoa_G0eL1dyBFiA--HnD6vNylFGFvonpscRhtAlvkcixkPMTWyQwJNa0DUG3cYryJg/s220/blog.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8000715364570585519.post-4535882707906687175</id><published>2009-12-28T18:49:00.000-08:00</published><updated>2010-01-03T19:55:27.821-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>Secure your cookies</title><content type='html'>Recently our IT Risk team suggested us to hide our cookies as part of making our site more secure. One of their main concerns were that all cookie names suggest exactly what data is stored. So we came up with the following solution.&lt;br /&gt;
&lt;br /&gt;
First abstract the cookies to a new class called WebCookie.&lt;br /&gt;
Based on our requirement we only need to make sure that the cookies expire after a specified number of seconds.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp;&quot;&gt;[Serializable]
public class WebCookie
{
   private string _Name = &quot;&quot;;
   public string Name
   {
    get { return _Name; }
    set { _Name = value; }
   }
   private string _Value = &quot;&quot;;
   public string Value
   {
    get { return _Value; }
    set { _Value = value; }
   }
   private int _ExpiresInSeconds = 1200;
   public int ExpiresInSeconds
   {
    get { return _ExpiresInSeconds; }
    set { _ExpiresInSeconds = value; }
   }
   public WebCookie() { }
   public WebCookie(string name, string value)
   {
    _Name = name;
    _Value = value;
   }
   public WebCookie(string name, string value, int expiresInSeconds)
   {
    _Name = name;
    _Value = value;
    _ExpiresInSeconds = expiresInSeconds;
   }
}&lt;/pre&gt;&lt;br /&gt;
Use the base web page to store these cookies as a dictionary. Also expose some methods to add/read cookies.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp;&quot;&gt;private Dictionary&amp;lt;string, WebCookie&amp;gt _WebCookies = new Dictionary&amp;lt;string, WebCookie&amp;gt;();

public void SetCookie(string name, string value)
{
   string keyName = name.ToUpper();
   if (_WebCookies.ContainsKey(keyName))
    _WebCookies[keyName].Value = value;
   else
    _WebCookies.Add(keyName, new WebCookie(name, value));
}

public WebCookie GetCookie(string name)
{
   string keyName = name.ToUpper();
   if (_WebCookies.ContainsKey(keyName))
    return _WebCookies[keyName];
   return null;
}&lt;/pre&gt;&lt;br /&gt;
On pre render, serialize the dictionary, then encrypt and send it as cookie. Also make sure to add the Cookie generated time to the dictionary before serializing. We can use this time stamp later to findout which cookie items have timed out.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp;&quot;&gt;private string _CookieName = &quot;__CookieStore__&quot;;
private string _LastPostTimeCookieKeyName = &quot;LastPostTime&quot;;
protected override void OnPreRender(EventArgs e)
{
   _WebCookies.Add(_LastPostTimeCookieKeyName, new WebCookie(_LastPostTimeCookieKeyName, DateTime.Now.Ticks.ToString()));
   LosFormatter los = new LosFormatter();
   StringWriter sw = new StringWriter();
   los.Serialize(sw, _WebCookies);
   string cookieValueToStore = sw.GetStringBuilder().ToString();
   // Encrypt cookieValueToStore to make it more secure.
   HttpCookie cookie = new HttpCookie(_CookieName, cookieValueToStore);
   Response.Cookies.Add(cookie);
   base.OnPreRender(e);
}&lt;/pre&gt;&lt;br /&gt;
On pre init, read the cookie and populate the dictionary. Also check the last post time to findout which items have really timed out.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp;&quot;&gt;protected override void OnPreInit(EventArgs e)
{
   if (Request.Cookies[_CookieName] != null &amp;amp;&amp;amp; !string.IsNullOrEmpty(Request.Cookies[_CookieName].Value))
   {
    string cookieValue = Request.Cookies[_CookieName].Value;
    // Decrypt it, if you&#39;ve encrypted it.
    LosFormatter los = new LosFormatter();
    _WebCookies = los.Deserialize(cookieValue) as Dictionary&amp;lt;string, WebCookie&amp;gt;;
    if (_WebCookies.ContainsKey(_LastPostTimeCookieKeyName))
    {
       _LastPostTime = new DateTime(long.Parse(_WebCookies[_LastPostTimeCookieKeyName].Value));
       _WebCookies.Remove(_LastPostTimeCookieKeyName);
    }
    // Remove all items which are expired.
   }
   base.OnPreInit(e);
}&lt;/pre&gt;&lt;br /&gt;
Now you have secured your cookies.&lt;br /&gt;
Enjoy!!!</content><link rel='replies' type='application/atom+xml' href='http://csharp-tipsandtricks.blogspot.com/feeds/4535882707906687175/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharp-tipsandtricks.blogspot.com/2009/12/secure-your-cookies.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8000715364570585519/posts/default/4535882707906687175'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8000715364570585519/posts/default/4535882707906687175'/><link rel='alternate' type='text/html' href='http://csharp-tipsandtricks.blogspot.com/2009/12/secure-your-cookies.html' title='Secure your cookies'/><author><name>Shaji PM</name><uri>http://www.blogger.com/profile/00372646697520630840</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRwC8OSkyqcFwvpE1bHxB2tKhSr5-NzQpRp2mxu6LlaFZHgEZgz6KtJcuHvNGLpoa_G0eL1dyBFiA--HnD6vNylFGFvonpscRhtAlvkcixkPMTWyQwJNa0DUG3cYryJg/s220/blog.jpg'/></author><thr:total>0</thr:total></entry></feed>