Sponsored By Aspose - File Format APIs for .NET

Aspose are the market leader of .NET APIs for file business formats – natively work with DOCX, XLSX, PPT, PDF, MSG, MPP, images formats and many more!

Why choose between Ajax or MVC ? Together they KISS so sweet…

Technology comes in waves. Over the years we have been drowned by several waves of web development technologies from MS. ASP, ASP.NET, ASP.NET Ajax and now there is ASP.MVC. A new wave does bring nice new things but also has the tendency to wash away the things brought by the one before. Also for the users of the software we create. Thanks to partial postbacks ASP.NET Ajax brought the user a far more pleasant view in the browser. Not every click resulted in a full screen refresh with its disturbing flickering. And the possibilities of javascript gave more room for screen candy. ASP.MVC, the next wave, still does care a lot about the possibilities of script but partial rendering has moved somewhat to the background of attention. Most MVC documentation and examples describe a full rebuild of the page. Bringing the user back to the well known restless browser screens.

But ASP.MVC is full of Ajax possibilities. It is even easier to build ajax style apps than in ASP.NET ajax. In this post I will first present the basics and give some hints to create a popup screen. Not one in a new window but one which can easily communicate with the document which created it.

Partial views

In MVC the basics for a partial screen update are present  in the form of partial views. They are regular ascx usercontrols.

AkM1

Inside straightforward MVC scaffolded markup, including the possibility to use a strong typed model

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MyModel>" %>

<%@ Import Namespace="AjaxKissesMVC.Models"%>

<% =Model.MyProperty %>

<%

    foreach (var item in Model.MyList)

    { %>

        <%

        =Ajax.ActionLink(item, "Partial", new {routeValue = item}, new AjaxOptions {}) %>

        &nbsp;

        <%

    } %>

 

More on the ActionLink later on. This is My Model

public class MyModel

{

    public MyModel()

    {

        MyProperty = "This is my model";

    }

 

    private readonly List<string> myList = new List<string>() {"One", "Two", "Three"};

    public string MyProperty { get; private set; }

    public IEnumerable<string> MyList

    {

        get

        {

            return myList;

        }

    }

}

You assemble a page from usercontrols using the renderpartial method of the html extension class

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">

    <h2><%= Html.Encode(ViewData["Message"]) %></h2>

    <p>

        <% Html.RenderPartial("MyPartialView", new MyModel()); %>       

    </p>

</asp:Content>

The ajax stuff needs extra script libraries. Include these in your masterfile

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

    <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>

    <link href="../../Content/Site.css" rel="stylesheet" type="text/css" />

    <script src="/Scripts/MicrosoftAjax.debug.js" type="text/javascript"></script>

    <script src="/Scripts/MicrosoftMvcAjax.debug.js" type="text/javascript"></script>

</head>


Async postbacks

The code so far produces this result.

 

AkM2

Three hyperlinks, as dictated by my model. As they are created by the ajax-, and not the html-, extension class they will do an async partial postback.

These requests are also caught by the home controller.

public class HomeController : Controller

{

    public ActionResult Partial(string routeValue)

    {

        return null;

    }

What the action returns does not matter yet, for now I just return null. The reason it does not matter yet is because the actionlink has not defined a target to receive the result of the action.

An ajax actionlink has as obligatory parameter an AjaxOptions object. So far I had created an empty object. A list of the properties of the AjaxOptions class is shown by Intellisense

 

AkM3

The updatetargetId is the id of any DOM element. Like an ordinary div. On the main page I will add an empty div as placeholder for the result of the async postback

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">

    <h2><%= Html.Encode(ViewData["Message"]) %></h2>

    <p>

        <% Html.RenderPartial("MyPartialView", new MyModel()); %>       

    </p>

    <div id="yourselection"></div>

</asp:Content>

(It would be tempting to code the div as <div id="yourselection"/>, but that will spoil the trick.)

This div is going to be the updatetarget for the ajax action link

        <%

=Ajax.ActionLink(item, "Partial", new {routeValue = item}, new AjaxOptions {UpdateTargetId = "yourselection"}) %>

Now the controller has a target for its result. I create another simple partial view to return

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MySelection>" %>

<%@ Import Namespace="AjaxKissesMVC.Models"%>

On <%=Model.SelectedTime %> you selected <%=Model.SelectedValue %>

This view uses another simple model

public class MySelection

{

    public MySelection(string selectedValue)

    {

        SelectedValue = selectedValue;

        SelectedTime = DateTime.Now.ToLongTimeString();

    }

 

    public string SelectedValue { get; set; }

    public string SelectedTime { get; private set;}

 

}

The model is passed to this partial view and this partial view will be the result of the action

public class HomeController : Controller

{

    public ActionResult Partial(string routeValue)

    {

        return View("Selected",new MySelection(routeValue));

    }

The result of the partial postback is now that the div will be filled by the contents of the usercontrol.

AkM4

That is all there is to the basics to create aync postbacks and do partial rendering. All pretty straightforward. And with loads of possibilities to enrichen behavior.

Creating a pop up

As a small example I will now present the basics of a (not the) way to do a popup screen. Creating a popup in a new browser window has quite a few drawbacks. Your application loses control of the window and communicating between the two DOM’s in the separate windows is no fun either. It is so much easier to have your popup and its contents in the same document.

Plain old HTML (POH ?) has the possibility to render itself in layers. Each layer has it’s own z-index. I will now add the target of the async postback as a new layer to the master page

<body>

    <div id="yourselection" style="z-index:2; position:absolute;"></div>

    <div class="page">

 

        <div id="header">

            <div id="title">

                <h1>My MVC Application</h1>

            </div>

 

The z-index attribute makes it a new layer. A new layer in the same document. The position:absolute attribute ensures independent positioning from the underlying layer. To see the effect the resulting partial view of the async postback is decorated with a style.

.popup

{

    background-color:Transparent;

    border-style: double;

    border-width: thick;

    border-color:Red;

}

Also a button is added to the popup. Clicking the button fires a script statement to close the popup. It does that by clearing the innerHTML of the target div

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MySelection>" %>

<%@ Import Namespace="AjaxKissesMVC.Models"%>

<div class="popup">

   On <%=Model.SelectedTime %> you selected <%=Model.SelectedValue %>

   <input type ="button" value="Close" onclick="$get(‘yourselection’).innerHTML=”;"/>

</div>

This results in a transparent popup which lies on top of the originating page and can be closed by clicking the button.

 

AkM5

 

 

 

By far not complete but the basics are there. I will leave it up to you (or better your html artist, I’m not good at it either…) for the further visual candy.

What I hope to have demonstrated is how easy and straightforward it is to add ajax functionality to an mvc application. Do your end users a favor and use it.

This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Nate

    Microsoft still needs a framework that replaces AjaxPro.net.

  • http://codebetter.com/members/pvanooijen/default.aspx pvanooijen

    Or Keep It Simple Stupid
    Capitalization was intended :)

  • http://tipsinterview.com Jack

    KISS = Keep your Implementation Short and Simple

  • http://codebetter.com/members/pvanooijen/default.aspx pvanooijen

    You are right, the text was not clear in what I intended to say

    Now it is:

    The model is passed to this partial view and this partial view will be the result of the action

    Thanks

  • chris

    you might want to change this line – it’s not true

    “This partial view is passed the model and will be the result of the action”

    the view is not passed to the model

  • http://codebetter.com/members/pvanooijen/default.aspx pvanooijen

    I have no intention to integrate the “official” ASP.AJAX with ASP.MVC. My only point is that ASP.MVC has all major ajax features on board but that the majority of the examples neglects them.

    Sometimes I am somewhat jealeous of the rich controls in the MS ajax control toolkit. But after some basic html fiddling, like the popup example, the need for the control becomes far less.

  • Paco

    It shouldn’t be Asp.Ajax versus Asp.Mvc, but it should be Asp.Ajax vs JQuery/Prototype/anything else. I don’t think Asp.Ajax has any benefits on integrating with Asp.Mvc over any of the other ajax frameworks.