2012-04-24 22 views
16

Chciałbym korzystać z wbudowanych funkcji sprawdzania poprawności, o ile to możliwe. Chciałbym również użyć tego samego modelu dla metod CRUD.Czy możliwe jest ręczne zaktualizowanie pliku ModelState.IsValid?

Jednak, ponieważ lista rozwijana nie może być wykonana przy użyciu wzorca standardowego, muszę ją potwierdzić ręcznie. W metodzie "post-back" chciałbym tylko zweryfikować listę rozwijaną i dodać ten wynik do ModelState, aby nie musiałem sprawdzać wszystkich innych parametrów, które są wykonywane za pomocą Adnotacji Danych. Czy można to osiągnąć?

Mogę się mylić co do rozwijanej listy, ale z tego, co przeczytałem, nazwa obiektu HTML dla rozwijanej listy nie może być taka sama jak właściwość w modelu, aby wybrana wartość była poprawnie ustawiona. Czy nadal można korzystać z adnotacji danych w tym obejściu?

Dzięki.

Odpowiedz

49

Można użyć addModelError

ModelState.AddModelError(key,message) 

kiedy go użyć, to unieważnia ModelState tak isValid zwróci false.


Aktualizacja
po obejrzeniu komentarz @ Pieter za odpowiedź

Jeśli chcesz wykluczyć element z wpływu na wynik isValid(), można użyć metody ModelState.Remove(field) przed wywołaniem isValid().

+0

+1 za podanie linku do funkcji addModelError –

+10

ModelState.Remove (pole) jest właśnie tym, czego potrzebuję! Dzięki. –

+1

Należy zachować ostrożność, jeśli używasz obiektu IValidatableObject w modelu, ponieważ sprawdzanie poprawności nie działa, gdy sprawdzanie poprawności atrybutu nie powiedzie się, ale ponownie, jeśli nie powiedzie się tylko dla właściwości, którą usuniesz() ma niepoprawny poprawny wynik. – pauloya

5

Nie można ręcznie ustawić właściwości ModelState.IsValid, ale można dodać komunikaty do ModelState, które zapewnią, że wartość IsValid będzie równa false.

ModelState.AddModelError(); 
+0

To nie jest to, czego szukam. To, czego szukam, jest czymś odwrotnym: ModelState.IgnoreModelError ("somekey"), aby zignorować wszelkie błędy sprawdzania poprawności właściwości za pomocą jakiegoś klucza, tak aby ModelState.IsValid nadal będzie analizował wszystkie pozostałe parametry.Powodem, dla którego tego potrzebuję, jest to, że próbuję mieć jeden model dla wszystkich metod CRUD, ale problem z listą rozwijaną wymaga ode mnie potraktowania listy rozwijanej inaczej w Create a Update. Wymagana adnotacja danych może być użyta przy tworzeniu, ale nie w aktualizacji. W przypadku aktualizacji będę musiał ją ręcznie zweryfikować ... –

+0

ręcznie, ale nie chcę, aby jego automatyczny błąd sprawdzania poprawności spowodował, że cały model był nieprawidłowy. –

+0

Oczywiście, mogę przezwyciężyć problem, korzystając z innego modelu aktualizacji. Dzięki. –

11

Inną opcją jest dziedziczenie IValidatableObject w modelu. Wdrożyć jego metodę Validate i można pozostawić wszystkie inne sprawdzanie poprawności w miejscu i napisać kod, który chcesz w tej metodzie. Uwaga: zwraca się pusty IEnumerable<ValidationResult>, aby wskazać, że nie wystąpiły żadne błędy.

public class Class1 : IValidatableObject 
{ 
    public int val1 { get; set; } 
    public int val2 { get; set; } 

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
    { 
     var errors = new List<ValidationResult>(); 
     if (val1 < 0) 
     { 
      errors.Add(new ValidationResult("val1 can't be negative", new List<string> { "val2" })); 
     } 
     if (val2 < 0) 
     { 
      errors.Add(new ValidationResult("val2 can't be negative", new List<string> { "val2" })); 
     } 
     return errors; 
    } 
} 

EDIT: Po ponownym przeczytaniu pytanie nie sądzę to zastosowania w niniejszej sprawie, ale wyjeżdżam odpowiedź tutaj w przypadku pomaga kogoś innego.

+0

Dzięki. Jest to opcja dla bardziej złożonych sytuacji. Dzięki za prowadzenie. –

+0

Osobiście podoba mi się ta opcja lepiej niż wybrane pytanie. Zachowuje logikę do sprawdzania poprawności modelu wewnątrz samego modelu, zamiast w kontrolerze. – ohyeah

2

tak, można to osiągnąć (także będzie korzystać z tego samego modelu metod CRUD):

modelowym przykładem

public class User 
{ 
    public virtual int Id{ get; set; } 
    public virtual Role Role { get; set; } 
} 
public class Role 
{   
    [Required(ErrorMessage = "Id Required.")] 
    public virtual int Id { get; set; } 
    [Required(ErrorMessage = "Name Required.")] 
    public virtual string Name { get; set; } 
} 

Przykład widoku z walidacji na dropdownlist

@Html.DropDownListFor(m => m.Role.Id, (SelectList)ViewBag.gRoles, "-- Select --") 
@Html.ValidationMessageFor(m => m.Role.Id) 

KONTROLER: wyczyszczenie wymaganych (ale niewymaganych tutaj) pól

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Creedit(User x) 
{ 
    x.Role = db.RoseSet.Find(x.Role.Id); 
    if (x.Role != null) 
    { 
     ModelState["Role.Name"].Errors.Clear(); 

    } 

    if (ModelState.IsValid) 
    { 
     // proceed 
    } 
    else 
    { 
     // return validation error 
    } 
} 
+1

Świetna odpowiedź dzięki za ModelState ["Role.Name"]. Błędy.Clear() – InkHeart

Powiązane problemy