13

Mam proces dwuetapowy proces, w którym pierwszy zestaw danych jest przechowywany w sesji.ASP.NET MVC TryValidateModel() Problemy, gdy model jest modyfikowany

[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) wraca fałszywe, mówiąc VideoClip i VideoThumnail są wymagane, mimo mapowanie ich z seesionModel do ViewModel. Dodałem punkt przerwania i sprawdziłem, czy nie są one puste.

Wygląda na to, że istnieje pewna podstawowa funkcja, o której nie wiem, jak działają funkcje ModelState i ValidateModel(), po prostu nie wiem co.

UPDATE

Nie chciałbym powiedzieć, że problem został rozwiązany, ale zorientowali się obejście, że nie jest tak ładna, przechodząc do ModelState możliwe jest ustawienie ModelValue użyciu SetModelValue() następnie ręcznie usunąć błąd ze stanu modelu, a następnie wywołanie TryValidateModel() - możesz nawet nie dodawać wartości, tylko usunąć błąd, którego nie próbowałem. Oto moja praca.

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

Odpowiedz

20

Podczas wiązania modelu sprawdzana jest poprawność parametrów działania. Tak więc, gdy wykonanie zostanie wykonane zgodnie z public ActionResult TvCreate(TvNewsVideoVM modelVM) metodą , zawiera już błędy sprawdzania poprawności.
Po wywołaniu TryValidateModel, nie usuwa z ModelState, więc błędy sprawdzania poprawności pozostają tam, dlatego zwraca false. Więc trzeba wyczyścić zbiór ModelState jeśli chcesz przerobić walidacji później ręcznie:

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

Ów lepsze dzięki - Nie rozumiem, dlaczego metoda TryValidateModel() nie wywołać clear() Metoda pierwsza a następnie spróbować zweryfikować model. – SimonGates

+2

Jeśli jesteś zainteresowany tylko ręcznym sprawdzaniem poprawności, możesz pominąć początkową magię walidacji, dekorując metodę kontrolera przez bkwdesign

Powiązane problemy