Friday, June 19, 2009

ASP.Net - Single Sign On

Task : As soon as user logs into the website, he remains logged in even if he move across sub domains.

eg. if user logged in to the website using www.domain.com, now via a link, he moves to subdomain.domain.com then he should not be required to re login.

Solution :

In order to achieve this, you need to take two actions,

1. Make the following changes in web.config :

Within System.web element, add the following,

<authentication mode="Forms">
<forms path="/" name=".cookieName" cookieless="UseCookies" domain=".domainname.com"/>

</authentication>

If your site's domain address is "www.sitename.com" then domain will be set as ".sitename.com"

2. Add the following code piece to the code which runs on logout,

HttpCookie cookie = Request.Cookies[FormsAuthentication.FormsCookieName];

if (cookie != null)

{

cookie.Domain = FormsAuthentication.CookieDomain;

cookie.Expires = DateTime.Now.AddDays(-360);

Response.Cookies.Add(cookie);

}

FormsAuthentication.SignOut();

If you use a single domain then it's not required that you explicitly expire the authentication cookie, a simple ForsmAuthentication.SignOut() should work fine, but once the cookie domain is set then you will need to expire the cookie explicitly, otherwise your user will remain logged in.

Once you have done both the actions, your job is done and your user's login should work for the main domain and all the sub domains.

Next Problem >> Though this solution will keep the user logged in but every time when he will move to a new sub domain, his session will renew, any information which you placed into the session at the time of logging in will be lost too. The informatino can be refilled but more than that it's a performance issue.

Let's discuss this in Part 2.

Monday, June 15, 2009

ASP.Net - Calculate label width dynamically using the text

Sometimes, we have to calculate a label's width dynamically , depending on the provided text. In order to do that, use the following,

float width = Graphics.FromImage(new Bitmap(1, 1)).MeasureString("Hello world!", new Font("Verdana", 14)).Width

You will have to mention the font family and the desired size.

ASP.Net Menu Control - Rounded Corners

So it's a little hard to play with ASP.Net's menu and there is no simple way to have tab with rounded corners unless you decide to do something with the render method of menu control, which is time consuming. And it doesn't help that menu item class is sealed and you can't do anything to it.

So here is this simple hack which will make the selected item's corner as image based, but with this simple trick, you can do alot of other creative things.

The whole idea is to set the selected item's text and you can specify any type of HTML using this!

Handle the menu's databound event and add the following code, as a side note, the HTML used here is not good and is not the suggested way of doing it, go for div based HTML with everything handled via CSS

protected void mainMenu_DataBound(object sender, EventArgs e)
{

if (!Page.IsPostBack)

if (mainMenu.SelectedItem != null)
{
MenuItem selectedItem = mainMenu.SelectedItem;

if (mainMenu.SelectedItem.Parent != null) //assuming two level menu
selectedItem = mainMenu.SelectedItem.Parent;

if (selectedItem != null)
{
string imgBg = "images/menubg.jpg";
string imgLeft = "images/menuleft.jpg";
string imgRight = "images/menuright.jpg";

_width = 240; //You may want to calculate it dynamically

selectedItem.Text = String.Format
(@"<table width='{5}' border='0' cellspacing='0' cellpadding='0'>
<tr>
<td width='6px' valign='top' background=''><img src='{1}' width='6' height='41' style='border:0px;' /></td>
<td width='{4}px' align='center' background='{2}' class='links'><div align='center'><strong>{0}</strong></div></td>
<td width='11px' valign='top'><img src='{3}' width='11' height='41' style='border:0px;' /></td>
</tr>
</table>", selectedItem.Text, imgLeft, imgBg, imgRight, _width, _width + 20);

}
}
}

Not the best solution out there, but it's definitely quick and dirty.

Update : As one of my friends just mentioned to me, apart from tables/div, you can also use JQuery to get rounded corners (which is actually the preferred approach these days,) but the approach of getting the rounded corner could be anything you want, using the selectedItem.Text property will allow you to set the Item's HTML according to your desire as you can't inherit MenuItem control and overwrite it's Render method.

Latest Move : Dot Net 2.0 to Dot Net 3.5

So we moved one of our products from Dot Net 2.0 to Dot Net 3.5. Our move planning was simple,

1. Study the breaking changes list and see if anything is critical to our application - apparently nothing was.

2. Make a copy of application and export it to VS 2008 - This worked fine too

3. Provide a copy to QA for testing and see that how it works.

And with some minor issues, everything turned out to be quite fine. Here let me tell you a few more things ,

1. If you have installed 3.5 on your machine and then went to IIS >> ASP.Net tab, and surprisingly version 3.5 was not there, then don't be surprised. Version 3.5 actually uses 2.0 engine, there is no change with regards to IIS, so leave the version at 2.0.

2. You'll need to change the compilation version to 3.5, for that you just need to add the following to your web.config

<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<provideroption name="CompilerVersion" value="v3.5">
</provideroption>
</compiler>
</compilers>
</system.codedom >

And your job is done!