C# MVC 4 模态窗口,局部视图和验证

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16016761/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 23:43:48  来源:igfitidea点击:

MVC 4 Modal window, partial view and validation

c#jqueryajaxasp.net-mvctwitter-bootstrap

提问by Traffy

I'm using MVC4 & Entity Framework to develop a web application. I have a table which enumerates all the persons I have in my DB. For each of them, I can edit their info throught a modal window which is a Partial View. However, when I put some wrong information, my application redirects me to my partial view. What I wanted to do is to display the errors intomy modal window.

我正在使用 MVC4 和实体框架来开发 Web 应用程序。我有一张表格,列出了我数据库中的所有人员。对于他们每个人,我都可以通过作为局部视图的模式窗口编辑他们的信息。但是,当我输入一些错误信息时,我的应用程序会将我重定向到我的部分视图。我想要做的是将错误显示我的模态窗口中。

My action :

我的行动:

[HttpGet]
public ActionResult EditPerson(long id)
{
    var person = db.Persons.Single(p => p.Id_Person == id);

    ViewBag.Id_ProductPackageCategory = new SelectList(db.ProductPackageCategories, "Id_ProductPackageCategory", "Name", person.Id_ProductPackageCategory);

    return PartialView("_EditPerson", person);
}

[HttpPost]
public ActionResult EditPerson(Person person)
{

    ViewBag.Id_ProductPackageCategory = new SelectList(db.ProductPackageCategories, "Id_ProductPackageCategory", "Name", person.Id_ProductPackageCategory);

    if (ModelState.IsValid)
    {
        ModelStateDictionary errorDictionary = Validator.isValid(person);

        if (errorDictionary.Count > 0)
        {
            ModelState.Merge(errorDictionary);
            return PartialView("_EditPerson", person);
        }

        db.Persons.Attach(person);
        db.ObjectStateManager.ChangeObjectState(person, EntityState.Modified);
        db.SaveChanges();
        return View("Index");
    }

    return PartialView("_EditPerson", person);
}

My partial view :

我的部分观点:

@model BuSIMaterial.Models.Person

<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
    <h3 id="myModalLabel">Edit</h3>
</div>
<div>

@using (Ajax.BeginForm("EditPerson", "Person", FormMethod.Post,
                    new AjaxOptions
                    {
                        InsertionMode = InsertionMode.Replace,
                        HttpMethod = "POST",
                        UpdateTargetId = "table"
                    }))
{

    @Html.ValidationSummary()
    @Html.AntiForgeryToken()

    @Html.HiddenFor(model => model.Id_Person)

    <div class="modal-body">
       <div class="editor-label">
            First name :
        </div>
        <div class="editor-field">
            @Html.TextBoxFor(model => model.FirstName, new { maxlength = 50 })
            @Html.ValidationMessageFor(model => model.FirstName)
        </div>
        <div class="editor-label">
            Last name :
        </div>
        <div class="editor-field">
            @Html.TextBoxFor(model => model.LastName, new { maxlength = 50 })
            @Html.ValidationMessageFor(model => model.LastName)
        </div>
        <div class="editor-label">
            National number :
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.NumNat, new { maxlength = 11 })
            @Html.ValidationMessageFor(model => model.NumNat)
        </div>
        <div class="editor-label">
            Start date :
        </div>
        <div class="editor-field">
            @Html.TextBoxFor(model => model.StartDate, new { @class = "datepicker", @Value = Model.StartDate.ToString("yyyy/MM/dd") })
            @Html.ValidationMessageFor(model => model.StartDate)
        </div>
        <div class="editor-label">
            End date :
        </div>
        <div class="editor-field">
            @if (Model.EndDate.HasValue)
            {
                @Html.TextBoxFor(model => model.EndDate, new { @class = "datepicker", @Value = Model.EndDate.Value.ToString("yyyy/MM/dd") })
                @Html.ValidationMessageFor(model => model.EndDate)
            }
            else
            {
                @Html.TextBoxFor(model => model.EndDate, new { @class = "datepicker" })
                @Html.ValidationMessageFor(model => model.EndDate)
            }
        </div>
        <div class="editor-label">
            Distance House - Work (km) :
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.HouseToWorkKilometers)
            @Html.ValidationMessageFor(model => model.HouseToWorkKilometers)
        </div>
        <div class="editor-label">
            Category :
        </div>
        <div class="editor-field">
            @Html.DropDownList("Id_ProductPackageCategory", "Choose one ...")
            @Html.ValidationMessageFor(model => model.Id_ProductPackageCategory) <a href="../ProductPackageCategory/Create">
                Add a new category?</a>
        </div>
        <div class="editor-label">
            Upgrade? :
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Upgrade)
            @Html.ValidationMessageFor(model => model.Upgrade)
        </div>
    </div>
    <div class="modal-footer">
        <button class="btn btn-inverse" id="save" type="submit">Save</button>
    </div>
}

</div>

My script which is in the Index view :

我在索引视图中的脚本:

        $('.edit-person').click(function () {
               var id = $(this).data("id");
               var url = '/Person/EditPerson/'+id;
               $.get(url, function(data) {

                   $('#edit-person-container').html(data);
                   $('#edit-person').modal('show');

               });
        });

Also, as you can see, I have put a size for my textboxes but in my modal, it seems to not be taken into account. Any ideas for these issues?

另外,正如您所看到的,我为我的文本框设置了一个大小,但在我的模式中,似乎没有考虑到它。对这些问题有什么想法吗?

回答by carmina

You need to handle the submission of the edit form via JavaScript otherwise it will redirect you to your partial view.

您需要通过 JavaScript 处理编辑表单的提交,否则它会将您重定向到您的部分视图。

You can do something like this:

你可以这样做:

$('form.edit').submit(function(e) {

    e.preventDefault();

    $.ajax({
        type: 'POST',
        url: '/Person/EditPerson/'
        data: { person: $(this).serialize() },
        success: function(data) {

            /* Add logic to check if successful edit or with errors. Or just return true when edit is successful. */

            $('#edit-person-container').html(data);
        }
    });

});

回答by Mortalus

You have to manually fire the validator on your form that was loaded dynamically into your html page.

您必须在动态加载到 html 页面的表单上手动触发验证器。

try this:

尝试这个:

in your view use Ajax.ActionLinkto load the content of the partial view into your dialog container to avoid unnecessary JavaScript.

在您的视图中用于Ajax.ActionLink将局部视图的内容加载到对话框容器中以避免不必要的 JavaScript。

@Ajax.ActionLink("AjaxLink", "EditPerson", new { PersonID = model.Id_Person }, new AjaxOptions { UpdateTargetId = "myModalDialog", HttpMethod = "Post",OnSuccess="OpenDialog(myModalDialog)" })

<div id="myModalDialog" title="" style="display: none">
</div>

in you JS file do this

在您的 JS 文件中执行此操作

function OpenDialog(DialogContainerID)
{
     var $DialogContainer = $('#' + DialogContainerID);
     var $jQval = $.validator; //This is the validator
     $jQval.unobtrusive.parse($DialogContainer); // and here is where you set it up.
     $DialogContainer.modal();

     var $form = $DialogContainer.find("form");
     $.validator.unobtrusive.parse($form);

     $form.on("submit", function (event)
     {
             var $form = $(this);

             //Function is defined later...
             submitAsyncForm($form,
             function (data)
             {
                     $DialogContainer.modal("hide");
                     window.location.href = window.location.href;

             },
             function (xhr, ajaxOptions, thrownError)
             {
                     console.log(xhr.responseText);
                     $("body").html(xhr.responseText);
             });
             event.preventDefault();
     });
}

//This is the function that will submit the form using ajax and check for validation errors before that.
function submitAsyncForm($formToSubmit, fnSuccess, fnError)
{
        if (!$formToSubmit.valid())
                return false;

        $.ajax({
                type: $formToSubmit.attr('method'),
                url: $formToSubmit.attr('action'),
                data: $formToSubmit.serialize(),

                success: fnSuccess,
                error: fnError

        });

}

回答by ofirbt

This worked for me:

这对我有用:

//allow the validation framework to re-prase the DOM
jQuery.validator.unobtrusive.parse();    
//or to give the parser some context, supply it with a selector
//jQuery validator will parse all child elements (deep) starting
//from the selector element supplied
jQuery.validator.unobtrusive.parse("#formId");
// and then:
$("#formId").valid()

Taken from Here

取自这里

回答by Anthony Mason

Have you added the following script to the layout or the view containing the partial? jquery.unobtrusive-ajax.min.js. This is required for asynchronous requests and is not added by default but is present within a new solution under Scripts.

您是否将以下脚本添加到包含部分的布局或视图中?jquery.unobtrusive-ajax.min.js。这是异步请求所必需的,默认情况下不会添加,但存在于脚本下的新解决方案中。