2011-01-14 13 views
20

Gram z nowym modelem JSM3 JSM Binding i jest całkiem niezły.ASP.NET MVC 3 Model JSON Wiązanie i walidacja modelu po stronie serwera pomieszane z walidacją po stronie klienta

Obecnie mogę wysłać JSON do kontrolera i powiązać go. Sprawdzanie poprawności modelu jest również przyjemne.

Co się stanie, jeśli model okaże się nieprawidłowy?

Chciałbym powrócić JSON i mają po stronie klienta powiadamia użytkownika (podobny jak chcesz wykonać normalne poprawności po stronie klienta w MVC)

czy ktoś wie niektórych samouczki na temat wykonywania tego?

Czy to możliwe?

A może istnieją ramy, które mogę wykorzystać, aby to zrobić?

+0

Jak się pisaniu tej JSON? Czy używasz AJAX? –

+0

yes, księgowanie przez ajax –

+0

@ TheCodeKing Czy łączysz się z powrotem z tym pytaniem? –

Odpowiedz

25

Poniższy przykład działa dla mnie przy użyciu dyskretnego JavaScript w MVC3. Robię coś bardzo podobnego. Biorąc pod uwagę następujące JsonResponse klasa:

public enum Status 
{ 
    Ok, 
    Error 
} 

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

Mój kontroler może mieć metodę tak:

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

A ModelStateDictionary może być wyliczone za błędy jak tak:

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

Wtedy w moim widok Mogę mieć następujący POST: JSON:

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

Używam jQuery.tmpl, aby wyświetlić błędy. Wyłączyłem to jednak z tego przykładu.

+2

okrzyki za odpowiedź .. Nie mogę tego w tej chwili przetestować, ponieważ jestem na wakacjach. Mam nadzieję, że nie przeszkadza ci, jeśli zostawię to otwarte, dopóki nie wrócę? –

+0

@Junto Dlaczego nie użyć wartości boolowskiej zamiast wyliczenia? – Rushino

+1

@Rushino Możesz rozszerzyć wyliczenie, dołączając na przykład ostrzeżenia lub informacje. Boolean ogranicza cię. – Junto

1

Dzięki za to rozwiązanie. Ulepszyłem to nieco, przekazując słownik, aby można było użyć dyskretnego javascriptu do umieszczenia sprawdzania poprawności na poszczególnych polach zamiast podsumowania przez odniesienie do klucza słownika.

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

Zastanawiam się, w jaki sposób wiążę błędy z json do formularza po stronie klienta - czy mógłbyś wyjaśnić, proszę? – mb666

0

@Junto i @ Jamey777, oboje przechodzą ModelState do funkcji błędu, ale następnie użyć zmiennej globalnej zamiast parametru.

i dlaczego nie można po prostu użyć trochę LINQ jak

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