2011-01-14 24 views
20

Ho giocato con la nuova MVC3 Json Model Binding ed è molto bello.ASP.Net MVC 3 Modello JSON Convalida del modello lato server e binding con convalida lato client

Attualmente, posso postare JSON sul controller e collegarlo. Anche la convalida del modello si presenta bene.

Ma cosa succede se il modello non è valido?

mi piacerebbe tornare JSON e hanno il lato client notificare l'utente (come come che ci si comporta normale validazione lato client in MVC)

Qualcuno sa di alcuni tutorial su come eseguire questa?

È possibile?

O ci sono quadri che posso sfruttare per fare questo?

+0

Come stai scrivendo questo JSON? Stai usando AJAX? –

+0

si, inviando tramite ajax –

+0

@TheCodeKing Stai tornando a questa domanda? –

risposta

25

Il seguente esempio funziona per me quando si utilizza JavaScript non invadente in MVC3. Sto facendo qualcosa di molto simile. Dato il seguente JsonResponse classe:

public enum Status 
{ 
    Ok, 
    Error 
} 

public class JsonResponse 
{ 
    public Status Status { get; set; } 
    public string Message { get; set; } 
    public List<string> Errors { get; set; } 
} 

mio controller può avere un metodo così:

[HttpPost] 
public ActionResult Login(UserLoginModel model) 
{ 
    JsonResponse res = new JsonResponse(); 

    if (!ModelState.IsValid) 
    { 
     res.Status = Status.Error; 
     res.Errors = GetModelStateErrorsAsString(this.ModelState); 
     res.Message = "Oh dear, what have you done. Check the list of errors dude!"; 
    } 
    else 
    { 
     // Save it here... 

     // Return success 
     res.Status = Status.Ok; 
     res.Message = "Everything was hunky dory"; 
    }    

    return Json(res); 
} 

E il ModelStateDictionary può essere enumerato gli errori come così:

private List<string> GetModelStateErrorsAsString(ModelStateDictionary state) 
{ 
    List<string> errors = new List<string>(); 

    foreach (var key in ModelState.Keys) 
    { 
     var error = ModelState[key].Errors.FirstOrDefault(); 
     if (error != null) 
     { 
      errors.Add(error.ErrorMessage); 
     } 
    } 

    return errors; 
} 

Poi nel mio visualizzazione Posso avere il seguente JSON POST:

<script type="text/javascript"> 
$("form").submit(function (evt) { 
    // validate 
    $('form').valid(); 

    // extract values to submit   
    var form = $(this), 
     username = form.find("[name=Username]").val(), 
     password = form.find("[name=Password]").val(), 
     json = JSON.stringify({ 
      Username: username, 
      Password: password 
     }); 

    $.ajax({ 
     url: form.attr("action"), 
     type: 'POST', 
     contentType: 'application/json; charset=utf-8', 
     dataType: 'json', 
     data: json, 
     success: function (result) { 
      alert(result.Message); 
     } 
    }); 

    // stop form submitting 
    evt.preventDefault(); 
}); 
</script> 

Sto usando jQuery.tmpl per visualizzare gli errori. Ho escluso che da questo esempio però.

+2

evviva per la risposta .. Non riesco proprio a testare questo momento in quanto sono in vacanza. Spero non ti dispiaccia se lascio questo aperto fino al mio ritorno? –

+0

@Junto Perché non usare un booleano invece di un enum? – Rushino

+1

@Rushino È possibile estendere l'enumerazione per includere avvisi o informazioni. Boolean ti limita. – Junto

1

Grazie per questa soluzione. Ho migliorato un po 'passando un dizionario in modo che tu possa usare il discreto javascript per mettere la validazione sui singoli campi invece di un sommario facendo riferimento alla chiave del dizionario.

private Dictionary<string, string> GetModelStateErrorsAsString(ModelStateDictionary state) 
    { 
     Dictionary<string, string> errors = new Dictionary<string, string>(); 
     foreach (var key in ModelState.Keys) 
     { 
      var error = ModelState[key].Errors.FirstOrDefault(); 
      if (error != null) 
      { 
       errors.Add(key, error.ErrorMessage); 
      } 
     } 
     return errors; 
    } 
+4

Mi chiedo in effetti in che modo vincoli gli errori da json al tuo modulo sul lato client - potresti spiegare per favore? – mb666

0

@Junto e @ Jamey777, si sia passare il ModelState alla funzione di errore, ma poi si utilizza la variabile globale al posto del parametro.

e perchè non basta usare un po 'di LINQ come

private Dictionary<string, string> GetModelStateErrorsAsString() 
    { 
     return ModelState.Where(x=> x.Value.Errors.Any()) 
      .ToDictionary(x => x.Key, x => x.Value.Errors.First().ErrorMessage); 
    } 
Problemi correlati