One of the major hurdles when you switch over from ASP.NET web forms to ASP.NET MVC is deciding how to handle your submission forms. You no longer have all of the input controls and the nice validation controls, so you may be a little lost as to how to proceed. Doing server-side validation isn't enough anymore in the ajax world we live in. Writing custom javascript code to handle all of the validation would be a huge undertaking. Luckily, Dojo comes to the rescue with its Dijit.Form widgets. Below is what a login form would look like using dojo:


 
<div dojoType="dijit.form.Form" jsId="loginForm" 
            encType="multipart/form-data" action="" method="">
            <script type="dojo/method" event="onSubmit">
                if (this.validate()) {
                    SubmitLoginForm(loginForm.getValues());
                }
                return false;
            </script>
 
            <table cellspacing="0">
                <tr>
                    <td class="label">Username:</td>
                    <td class="input mediumfield">
                        <input id="tbUsername" name="tbUsername" type="text" size="20"
                            dojoType="dijit.form.ValidationTextBox"
                            required="true"
                            promptMessage="Enter Username."
                            invalidMessage="Username is required." />
                    </td>
                </tr>
                <tr>
                    <td class="label">Password:</td>
                    <td class="input mediumfield">
                        <input id="tbPassword" name="tbPassword" type="password" size="20"
                            dojoType="dijit.form.ValidationTextBox"
                            required="true"
                            promptMessage="Enter Password."
                            invalidMessage="Password is required." />
                    </td>
                </tr>
            </table>
 
            <table id="buttons" class="buttons" cellspacing="0">
                <tr>
                    <td class="center">
                        <button dojoType="dijit.form.Button" type="submit" value="Submit">Login</button>
                    </td>
                </tr>
            </table>
 
        </div>
 

 

As you can see, you create a dijit.form.Form widget, which will act as our <form> element normally would. When the login button is clicked, it'll validate all of the controls within the form and then call a javascript method called SubmitLoginForm. You'll notice that my dojo method for onSubmit returns false. Normally you would have it return false if the form was invalid and true otherwise, but this would actually submit the form and do a server-side postback. Seeming that we're using purely ajax to make our calls in this example, we're returning false regardless of if the form is valid or not so that it won't postback to the server.

Next we need to write our javascript to submit the login form using ajax:


    dojo.require("dojo.parser");
    dojo.require("dijit.form.Form");
    dojo.require("dijit.form.ValidationTextBox");
    dojo.require("dijit.form.Button");
    dojo.addOnLoad(SetFocus);
    function SetFocus() {
        //find controls.
        var tbUsername = dojo.byId("tbUsername");
        //set focus.
        tbUsername.focus();
    }
    function SubmitLoginForm(fields) {
        //ajax call.
        var request = { "userName": fields.tbUsername, "password": fields.tbPassword };
        Post("login/validate/", request, FormResult);
    }
    function FormResult(result) {
        if (result.indexOf("Error") > -1) {
            //TODO: show error.
        }
        else {
            //redirect.
            window.location = result;
        }
    }
 

 

The cool part is that when you call loginForm.getValues(), it returns an object containing the values of all of the form fields. Within the SubmitLoginForm method we're able to easily create an ajax request and post it back to the server. Above I omitted the function declaration for Post, so below I'm showing what mine looks like. It can be a lot simpler if you only want to make one ajax call, but my example below will try up to 5 times to make the ajax call, in case there are some sort of flukey issues that cause your ajax requests to fail every now and then:

 


 
var maxAjaxCalls = 5;
var currentAjaxCalls = new Array();
 
function Post(path, request, callbackFunction) {
    //increment current ajax calls.
    currentAjaxCalls[currentAjaxCalls.length] = path;
    //make sure hasn't gone over max ajax calls.
    var numAjaxCall = NumAjaxCalls(path);
    if (numAjaxCall <= maxAjaxCalls) {
        if (numAjaxCall > 1) {
            console.debug("Invoking " + path + " ajax call for try #" + numAjaxCall);
        }
        dojo.xhrPost({
            url: baseUrl + path,
            handleAs: 'json',
            timeout: 60000,
            content: request,
            contentType: "application/x-www-form-urlencoded",
            load: function(result) { PostSuccess(result, path, callbackFunction); },
            error: function(error, args) { AjaxError(error, args, path, request, callbackFunction); }
        });
    }
    else {
        console.debug("Tried to make " + path + " ajax call " + maxAjaxCalls + " times but failed!");
    }
}
 
function NumAjaxCalls(path) {
    var numAjaxCalls = 0;
    for (var k = 0; k < currentAjaxCalls.length; k++) {
        if (currentAjaxCalls[k] == path) {
            numAjaxCalls++;
        }
    }
    return numAjaxCalls;
}
 
function PostSuccess(result, path, callbackFunction) {
    //remove path from array.
    for (var k = 0; k < currentAjaxCalls.length; k++) {
        if (currentAjaxCalls[k] == path) {
            currentAjaxCalls.splice(k, 1);
            k--;
        }
    }
    //invoke callback function.
    callbackFunction(result);
}
 
function AjaxError(error, args, path, request, callbackFunction) {
    //show error message.
    //console.debug("ajax error: " + error.message + " " + error.responseText);
    //console.debug(error);
    //try ajax call again in 1 second.
    window.setTimeout(function() { Post(path, request, callbackFunction); }, 1000);
}
 

 

The last step would be to create your LoginController and create a method called Validate:

 

//GET: /Login/Validate/

        public ActionResult Validate(string userName, string password, string returnUrl)

        {

            string result = String.Empty;

            try

            {

                if(IsAuthenticated)//TODO: check if they're authenticated.

                    result = "someurltoredirectto";

                }

                else

                {

                    result = "Error: Authentication failed, check your Username and Password.";

                }

            }

            catch (Exception ex)

            {

                result = "Error: " + ex.Message;

            }

            return Json(result);

        }

 

 

Pretty simple stuff. In this way you're able to save yourself from having to write a lot of code, letting dojo do the majority of the heavy lifting. If you were to use this example, you'd obviously want to make sure you took care of server-side validation as well, in case someone disabled javascript.