2010-07-02 12 views
7

Sto tentando di escludere una proprietà richiesta (password) in modo che lo stato del modello non convalidi quella proprietà, ma per qualche motivo continua a essere valida anche quando provo a escluderla.ModelState.IsValid non esclude la proprietà richiesta

Controller:

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

Vista:

... 
    <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> 

Utente (con dataannotation):

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

Im utilizzando VS2008, MVC2, firefox

Forse im solo stanco e può' lo vedo Ogni aiuto è apprezzato

risposta

14

Attualmente sto riscontrando un problema simile con MVC3.

Nonostante [Bind(Exclude = "Password")] nella mia azione, ModelState.IsValid restituisce ancora false.

Ho notato che TryUpdateModel(user, null, null, new string[]{"Password"}); aggiornava correttamente il modello; tuttavia ancora restituendo false. Ho quindi scoperto (da qualche parte su StackOverflow, scuse per non avere il collegamento) che TryUpdateModel restituisce effettivamente ModelState.IsValid.

Pertanto, il problema non è con TryUpdateModel, ma con ModelState.IsValid.

NB: questo significa anche che non è necessario verificare due volte ... è possibile utilizzare questo codice:

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

La questione appare dunque come se ModelState è ancora convalidando proprietà che sono state escluse dal il tuo FormCollection.

sono stato in grado di superare questo rimuovendo il campo da ModelState prima di chiamare TryUpdateModel:

ModelState.Remove("Password"); 

Nota che TryUpdateModel richiede ancora l'elenco di immobili da escludere l'aggiornamento come per il codice di cui sopra.

+0

Anche io sto lottando con questo. Sembra logico eseguire ModelState.Remove, quando ovviamente dovrebbe essere escluso. Qualcuno può spiegare esattamente perché la validazione MC3 ignora Bind (Escludi =)? – automagic

+0

@James: Sono d'accordo, sembra piuttosto controintuitivo che TryUpdateModel escluda le proprietà elencate in excludeProperty, ma IsValid non esclude quelle elencate in Bind (Exclude) (o in excludeProperty). –

+0

Penso di aver trovato la risposta: http://bradwilson.typepad.com/blog/2010/01/input-validation-vs-model-validation-in-aspnet-mvc.html –

0

Forse si dovrebbe sostituire

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

con

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

Perché potrebbe essere fonte di confusione che di sovraccarico per TryUpdateModel sta usando. Solo dicendo ...

+0

Thx per la risposta, ma Penso che il mio problema sia legato a me usando lo stesso modello per creare e modificare. Voglio che la password sia richiesta durante la creazione ma non durante la modifica. A quanto pare, la lista bianca/nera non ha nulla a che fare con il modelstate che è valido: D – larole

3

Ho avuto successo utilizzando il seguente metodo all'interno di ASP.NET MVC 2

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

Per mantenere il TryUpdate di legarsi a determinate proprietà modello è possibile creare un modello di inclusione come quello qui sotto:

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

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

L'aggiornamento alla chiamata TryUpodateModel come segue:

TryUpdateModel<IUserValidateBindable>(user); 
0

Ho usato con successo [Bind(Exclude = "Property")] e ModelState.Remove("Property") insieme, e ha funzionato come fascino.

-2

Sembra che sto rispondendo troppo tardi, ma ho anche affrontato lo stesso problema.

Controlla la tua collezione ModelState.Keys. Le chiavi potrebbero essere nel formato modelObjectName.Password e lo stesso vale per il resto delle proprietà del modello.

Quindi in questo caso ModelState.Remove("Password") non funzionerà. Si dovrebbe cercare ModelState.Remove("modelObjectName.Password")

Speranza problema questa volontà di qualcuno :)

0

Si potrebbe utilizzare un metodo di estensione in questo modo:

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

Poi basta chiamare:

var result = ModelState.IsValidExclude("Password"); 
Problemi correlati