2012-06-18 10 views
18

ProblemaCome ottenere una chiave ModelState di un elemento in un elenco

Ho una lista di campi che l'utente può modificare. Quando viene inviato il modello, voglio verificare se questi articoli sono validi. Non posso usare le notazioni dei dati perché ogni campo ha un processo di convalida diverso che non conoscerò fino al runtime. Se la convalida fallisce, utilizzo lo ModelState.AddModelError(string key, string error) dove la chiave è il nome dell'elemento html a cui si desidera aggiungere il messaggio di errore. Poiché esiste un elenco di campi, il nome che Razor genera per l'elemento html è come Fields[0].DisplayName. La mia domanda è un metodo o un modo per ottenere la chiave del nome html generato dal modello di visualizzazione?

tentata soluzione

ho provato il metodo toString() per la chiave senza fortuna. Ho anche esaminato la classe HtmlHelper ma non ho visto alcun metodo utile.

frammento di codice

View Modello

public class CreateFieldsModel 
{ 
    public TemplateCreateFieldsModel() 
    { 
     FreeFields = new List<FieldModel>(); 
    } 

    [HiddenInput(DisplayValue=false)] 
    public int ID { get; set; } 

    public IList<TemplateFieldModel> FreeFields { get; set; } 


    public class TemplateFieldModel 
    { 
     [Display(Name="Dispay Name")] 
     public string DisplayName { get; set; } 

     [Required] 
     [Display(Name="Field")] 
     public int FieldTypeID { get; set; } 
    } 
} 

controller

public ActionResult CreateFields(CreateFieldsModel model) 
{ 
    if (!ModelState.IsValid) 
    { 
     //Where do I get the key from the view model? 
     ModelState.AddModelError(model.FreeFields[0], "Test Error"); 
     return View(model); 
    } 
} 

risposta

24

Dopo aver scavato nel codice sorgente ho trovato la soluzione. Esiste una classe denominata ExpressionHelper che viene utilizzata per generare il nome html per il campo quando viene chiamato EditorFor(). La classe ExpressionHelper ha un metodo chiamato GetExpressionText() che restituisce una stringa che è il nome dell'elemento html. Ecco come usarlo ...

for (int i = 0; i < model.FreeFields.Count(); i++) 
{ 
    //Generate the expression for the item 
    Expression<Func<CreateFieldsModel, string>> expression = x => x.FreeFields[i].Value; 
    //Get the name of our html input item 
    string key = ExpressionHelper.GetExpressionText(expression); 
    //Add an error message to that item 
    ModelState.AddModelError(key, "Error!"); 
} 

if (!ModelState.IsValid) 
{ 
    return View(model); 
} 
+4

Questo è buono ma ho appena trovato un altro post che avvolge questa logica in un bel metodo di estensione: http://stackoverflow.com/a/12689563/1825109 – Michael12345

0

Bisogna inquadrare la chiave (nome dell'elemento ingresso) all'interno del controllore base su come stai rendendo il f Ields nella forma.

Per es. se la convalida del secondo elemento della raccolta FreeFields di CreateFieldsModel non riesce, è possibile inquadrare il nome dell'elemento di input, ovvero il codice FreeFields[1].DisplayName in cui verrà mappato l'errore di convalida.

Per quanto ne so non si può facilmente ottenere dal controller.

+0

Quindi, forse, un campo nascosto in cui il nome è un valore costante e il valore del campo essere l'output del metodo EditorFor tranne ottenere l'attributo nome? –

Problemi correlati