Подтвердить что ты не робот

ASP.Net MVC 3 JSON Model Binding и проверка на стороне сервера, смешанная с проверкой на стороне клиента

Я играл с новым MVC3 Json Model Binding, и это довольно приятно.

В настоящее время я могу отправить JSON на контроллер и связать его. Проверка модели происходит также хорошо.

Но что произойдет, если модель недействительна?

Я хотел бы вернуть JSON и клиентская сторона уведомить пользователя (например, как вы будете выполнять обычную проверку на стороне клиента в mvc)

Кто-нибудь знает о некоторых учебниках о том, как это сделать?

Возможно ли это?

Или существуют ли рамки, которые я могу использовать для этого?

4b9b3361

Ответ 1

Следующий пример работает для меня при использовании ненавязчивого JavaScript в MVC3. Я делаю что-то очень похожее. Учитывая следующий класс JsonResponse:

public enum Status
{
    Ok,
    Error
}

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

Мой контроллер может иметь такой метод:

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

И ModelStateDictionary можно перечислить для ошибок так:

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

Тогда, на мой взгляд, у меня может быть следующая 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>

Я использую jQuery.tmpl для отображения ошибок. Однако я исключил это из этого примера.

Ответ 2

Спасибо за это решение. Я немного улучшил его, передав словарь, чтобы вы могли использовать ненавязчивый javascript для проверки правильности в отдельных полях вместо сводки, ссылаясь на ключ словаря.

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

Ответ 3

@Junto и @Jamey777, вы оба передаете ModelState в свою функцию ошибки, но затем вместо параметра вы используете глобальную переменную.

и почему вы просто не используете немного linq, например

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