2012-04-27 10 views
5

C'è un modo per forzare il binding delle proprietà A e B prima di C?ASP.NET MVC (4) - Associare le proprietà in un determinato ordine

Esiste una proprietà Order nella classe System.ComponentModel.DataAnnotations.DisplayAttribute, ma influisce sull'assegnazione di binding?

quello che sto cercando di realizzare è

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

in un costume ModelBinder

+0

Sarei corretto nel dire che 'page.Parent.Path' e' page.Slug' sono vincolati dal form e che vuoi che 'page.Path' sia impostato sulla concatenazione dei loro contenuti subito dopo l'associazione? vale a dire il valore 'page.Path' non esiste nel modulo? – Dangerous

+0

@ Corretto pericoloso, 'page.Path' non è presente nel modulo. Ottengo 'page.Parent.Id' e' page.Slug' dal modulo. –

+0

E voglio costruire il 'page.Path' dopo che' page.Parent' e 'page.Slug' sono vincolati. –

risposta

0

Inizialmente avrei risposto a Sams in quanto non avrebbe comportato alcun legame con la proprietà Path. Hai menzionato che potresti concatenare i valori usando una proprietà Path in quanto ciò causerebbe il caricamento lento. Immagino quindi che stai usando i tuoi modelli di dominio per mostrare le informazioni alla vista. Pertanto, consigliamo di utilizzare i modelli di visualizzazione per visualizzare solo le informazioni richieste nella vista (quindi utilizzare la risposta Sams per recuperare il percorso) e quindi associare il modello di visualizzazione al modello di dominio utilizzando uno strumento (ad esempio AutoMapper).

Tuttavia, se si continua a utilizzare il modello esistente nella vista e non è possibile utilizzare gli altri valori nel modello, è possibile impostare la proprietà del percorso sui valori forniti dal provider del valore del modulo in un raccoglitore modello personalizzato dopo la è stato eseguito un altro bind (supponendo che non sia eseguita alcuna convalida sulla proprietà path).

così lascia supporre si ha la seguente vista:

@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" /> 
} 

E la seguente vista del modello (o modello di dominio come il caso):

public class IndexViewModel { public string ParentPath { ottenere; impostato; } slug stringa pubblica {get; impostato; } stringa pubblica Percorso {get; impostato; } }

È quindi possibile specificare il seguente modello legante:

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; 
      } 
     } 
    } 

E infine specificare che questo modello legante deve essere utilizzato utilizzando il seguente attributo al modello di vista:

[ModelBinder(typeof(IndexViewModelBinder))] 
1

Perché non implementare la proprietà pagina come:

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

?

+0

Ciò causerebbe il caricamento lazy di tutti gli antenati della pagina uno per uno. Per esempio. se si visualizzano 10 pagine (ciascuna al livello 3 nella gerarchia) che potrebbero causare ulteriori 20 query al database. –