Par Thierry Thoua,
dimanche, décembre 7 2008.
Lien permanent
ASP.NET
Après plusieurs semaines sans Internet à domicile, me revoici en ligne
avec le reste du monde ;-).. J'en profite pour publier un article sur
la gestion des "Binders" en ASP.NET MVC.
- BINDERS ? Kezako ?
Il existe un mécanisme de binding qui offre la possibilité de passer un "objet métier" à une méthode d'un controlleur. L'objet "Binder" fera cette traduction entre ce qui se trouve dans l'objet Form ASP.NET et l'objet métier. La liaison se définit dans le fichier global.asax.
- Exemple visuel
- Un formulaire basique d'insertion d'une facture
- On ne donne pas le montant de la facture. Il s'agit d'une erreur "bloquante"
- Le binding s'effectuera et remplira l'objet métier qui sera passé à la méthode du controlleur. De plus on affichera une erreur pour signaler que l'on a encodé une valeur erronnée
- Exemple de code
- Implémentation du binding de la classe Invoice
public class InvoiceBinder : IModelBinder
{
#region IModelBinder Members
public ModelBinderResult BindModel(ModelBindingContext bindingContext)
{
if (bindingContext == null)
throw new ArgumentNullException("bindingContext");
Invoice invoice = new Invoice();
NameValueCollection values = bindingContext.HttpContext.Request.Form;
invoice.CustomerName = values["CustomerName"];
try
{
string totalAmount = values["TotalAmount"];
if (string.IsNullOrEmpty(totalAmount))
bindingContext.ModelState.AddModelError("TotalAmount",
"Ce champ est obligatoire !");
else
invoice.TotalAmount = Convert.ToSingle(values["TotalAmount"]);
}
catch (Exception ex)
{
bindingContext.ModelState.AddModelError("TotalAmount", ex);
}
return new ModelBinderResult(invoice);
}
#endregion
}
- Déclaration du binding dans le Global.asax
protected void Application_Start()
{
ModelBinders.Binders[typeof(Invoice)] = new InvoiceBinder();
ModelBinders.DefaultBinder = new DefaultModelBinder();
RegisterRoutes(RouteTable.Routes);
}
- Implémentation du controlleur
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
return RedirectToAction("Create");
}
[AcceptVerbs("GET")]
public ActionResult Create()
{
return View(new Invoice());
}
[AcceptVerbs("POST")]
public ActionResult Create(Invoice invoice)
{
return View(invoice);
}
}
- Implémentation du formulaire
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
AutoEventWireup="true" CodeBehind="Create.aspx.cs"
Inherits="DemoMVC.Views.Home.Create" %>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<h2>
Add invoice :
</h2>
<% Html.BeginForm("Create", "Home"); %>
<table>
<tr>
<td>
Customer Name :
</td>
<td>
<%= Html.TextBox("CustomerName") %>
</td>
</tr>
<tr>
<td>
Total amount :
</td>
<td>
<%= Html.TextBox("TotalAmount") %>
<%= Html.ValidationMessage("TotalAmount") %>
</td>
</tr>
</table>
<input type="submit" value="Click clack" />
<% Html.EndForm(); %>
</asp:Content>
- Conclusion
Ce petit post se termine ici. Il ne se focalise pas trop sur les binders ... mais plutôt sur le couple ModelState + Binder. Il n'empêche ... ce mécanisme de binder offre de belles perspectives !