2010-11-02 17 views
6

Ich möchte einige Eigenschaften meines View-Modells vom Typ TimeSpan deklarieren, um die TotalMinutes-Eigenschaft anzuzeigen und an eine TimeSpan zu binden.Model binding TimeSpan from integer

Ich habe die Eigenschaft gebunden, ohne die stark typisierte Helfer, um die TotalMinutes Eigenschaft abzurufen mit: wird

<%=Html.TextBox("Interval", Model.Interval.TotalMinutes)%> 

Wenn das Feld mit dem View-Modell-Klasse gebunden zurück es die Zahl als Tag parst (1440 Minuten).

Wie kann ich dieses Verhalten bei bestimmten Eigenschaften überschreiben (vorzugsweise mit Attributen im View Model selbst)?

Antwort

10

ein Modell kundenspezifische Mappe Schreiben scheint wie eine gute Idee hier:

public class TimeSpanModelBinder : DefaultModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + ".TotalMinutes"); 
     int totalMinutes; 
     if (value != null && int.TryParse(value.AttemptedValue, out totalMinutes)) 
     { 
      return TimeSpan.FromMinutes(totalMinutes); 
     } 
     return base.BindModel(controllerContext, bindingContext); 
    } 
} 

Und es in Application_Start Registrierung:

protected void Application_Start() 
{ 
    AreaRegistration.RegisterAllAreas(); 
    RegisterRoutes(RouteTable.Routes); 
    ModelBinders.Binders.Add(typeof(TimeSpan), new TimeSpanModelBinder()); 
} 

Und schließlich bevorzugt immer stark typisierte Helfer in Ihrer Ansicht:

<% using (Html.BeginForm()) { %> 
    <%= Html.EditorFor(x => x.Interval) %> 
    <input type="submit" value="OK" /> 
<% } %> 

Und die entsprechende Editor-Vorlage (~/Views/Home/EditorTemplates/TimeSpan.ascx):

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<TimeSpan>" %> 
<%= Html.EditorFor(x => x.TotalMinutes) %> 

Nun könnte der Controller so einfach wie:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     var model = new MyViewModel 
     { 
      Interval = TimeSpan.FromDays(1) 
     }; 
     return View(model); 
    } 

    [HttpPost] 
    public ActionResult Index(MyViewModel model) 
    { 
     // The model will be properly bound here 
     return View(model); 
    } 
} 
+0

funktioniert perfekt. Es hat nicht geklickt, dass es möglich wäre, an eine Eigenschaft der 'TimeSpan' zu binden, indem man den Wertanbieter wie diesen benutzt. Vielen Dank. –