Nicolas Moyère
Utilisation de jQuery avec ASP.NET MVC
Développer une IHM à page unique avec ASP.NET MVC et jQuery
Par Nicolas Moyère publié le 30/06/2008 à 10:28, lu 1454 fois, 9 pages
 8 | Consolidation
La partie Javascript est bien factorisée. Ce n'est pas le cas de la méthode Render dans les vues ou du code dans les contrôleurs.

Toutes les vues MVC doivent hériter de ViewPage. Nous pouvons créer notre propre AjaxViewPage pour y placer la méthode Render :

using System.Web.Mvc;

using System.Web.UI;

 

namespace Messenger

{

    public class AjaxViewPage<TModel> : ViewPage<TModel> where TModel : class

    {

        /// <summary>

        /// The control that must be rendered as result of the AJAX request.

        /// </summary>

        public string RenderedControlId

        {

            get

            {

                object controlId = null;

                ViewData.TryGetValue("__RenderedControlId", out controlId);

                return (string)controlId;

            }

        }

 

        protected override void Render(HtmlTextWriter writer)

        {

            if (RenderedControlId == null)

            {

                // The complete view must be rendered.

                // We keep the default mechanism

                base.Render(writer);

            }

            else

            {

                // Only the given control is rendered

                Control control = FindControl(RenderedControlId);

                control.RenderControl(writer);

            }

        }

    }

}

Le code behind d'Index.aspx se simplifie en changeant uniquement sa classe parent :

namespace Messenger.Views.Shared

{

    public partial class Index : AjaxViewPage<IndexViewData>

    {

    }

}

Côté contrôleur, la syntaxe pour créer un résultat Ajax est plus lourde que pour les vues classiques. La classe Controller de MVC ne contient presque que des méthodes utilitaires pour créer les différents types de résultats. Nous allons l'étendre et faire hériter nos contrôleurs d'AjaxController :

public class AjaxController : Controller

{

    public BinaryResult Binary(string contentType, byte[] data)

    {

        return new BinaryResult() { ContentType = contentType, Data = data };

    }

 

    public AjaxViewResult Ajax(string selector)

    {

        return new AjaxViewResult().Add(selector, View());

    }

 

    public AjaxViewResult Ajax(string selector, ActionResult actionResult)

    {

        return new AjaxViewResult().Add(selector, actionResult);

    }

 

    public AjaxViewResult Ajax(string selector, ViewResult viewResult, string controlId)

    {

        return new AjaxViewResult().Add(selector, viewResult, controlId);

    }

}

Une fois que ContactsController hérite d'AjaxController, le code pour mettre à jour la liste des contacts et la zone de lecture devient :

return Ajax("#panel", View("Index"), "ReadContactPanel")

    .Add("#contacts", View("Index"), "ContactsPanel");

Enfin, nous pouvons remplacer les appels à notre extension jQuery en étendant l'AjaxHelper de MVC pour qu'il génère les appels à notre place :

public static class AjaxExtensions

{

    public static string Ajaxify(this AjaxHelper helper, params string[] selectors)

    {

        StringBuilder builder = new StringBuilder();

        builder.Append("<script type=\"text/javascript\">$(document).ready(function() { ");

        foreach (string selector in selectors)

        {

            builder.Append("$('" + selector + "').ajaxify();");

        }

        builder.Append("});</script>");

 

        return builder.ToString();

    }

}

Avec cette extension, la page d'envoi d'un nouveau message se transforme en :

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="New.ascx.cs" Inherits="Messenger.Views.Messages.New" %>

 

<form method="post" action="<%= Url.Action("Send", new { id = ViewData.Model } ) %>">

    <textarea name="messagetext" cols="28" rows="3"></textarea>

    <br />

    <%= Html.SubmitButton("send", "Send") %>

</form>

<%= Ajax.Ajaxify("#panel form") %>

Nous n'avons même plus à écrire de Javascript.
 
» Démarrer une discussion