2011-09-07 17 views
13

Ho un modulo "invia feedback" che utilizza "Ajax.BeginForm" per eseguire il rendering di un partial contenente gli elementi del modulo. L'evento OnSuccess si attiva anche se ModelState non è valido. È normale? Mi aspettavo di essere in grado di fare alcuni postback con conseguente modello non valido, quindi quando il modello è valido e non ci sono errori, l'evento OnSuccess si innescherà?ASP.NET MVC "Ajax.BeginForm" esegue OnSuccess anche se il modello non è valido

+0

sono d'accordo che questo è inutilmente complessa con cui lavorare. Ovviamente abbiamo bisogno di un valore semplice che indichi se il modello è valido o meno. –

risposta

17

È normale?

Sì, certo. Se il server invia HTTP 200, viene chiamato il metodo OnSuccess. La nozione di validità dello stato del modello è solo lato server. Finché l'azione del tuo controller restituisce qualche vista/partial/json/... l'OnSuccess si innescherà. Se viene generata un'eccezione all'interno dell'azione del controller, verrà attivato l'errore OnError anziché OnSuccess.

Quindi, al fine di gestire questo caso si potrebbe avere la vostra azione di controllo fare qualcosa sulla falsariga di:

[HttpPost] 
public ActionResult Process(MyViewModel model) 
{ 
    if (!ModelState.IsValid) 
    { 
     return Json(new { success = false }); 
    } 
    return Json(new { success = true }); 
} 

e poi:

function success(result) { 
    if (result.success) { 
     // the model was valid 
    } else { 
     // the model was invalid 
    } 
} 

Ora, nel caso del modello non valida si potrebbe desidera mostrare i messaggi di errore all'utente aggiornando il modulo. Quello che potresti fare in questo caso è inserire il tuo modulo all'interno di un partial e nel caso di uno stato di modello non valido restituirai una partialview dall'azione del controller e nel caso di successo di un oggetto json. Quindi nel tuo gestore di successo si potrebbe verificare:

function success(result) { 
    if (result.success) { 
     // the model was valid 
    } else { 
     // there were errors => show them 
     $('#myform_container').html(result); 
     // if you are using client side validation you might also need 
     // to take a look at the following article 
     // http://weblogs.asp.net/imranbaloch/archive/2011/03/05/unobtrusive-client-side-validation-with-dynamic-contents-in-asp-net-mvc.aspx 
     // and reattach the client validators to the form as you are 
     // refreshing its DOM contents here 
    } 
} 
+4

Grazie grazie. Questa risposta è perfetta. Sono sorpreso che non ci sia una solida documentazione sulla gestione di questo scenario (errori del modello) con la roba AJAX non invadente. –

+1

Non funziona per me perché, in caso di errore, devo restituire una vista, non un JSON. – Misi

+0

Penso che prima devi controllare il tipo del risultato: if (typeof (risultato) == "oggetto" && result.success) { – Misi

25

mi occupo di questo problema con un abbastanza semplice tecnica javascript:

Prima impostare il OnSuccess in questo modo:

OnSuccess = "UpdateSuccessful(data)" 

Allora la vostra funzione javascript come questo:

function UpdateSuccessful(data) { 
    if (data.indexOf("field-validation-error") > -1) return; 

    // Do your valid stuff here 
} 

In questo modo, non c'è bisogno di pasticciare w esimo il controller, o più importante, il controller può restituire il Partial View con gli errori del modello senza fare nulla di strano, vale a dire:

public ActionResult SaveDetails(Project model) 
    { 
     if (ModelState.IsValid) 
     { 
      model.SaveProject(); 
     } 

     return PartialView("ProjectForm", model); 
    } 

E nel tuo AjaxOptions:

UpdateTargetId = "FormContents" 

Ora basta assicurarsi di avere un div o qualcosa con id="FormContents" ovunque tu voglia visualizzare il tuo modulo.

+1

'OnSuccess =" UpdateSuccessful (data) "': davvero utile. Grazie. –

+0

Questo oggetto ** 'dati' ** funziona su tutti i browser? ha qualche limite o problemi di compatibilità? –

+0

Questo dovrebbe funzionare su tutti i browser che hanno JavaScript abilitato. –

3

È possibile effettuare le seguenti operazioni:

var OnSuccess = function() { 
    if ($(".validation-summary-errors").length == 0) { 
     //Your javascript/jquery code goes here 
    } 
} 
1

lieve variazione sul risposta Luis':

function OnSuccess() { 
    if ($("span[class='field-validation-error']").length == 0) { 
     alert("Target Platform saved Successfully."); 
    } 
} 
Problemi correlati