2011-12-20 12 views
13

Ho un processo in due fasi in cui il primo set di dati viene archiviato in sessione.ASP.NET MVC TryValidateModel() Problemi con la modifica del modello

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

controller

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) ritorna falso, dicendo VideoClip e VideoThumnail sono obbligatori, nonostante loro mappatura dal seesionModel al ViewModel. Ho aggiunto un punto di interruzione e ho verificato che non sono nulli.

Sembra che ci siano alcune funzionalità di base di cui non sono a conoscenza riguardo a come funzionano ModelState e ValidateModel(), ma non so cosa.

UPDATE

Non direi che ho risolto il problema, ma capito una soluzione che non è quella bella, andando nel ModelState è possibile impostare il ModelValue utilizzando SetModelValue() quindi rimuovere manualmente l'errore dallo stato del modello e quindi chiamare TryValidateModel() - potrebbe non essere nemmeno necessario aggiungere i valori basta rimuovere l'errore non ho provato. Ecco il mio lavoro in giro.

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

risposta

20

Durante il binding del modello, lo DefaultModelBinder convalida i parametri di azione. Quindi, quando l'esecuzione raggiunge il metodo , lo ModelState contiene già gli errori di convalida.
Quando si chiama TryValidateModel il numero non cancella il ModelState quindi gli errori di convalida rimangono lì, motivo per cui restituisce false. Quindi, è necessario cancellare la raccolta ModelState se si vuole rifare la convalida manualmente in seguito:

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

Quello è meglio grazie - Non capisco il motivo per cui il metodo del TryValidateModel() non chiama Clear() Metodo primo e quindi tentare di convalidare il modello. – SimonGates

+2

se si è interessati solo alla convalida manuale, è possibile saltare la magia di convalida iniziale decorando il metodo Controller con bkwdesign

Problemi correlati