2012-06-18 15 views
18

ProblemJak uzyskać klucz ModelState elementu w liście

Mam listę pól, które użytkownik może edytować. Po przedłożeniu modelu chcę sprawdzić, czy te elementy są prawidłowe. Nie mogę używać notacji danych, ponieważ każde pole ma inny proces sprawdzania poprawności, którego nie będę znać przed uruchomieniem. Jeśli sprawdzanie poprawności nie powiedzie się, używam ModelState.AddModelError(string key, string error), gdzie klucz jest nazwą elementu html, do którego chcesz dodać komunikat o błędzie. Ponieważ istnieje lista pól, nazwa Razor generuje dla elementu html jest podobna do Fields[0].DisplayName. Moje pytanie dotyczy metody lub sposobu uzyskania klucza wygenerowanej nazwy html z modelu widoku?

Próba Rozwiązanie

Próbowałem metody toString() dla klucza bez powodzenia. Przeglądałem też klasę HtmlHelper, ale nie widziałem żadnych pomocnych metod.

Code Snippet

Widok Model

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

Odpowiedz

24

Po wykopaniu się w kodzie źródłowym znalazłem rozwiązanie. Istnieje klasa o nazwie ExpressionHelper, która jest używana do generowania nazwy html dla pola, gdy jest wywoływana EditorFor(). Klasa ExpressionHelper ma metodę o nazwie GetExpressionText(), która zwraca ciąg znaków, który jest nazwą tego elementu html. Oto jak z niego korzystać ...

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

To jest dobre, ale właśnie znalazłem inny post, który owija tę logikę w przyjemną metodę rozszerzenia: http://stackoverflow.com/a/12689563/1825109 – Michael12345

0

Trzeba wrobić klawisz (nazwa elementu wejściowego) wewnątrz sterownika opartego po tym, jak renderujesz f tony w formie.

Na przykład. jeśli sprawdzanie poprawności drugiego elementu w kolekcji FreeFields z CreateFieldsModel zakończy się niepowodzeniem, można wykadrować nazwę elementu wejściowego, np. klucz, jako FreeFields[1].DisplayName, gdzie zostanie odwzorowany błąd sprawdzania poprawności.

Z tego co wiem, nie można tego łatwo uzyskać z kontrolera.

+0

Więc może masz ukryte pole, w którym nazwa ma pewną stałą wartość, a wartość pola jest wynikiem metody EditorFor, z wyjątkiem uzyskania atrybutu name? –

Powiązane problemy