browse by category or date

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 --->

About Hardono

Howdy! I'm Hardono. I am working as a Software Developer. I am working mostly in Windows, dealing with .NET, conversing in C#. But I know a bit of Linux, mainly because I need to keep this blog operational. I've been working in Logistics/Transport industry for more than 11 years.

Possibly relevant:

As we all know, HTTP is not secure. It is easy for evil people to listen the HTTP conversation between client and server. If our application is using AJAX to send/retrieve data from server, we are at a high risk.

No other methods can prevent the Man-In-The-Middle attack, except HTTPS protocol.

To do so, we need to ensure that people is using HTTPS protocol instead of HTTP.

I will share with you the solution that I did to make the Web Application automatically redirect to the HTTPS protocol.

First Step: Create App_Code folder in your ASP.NET web root
Second Step: Create the redirect class

RedirectHttpModule.cs

using System;
using System.Web;

namespace myMVCProject.App_Code
{
    public class RedirectHttpModule: IHttpModule
    {
        public RedirectHttpModule()
        { }

        public String ModuleName
        {
            get { return "RedirectHttpModule"; }
        }

        public void Init(HttpApplication app)
        {
            app.BeginRequest += (new EventHandler(this.BeginRequest));
        }
        public void BeginRequest(Object source, EventArgs e)
        {
            HttpApplication app = (HttpApplication)source;
            HttpContext ctx = app.Context;
            if (ctx.Request.Url.OriginalString.ToLower().StartsWith("http://"))
            {
                
                 ctx.Response.Redirect("https://" + ctx.Request.Url.Host + ctx.Request.Url.LocalPath +  ctx.Request.Url.Query);
            }
        }
        public void Dispose()
        {
        }
    }
}

Third Step: Modify your web.config

...
      
        ...
               
        ...

...

I hope it helps 😉

About Hardono

Howdy! I'm Hardono. I am working as a Software Developer. I am working mostly in Windows, dealing with .NET, conversing in C#. But I know a bit of Linux, mainly because I need to keep this blog operational. I've been working in Logistics/Transport industry for more than 11 years.

Possibly relevant:

extjsIn the past, I have built a Web Application using ASP.NET and Ext JS (now called Sencha) technology for company’s internal use. It has been ported to production and working well since.

But today I was astonished that a colleague phoned me telling that the application is not working. Luckily she is stationed in the same floor as me. So I hurried up visiting her PC.

What I saw in her PC was plain screen. I quickly enable Firebug, and saw the error messages accumulating in the Console Tab.

extjs.iwss.1

I clicked the error message, it brought me to the source code of ext-all.js
extjs.iwss.2

Sigh.. This is not the first time I affected by IWSS.

Hmm.. IWSS? This application is located in a server within the company’s intranet. It should not have used any proxy at all. Apparently the proxy exclusion was not properly set.
extjs.iwss.3
Once we have included the web application server IP address into proxy exclusion, the web application back to normal.

About Hardono

Howdy! I'm Hardono. I am working as a Software Developer. I am working mostly in Windows, dealing with .NET, conversing in C#. But I know a bit of Linux, mainly because I need to keep this blog operational. I've been working in Logistics/Transport industry for more than 11 years.

Possibly relevant: