2012-04-27 20 views
5

Gibt es eine Möglichkeit, bevor C Bindung von Eigenschaften A und B zu zwingen?ASP.NET MVC (4) - Bind Eigenschaften in einer bestimmten Reihenfolge

Es gibt Order-Eigenschaft in der System.ComponentModel.DataAnnotations.DisplayAttribute Klasse, aber ist es verbindliche Bestellung beeinflussen?

Was i

page.Path = page.Parent.Path + "/" + page.Slug 

in einem benutzerdefinierten zu erreichen bin versucht Modelbinder

+0

würde ich richtig sein zu sagen, dass '' page.Parent.Path' und page.Slug' an aus dem Formular gebunden werden und dass Sie 'page.Path' auf die Verkettung ihres Inhalts festgelegt werden nur nach der Bindung auftritt? h. der 'page.Path'-Wert existiert nicht in der Form? – Dangerous

+0

@Dangerous richtig, 'page.Path' ist nicht auf dem Formular. Ich bekomme 'page.Parent.Id' und' page.Slug' aus dem Formular. –

+0

Und ich möchte den 'page.Path' erstellen, nachdem' page.Parent' und 'page.Slug' gebunden sind. –

Antwort

0

ich hätte zunächst Antwort Sams empfohlen, da es überhaupt eine Bindung der Path-Eigenschaft nicht beteiligt wäre. Sie haben erwähnt, dass Sie die Werte mithilfe einer Path-Eigenschaft verketten können, da dies zu einem verzögerten Laden führen würde. Ich stelle mir daher vor, dass Sie Ihre Domänenmodelle verwenden, um Informationen zur Ansicht anzuzeigen. Ich würde mit Blick Modelle empfehlen daher in der Ansicht nur erforderlich, die Informationen angezeigt werden (dann Antwort verwenden Sams den Pfad abzurufen) und dann die Ansicht Modell dem Domänenmodell abzubilden unter Verwendung eines Werkzeugs (das heißt AutoMapper).

Wenn Sie jedoch weiterhin Ihr vorhandenes Modell in der Ansicht verwenden und die anderen Werte im Modell nicht verwenden können, können Sie die Pfadeigenschaft auf die vom Formularwertanbieter in einem benutzerdefinierten Modellbinder hinterlegten Werte festlegen Eine andere Bindung ist aufgetreten (vorausgesetzt, dass keine Validierung für die Pfadeigenschaft durchgeführt werden soll).

können also annehmen, dass Sie die folgende Ansicht haben:

@using (Html.BeginForm()) 
{ 
    <p>Parent Path: @Html.EditorFor(m => m.ParentPath)</p> 
    <p>Slug: @Html.EditorFor(m => m.Slug)</p> 
    <input type="submit" value="submit" /> 
} 

und die folgende Ansicht Modell (oder Domänenmodell wie es der Fall sein kann):

public class IndexViewModel { public string ParentPath { bekommen; einstellen; } öffentliche Zeichenfolge Slug {get; einstellen; } public string Pfad {get; einstellen; } }

Anschließend können Sie das folgende Modell Bindemittel fest:

public class IndexViewModelBinder : DefaultModelBinder 
    { 
     protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext) 
     { 
      //Note: Model binding of the other values will have already occurred when this method is called. 

      string parentPath = bindingContext.ValueProvider.GetValue("ParentPath").AttemptedValue; 
      string slug = bindingContext.ValueProvider.GetValue("Slug").AttemptedValue; 

      if (!string.IsNullOrEmpty(parentPath) && !string.IsNullOrEmpty(slug)) 
      { 
       IndexViewModel model = (IndexViewModel)bindingContext.Model; 
       model.Path = bindingContext.ValueProvider.GetValue("ParentPath").AttemptedValue + "/" + bindingContext.ValueProvider.GetValue("Slug").AttemptedValue; 
      } 
     } 
    } 

Und schließlich angeben, dass dieses Modell Bindemittel mit dem folgende Attribute auf dem View-Modell verwendet werden soll:

[ModelBinder(typeof(IndexViewModelBinder))] 
1

Warum die Seite Eigenschaft als nicht implementieren:

public string Path{ 
    get { return string.Format("{0}/{1}", Parent.Path, Slug); } 
} 

?

+0

Das würde dazu führen, dass alle Vorfahren der Seite einzeln nacheinander geladen werden. Z.B. Wenn Sie 10 Seiten anzeigen (jeweils auf Ebene 3 in der Hierarchie), die zusätzliche 20 Abfragen an die Datenbank verursachen könnten. –