2011-12-20 11 views
13

Tengo un proceso de formulario de dos pasos donde el primer conjunto de datos se almacena en la sesión.ASP.NET MVC TryValidateModel() Problemas cuando se modifica el modelo

[IsMp4File] 
[Required(ErrorMessage = "* Please select a video to upload")] 
public HttpPostedFileBase VideoClip { get; set; } 

[Required(ErrorMessage = "* Please select a thumbmail image")] 
public HttpPostedFileBase VideoThumbnail{ get; set; } 

public string VideoFileName { get { return VideoClip.FileName; } } 

public NewsWizardStep CurrentStep { get; set; } 

...

public enum NewsWizardStep : int 
{ 
    One = 1, 
    Two = 2, 
    Three = 3, 
    Four = 4, 
    Five = 5, 
    Six = 6 
} 

controlador

public ActionResult TvCreate(TvNewsVideoVM modelVM) 
{ 
    if (modelVM.CurrentStep == NewsWizardStep.Two) 
    { 
    var sessionModel = ((TvNewsVideoVM)Session["TvModelVM"]); 

    modelVM.VideoClip = sessionModel.VideoClip; 
    modelVM.VideoThumbnail = sessionModel.VideoThumbnail; 
    } 

    if (TryValidateModel(modelVM)) 
    { 
    ... 
    } 
} 

TryValidateModel(modelVM) retornos falsos, diciendo VideoClip y VideoThumnail se requieren, a pesar de la cartografía de ellos desde el seesionModel al modelo de vista. He agregado un punto de interrupción y comprobé que no son nulos.

Parece que hay alguna funcionalidad subyacente de la que no estoy al tanto de cómo funcionan ModelState y ValidateModel(), simplemente no sé qué.

ACTUALIZACIÓN

yo no diría que he resuelto el problema, pero encontrado una solución que no es tan bonita, Al entrar en la ModelState es posible establecer el ModelValue usando SetModelValue() a continuación, quitar manualmente el error del estado del modelo y luego llamar al TryValidateModel() - es posible que ni siquiera tenga que agregar los valores simplemente elimine el error que no he intentado. Aquí está mi trabajo alrededor.

if (modelVM.CurrentStep == NewsWizardStep.Two) 
{ 
    var sessionModel = ((MtTvNewsVideoVM)Session["MtTvModelVM"]); 

    modelVM.VideoClip = sessionModel.VideoClip; 
    modelVM.VideoThumbnail = sessionModel.VideoThumbnail; 

    ModelState.SetModelValue("VideoClip", new ValueProviderResult(sessionModel.VideoThumbnail, sessionModel.VideoFileName, CultureInfo.CurrentCulture)); 
       ModelState.SetModelValue("VideoThumbnail", new ValueProviderResult(sessionModel.VideoClip, sessionModel.VideoFileName, CultureInfo.CurrentCulture)); 

    ModelState["VideoClip"].Errors.RemoveAt(0); 
    ModelState["VideoThumbnail"].Errors.RemoveAt(0); 
} 

Respuesta

20

Durante el enlace del modelo, el DefaultModelBinder valida los parámetros de su acción. Entonces, cuando la ejecución golpea su método public ActionResult TvCreate(TvNewsVideoVM modelVM) , el ModelState ya contiene los errores de validación.
Cuando llama a TryValidateModelno borraModelState por lo que los errores de validación permanecen allí es por eso que devuelve falso. Así que hay que borrar la colección ModelState si desea volver a realizar la posterior validación manualmente:

public ActionResult TvCreate(TvNewsVideoVM modelVM) 
{ 
    ModelState.Clear(); 

    if (modelVM.CurrentStep == NewsWizardStep.Two) 
    { 
    var sessionModel = ((TvNewsVideoVM)Session["TvModelVM"]); 

    modelVM.VideoClip = sessionModel.VideoClip; 
    modelVM.VideoThumbnail = sessionModel.VideoThumbnail; 
    } 

    if (TryValidateModel(modelVM)) 
    { 
    ... 
    } 
} 
+0

Eso es mejor gracias - No entiendo por qué el método de la TryValidateModel() no llama al Clear() Método primera y luego intentar validar el Modelo. – SimonGates

+2

si solo está interesado en realizar la validación manual, puede omitir la magia de validación inicial decorando el método del Controlador con bkwdesign

Cuestiones relacionadas