2010-07-02 20 views
7

Im tratando de excluir una propiedad requerida (Contraseña) para que el modelo no valide esa propiedad, pero por alguna razón todavía valida aunque trate de excluirla.ModelState.IsValid no excluye la propiedad requerida

controlador:

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

Usuario (utilizando dataannotation):

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

Im usando VS2008, MVC2, Firefox

Quizá Im cansado y puede' t verlo Cualquier ayuda se agradece

Respuesta

14

Actualmente estoy teniendo un problema similar con MVC3.

A pesar de [Bind(Exclude = "Password")] en mi acción, ModelState.IsValid todavía devuelve falso.

Me di cuenta de que TryUpdateModel(user, null, null, new string[]{"Password"}); estaba actualizando correctamente el modelo; sin embargo, sigue siendo falso. Luego descubrí (en algún lugar en stackoverflow, disculpas por no tener el enlace) que TryUpdateModel realmente devuelve ModelState.IsValid.

Por lo tanto, el problema no es con TryUpdateModel, sino con ModelState.IsValid.

Nota: esto también significa que no es necesario para verificar esto dos veces ... puede utilizar este código:

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

Así pues, el problema parece como si ModelState todavía está validando propiedades que han sido excluidos de su FormCollection.

que fue capaz de superar esto quitando el campo de ModelState antes de llamar TryUpdateModel:

ModelState.Remove("Password"); 

Tenga en cuenta que TryUpdateModel todavía requiere la lista de propiedades para excluir de la actualización de acuerdo con el código de seguridad.

+0

También estoy luchando con esto. Parece una hazaña realizar ModelState.Remove, cuando obviamente debería ser excluido. ¿Alguien puede explicar exactamente por qué MC3 validaton ignora Bind (Exclude =)? – automagic

+0

@James: estoy de acuerdo, parece contradictorio que TryUpdateModel excluya las propiedades enumeradas en excludeProperty, pero IsValid no excluye las enumeradas en Bind (Exclude) (o en excludeProperty). –

+0

Creo que encontré la respuesta: http://bradwilson.typepad.com/blog/2010/01/input-validation-vs-model-validation-in-aspnet-mvc.html –

0

Tal vez debería cambiar

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

con

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

ya que podría ser confuso, que sobrecarga para TryUpdateModel está utilizando. Solo digo ...

+0

Thx por la respuesta, pero Creo que mi problema está relacionado con que use el mismo modelo para crear y editar. Quiero que se requiera una contraseña al crear, pero no cuando se edita. La lista blanca/negra aparentemente no tiene nada que ver con el estado modelo que es válido: D – larole

3

Tuve éxito usando el siguiente método dentro de ASP.NET MVC 2

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

Para mantener el TryUpdate de la unión a ciertas propiedades modelo puede crear una plantilla de inclusión como la de abajo:

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

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

La actualización de la llamada TryUpodateModel de la siguiente manera:

TryUpdateModel<IUserValidateBindable>(user); 
0

He usado con éxito [Bind(Exclude = "Property")] y ModelState.Remove("Property") juntos, y funcionó como el encanto.

-2

Parece que estoy respondiendo demasiado tarde, pero también tuve el mismo problema.

Compruebe su colección ModelState.Keys. Las claves pueden tener el formato modelObjectName.Password y lo mismo para el resto de las propiedades del modelo.

Por lo tanto, en este caso ModelState.Remove("Password") no funcionará. Usted debe tratar de ModelState.Remove("modelObjectName.Password")

Esperanza edición de esta determinación de alguien :)

0

Se podría utilizar un método de extensión de este 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); 
} 

A continuación, sólo llamar:

var result = ModelState.IsValidExclude("Password"); 
Cuestiones relacionadas