2010-07-02 10 views
7

Próbuję wykluczyć wymaganą właściwość (hasło), aby ta opcja modelu nie potwierdzała tej właściwości, ale z jakiegoś powodu nadal jest sprawdzana, nawet gdy próbuję ją wykluczyć.ModelState.IsValid nie wyklucza wymaganej właściwości

Kontroler:

[Authorize, AcceptVerbs(HttpVerbs.Post)] 
    public ActionResult _Edit(int id, [Bind(Exclude = "Password")]FormCollection collection) 
    { 
     var user = Proxy.GetUser(id); 

     TryUpdateModel(user, null, null, new[]{"Password"}); 

     if(!ModelState.IsValid) 
      return PartialView(user); 

     Proxy.UpdateUser(user); 
    } 

Widok:

... 
    <tr> 
     <td class="label"> 
      <label class="row_description" for="Password"><%= S._("Password")%></label> 
     </td> 
     <td> 
      <%= Html.Password("Password", null, new { @class = "row_input" })%> 
      <%= Html.ValidationMessage("Password", "*")%> 
     </td> 
    </tr> 

użytkownika (przy użyciu dataannotation):

[Required] 
public string Password { get; set; } 

Im przy użyciu VS2008, MVC2, firefox

Może jestem po prostu zmęczony i mogę' t to zobacz. Każda pomoc jest mile widziana

Odpowiedz

14

Obecnie mam podobny problem z MVC3.

Pomimo [Bind(Exclude = "Password")] w mojej Akcji, ModelState.IsValid nadal zwraca wartość false.

Zauważyłem, że TryUpdateModel(user, null, null, new string[]{"Password"}); pomyślnie zaktualizował model; jednak wciąż wraca false. Potem dowiedziałem się (gdzieś na stackoverflow, przepraszam za brak linku), że TryUpdateModel faktycznie zwraca ModelState.IsValid.

Tak więc problem nie występuje z TryUpdateModel, ale z ModelState.IsValid.

UWAGA: Oznacza to również, że nie ma potrzeby, aby zweryfikować to dwa razy ... można użyć tego kodu:

if (!TryUpdateModel(user, null, null, new string[]{"Password"})) 
    return PartialView(user); 

Problem pojawia się w ten sposób jakby ModelState jest jeszcze właściwości, które zostały wyłączone z walidacji twój FormCollection.

udało mi się przezwyciężyć poprzez usunięcie pola z ModelState przed wywołaniem TryUpdateModel:

ModelState.Remove("Password"); 

Zauważ, że TryUpdateModel nadal wymaga listę właściwości, aby wykluczyć z aktualizacji, jak na powyższym kodzie.

+0

Ja też mam z tym problemy. Wydaje się hackish wykonać wykonać ModelState.Remove, gdy oczywiście powinno być wykluczone. Czy ktoś może wyjaśnić dokładnie, dlaczego walidacja MC3 ignoruje Bind (Exclude =)? – automagic

+0

@ James: Zgadzam się, wydaje mi się to trochę sprzeczne z intuicją, że TryUpdateModel wyklucza właściwości wymienione w excludeProperty, ale IsValid nie wyklucza tych wymienionych w Bind (Exclude) (lub w excludeProperty). –

+0

Myślę, że znalazłem odpowiedź: http://bradwilson.typepad.com/blog/2010/01/input-validation-vs-model-validation-in-aspnet-mvc.html –

0

Może należy wymienić

TryUpdateModel(user, null, null, new[]{"Password"}); 

z

TryUpdateModel(user, null, null, new string[] {"Password"}); 

ponieważ może to być mylące, które przeciążać dla TryUpdateModel korzysta. Po prostu mówiąc ...

+0

Thx za odpowiedzi, ale Myślę, że mój problem jest związany ze mną przy użyciu tego samego modelu do tworzenia i edycji. Chcę, aby hasło było wymagane podczas tworzenia, ale nie podczas edycji. Biała/czarna lista najwyraźniej nie ma nic wspólnego z ważną wersją modelu: D – larole

3

Udało mi się zastosować następującą metodę w ASP.NET MVC 2

TryUpdateModel(user); 
ModelState.Remove("Password"); 
if (!ModelState.IsValid) return PartialView(user); 

Aby utrzymać TryUpdate od wiązania się z pewnymi właściwościami modelu można utworzyć szablon integracji, takich jak ten poniżej:

public interface IUserValidateBindable 
{ 
    string UserId { get; set; } 
} 

public class User : IUserValidateBindable 
{ 
    [Required] 
    public string UserId { get; set; } 
    [Required] 
    public string Password { get; set; } 
} 

tę aktualizację połączenia TryUpodateModel następująco:

TryUpdateModel<IUserValidateBindable>(user); 
0

Użyłem z powodzeniem [Bind(Exclude = "Property")] i ModelState.Remove("Property") razem, i zadziałało jak urok.

-2

Wygląda na to, że odpowiadam za późno, ale też stanąłem przed tym samym problemem.

Sprawdź swoją kolekcję ModelState.Keys. Klucze mogą mieć postać modelObjectName.Password i takie same dla pozostałych właściwości modelu.

W takim przypadku ModelState.Remove("Password") nie będzie działać. Należy starać ModelState.Remove("modelObjectName.Password")

nadzieję, że to rozwiązać czyjś problem :)

0

Można użyć metodę rozszerzenia tak:

public static bool IsValidExclude(this ModelStateDictionary modelState, params string[] exclude) 
{ 
    foreach (var key in exclude) 
    { 
     if (modelState.ContainsKey(key)) 
      modelState.Remove(key); 
    } 

    return modelState.All(m => m.Value.Errors.Count == 0); 
} 

Następnie wystarczy zadzwonić:

var result = ModelState.IsValidExclude("Password"); 
Powiązane problemy