2010
12.02

Gosh, I feel like an idiot. For the whole day I was trying to get my Ext.NET + ASP.NET MVC project to handle cookie, finally I manage to get it done. Then I found out a very simple method which only need a few lines of JavaScript.

The Beginning

I have this login form created with Ext.NET.
rojo.login
The behavior that I want is that whenever the checkbox is checked, a cookie will be set to remember the username.

The first thing that came to my mind was, “Oh right, let the MVC controller handles it, I remember HttpRequest/HttpResponse has access to cookie”. So I came out with the following code:

ControllersAccountController.cs


public ActionResult Login()
{
	var c = Request.Cookies["chkRememberMe"];
	this.ViewData["chkRememberMe"] = c != null ? "true" : "false";
	c = Request.Cookies["txtUsername"];
	this.ViewData["txtUsername"] = c != null ? c.Value : "";
	return View();
} 

[HttpPost]
public ActionResult Login(string txtUsername, string txtPassword, string ReturnUrl, string chkRememberMe)
{
	if (!String.IsNullOrEmpty(chkRememberMe)) {
		Response.Cookies.Add(new HttpCookie("chkRememberMe", "true"));
		Response.Cookies.Add(new HttpCookie("txtUsername", txtUsername));
	}
	else {
		Response.Cookies["chkRememberMe"].Value="false";
		Response.Cookies["txtUsername"].Value = "";
	}
	
	// --- snip --
}        

On the View portion, I amended it as follows:

ViewsAccountLogin.aspx

<ext:FormPanel runat="server" FormID="form1" 
	Url='<%# Html.AttributeEncode(Url.Action("Login")) %>'
	Border="false" Layout="form" BodyBorder="false"
	BodyStyle="background:transparent;">
	<Items>
		<ext:Container ID="Container1" Layout="column" 
			runat="server" Height="25" AnchorHorizontal="100%">
			<Items>
				<ext:TextField ID="txtUsername" runat="server" 
					FieldLabel="Username" AllowBlank="false"
					Text='<%# this.ViewData["txtUsername"] %>'
					BlankText="Username is required."  Width="225" />
				<ext:BoxComponent Width="10" runat="server" />    
				<ext:Checkbox ID="chkRememberMe" 
					Checked='<%# this.ViewData["chkRememberMe"] %>'
					runat="server" />
				<ext:Label runat="server" FieldLabel="Remember Me" 
					LabelSeparator=" " />
			</Items>
		</ext:Container>
		<ext:TextField ID="txtPassword" runat="server" 
			InputType="Password" FieldLabel="Password"
			AllowBlank="false" BlankText="Password is required." 
			AnchorHorizontal="100%" />
	</Items>
</ext:FormPanel>

If you think this will work, you’ll be disappointed. Just like I did. Even after checking that both cookies are set, and properly fed to Login’s ViewData, the Login’s View page doesn’t seem to bother to read its ViewData.

So I came out with another strategy. I will save the ViewData to a hidden input, and use Ext.NET’s DocumentReady event to populate it.

<input type="hidden" id="vwchkRememberMe" value="<%=this.ViewData["chkRememberMe"] %>" />
<input type="hidden" id="vwtxtUsername" value='<%=this.ViewData["txtUsername"] %>' />

<ext:ResourceManager runat="server">
	<Listeners>
		<DocumentReady Handler=" 
			#{chkRememberMe}.setValue(Ext.get('vwchkRememberMe').getValue()); 
			#{txtUsername}.setValue(Ext.get('vwtxtUsername').getValue()); 
		" />
	</Listeners>
</ext:ResourceManager>

It works and I was a happy man.

How it ended

I was reading the Ext.JS documentation when I saw this:
extjs.cookies
Oh Gawd… I can easily set/read cookies using Ext.JS built in methods!!!
The final changes

<!-- snip --->

<ext:ResourceManager runat="server">
	<Listeners>
		<DocumentReady Handler=" 
			#{chkRememberMe}.setValue(Ext.util.Cookies.get('vwchkRememberMe')); 
			#{txtUsername}.setValue(Ext.util.Cookies.get('vwtxtUsername')); 
		" />
	</Listeners>
</ext:ResourceManager>

<!-- snip --->

<ext:Button runat="server" Text="Login" Icon="Accept">
	<DirectEvents>
		<Click Url="/Account/Login" 
			Timeout="60000" FormID="form1" 
			CleanRequest="true" Method="POST"
			Before="
				Ext.Msg.wait('Verifying...', 'Authentication');
				Ext.util.Cookies.set('vwchkRememberMe', #{chkRememberMe}.getValue());
				Ext.util.Cookies.set('vwtxtUsername', #{txtUsername}.getValue());
			" 
			Failure="Ext.Msg.show({
			   title:   'Login Error',
			   msg:     result.errorMessage,
			   buttons: Ext.Msg.OK,
			   icon:    Ext.MessageBox.ERROR
			});">
			<EventMask MinDelay="250" />
			<ExtraParams>
				<ext:Parameter Name="ReturnUrl" 
					Value="Ext.urlDecode(String(document.location).split('?')[1]).r || '/'"
					Mode="Raw" />
			</ExtraParams>
		</Click>
	</DirectEvents>
</ext:Button>

<!-- snip --->
GD Star Rating
loading...
ASP.NET MVC, Ext.NET, The Cookie Conundrum, 4.0 out of 5 based on 1 rating

Incoming Search Term

ext net mvc

Advertise Here

1 comment so far

Add Your Comment
  1. I found out that to enable the Ext.NET to use the ViewData, I must set the property AutoDataBind=”true”