Добавьте ModelState.AddModelError в представление после отправки формы через javascript - PullRequest
0 голосов
/ 06 июля 2018

Я новичок в веб-разработке. В настоящее время я работаю над учебным проектом на asp.net mvc 5. У меня есть форма для пользователей, где администратор может добавить нового пользователя в систему. Новая пользовательская форма открывается в модальном режиме и представляется в формате

.

VIEW

@using (Html.BeginForm("AddUser", "User", FormMethod.Post, new { onsubmit = "return SubmitForm(this)" }))

{

@Html.ValidationSummary(true, "", new { @class = "text-danger" })

@Html.AntiForgeryToken()
<div class="form-horizontal">
    <div class="modal-header">
        <h4 class="modal-title" id="myModalLabel">Add New User</h4>
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.user_name, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-8">
            @Html.EditorFor(model => model.user_name, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.user_name, "", new { @class = "text-danger" })
            @Html.ValidationMessage("UserExist", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.role_id, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownListFor(model => model.role_id, new SelectList(ViewBag.roles, "role_id", "role_name"), "Select", new { @class = "form-control" })
            @Html.ValidationMessageFor(model => model.role_id)
        </div>
    </div>  


    <div class="form-group">
        @Html.LabelFor(model => model.user_password, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.user_password, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.user_password, "", new { @class = "text-danger" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(model => model.confirmPassword, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.confirmPassword, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.confirmPassword, "", new { @class = "text-danger" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(model => model.user_email, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.user_email, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.user_email, "", new { @class = "text-danger" })
            @Html.ValidationMessage("EmailExist", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.supervisor, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownListFor(model => model.supervisor, new SelectList(ViewBag.supervisors, "user_id", "user_name"), "Select Supervisor", new { @class = "form-control" })
        </div>

    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.region_id, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownListFor(model => model.region_id, new SelectList(ViewBag.regions, "region_id", "region_name"), "Select Region", new { @class = "form-control" })
        </div>
        @Html.ValidationMessageFor(model => model.region_id, "", new { @class = "text-danger" })
    </div>

    <div class="form-group">
        <input type="submit" id="submitBtn" value="Submit" class="btn btn-primary" />
        <input type="reset" value="Reset" class="btn" />
    </div>

</div>

}

Функция отправки Javascript

function SubmitForm(form) {
        if ($(form).valid()) {
            $.validator.unobtrusive.parse(form);
            $.ajax({
                type: "POST",
                url: form.action,
                data: $(form).serialize(),
                success: function (data) {
                    if (data.success) {
                        $('#myModal').modal('hide');
                        //Popup.dialog('close');
                        dataTable.ajax.reload();

                        //notify.js plugin
                        $.notify(data.message, {
                            globalPosition: "top center",
                            className: "success"
                        })
                    }
                }                    
            });
        }
        return false;
    }

при отправке форма переходит к результату действия POST, который работает нормально, и создается новый пользователь, но когда я пытаюсь добавить ошибку модели

#region User Already Exists
            var isUserExists = isUserExist(newUser.user_name);
            if (isUserExists)
            {
                ModelState.AddModelError("UserExist", "User already exists");
                return View(newUser);
            }
            #endregion

Ошибка модели не отражается в представлении. После отладки я обнаружил, что моя модель из результата действия POST не возвращается и используется предыдущая модель. Я уже давно занимаюсь этим вопросом, нашел несколько возможных решений, но ни одно из них, похоже, не работает. Любая помощь или чувство направления будут оценены.

Использование пульта здесь - это ViewModel

public class AddUser
{
    [Display(Name = "User name")]
    [Required(AllowEmptyStrings = false, ErrorMessage = "User name is required")]
    public string user_name { get; set; }

    [Display(Name = "Role")]
    [Required(AllowEmptyStrings = false, ErrorMessage = "Confirm Password is required")]
    public int role_id { get; set; }

    [Display(Name = "Password")]
    [Required(AllowEmptyStrings = false, ErrorMessage = "Password is required")]
    [DataType(DataType.Password)]
    [MinLength(6, ErrorMessage = "Minimum 6 characters required")]
    public string user_password { get; set; }


    [Display(Name = "Confirm Password")]
    [Required(AllowEmptyStrings = false, ErrorMessage = "Confirm Password is required")]
    [DataType(DataType.Password)]
    [System.ComponentModel.DataAnnotations.Compare("user_password", ErrorMessage = "Confirm password and password do not match")]
    public string confirmPassword { get; set; }

    [Display(Name = "Email")]
    [Required(AllowEmptyStrings = false, ErrorMessage = "Email is required")]
    [DataType(DataType.EmailAddress)]
    [System.Web.Mvc.Remote("CheckExistingEmail", "ModelValidation", HttpMethod = "POST", ErrorMessage = "Email already exists")]
    public string user_email { get; set; }

    [Display(Name = "Supervisor")]
    public Nullable<int> supervisor { get; set; }

    [Display(Name = "Region")]
    [Required(AllowEmptyStrings = false, ErrorMessage = "User Region is required")]
    public int region_id { get; set; }


}

и вот ValidationController

public class ModelValidationController : Controller
{
    [AllowAnonymous]
    [HttpPost]
    public ActionResult CheckExistingEmail(string Email)
    {
        try
        {
            return Json(!IsEmailExist(Email));
        }
        catch (Exception ex)
        {
            return Json(false);
        }
    }

    [NonAction]
    public bool IsEmailExist(string email)
    {
        using (mmpEntities mP = new mmpEntities())
        {
            var v = mP.users.Where(a => a.user_email == email).FirstOrDefault();
            //return v == null ? false : true;
            return v != null;
        }
    }

}

Ответы [ 2 ]

0 голосов
/ 07 июля 2018

Для валидации вы можете использовать ненавязчивый js-модуль jquery, и он даст вам функциональность при работе с ошибками jquery при вводе вводящего в заблуждение ввода. Вот как это можно использовать:

<script src=" jquery.validate.min.js"></script>
<script src="jquery.validate.unobtrusive.min.js"></script>
<script src="~/vendors/jquery.form.min.js"></script>
<script>
  $(document).ready(function () {
            $(document).on("click", "#Subscribe", function () {
                $('#SubscribeForm').ajaxForm({
                    success: function (response) {
                        if (response.Success) {
// You could use toastr notifaction in here } 
else {
                          // You could use toastr notifaction in here
                        }
                    }
                })
            })
        })
</script>
0 голосов
/ 06 июля 2018

Вот что я делаю внутри моего контроллера, чтобы отправить состояние модели обратно клиенту через успех (или сделано) в ajax:

if (ModelState.IsValid)
{
   //your post code to db

}
else
{
   var modelState = ModelState.ToDictionary
   (
       kvp => kvp.Key,
       kvp => kvp.Value.Errors.Select(e => e.ErrorMessage).ToArray()

   );
  return Json(new { modelState = modelState }, JsonRequestBehavior.AllowGet);
}

Затем в успешном или завершенном обратном вызове ajax выполните что-то вроде этого:

 if (data.modelState) {
     $.each(data.modelState, function (i, item) {
       item.valid(); //run jQuery validation to display error
     }
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...