1

我在局部视图中有一个表单,它可以工作,但是如果引发服务器端验证错误,它只会显示局部视图。所以我决定使用 ajax 来提交(实际上它是有道理的,因为它正在插入一个联系人并且在主视图中有一个列表)。

问题是,如果出现这些错误之一,则发布的代码会正确显示在视图中(我需要再次使部分可见,但这是另一回事),但如果没有错误,它将仅显示列表部分观点。我可以反过来做,在没有错误时正确显示,但不能正确显示验证错误。

我想了解什么是最好的方法,或者至少有哪些可能性:可能更改控制器中的代码或在成功回调中进行某种检查......

我编辑了我之前的内容,因为当没有错误时我应该返回列表,而不是我之前发布的整个视图,但无论如何我仍然对如何区分彼此有疑问,因为两者都是对 post 操作的成功调用

谢谢

观点是这个

@model ContactListViewModel

@{
    ViewBag.Title = " My Contacts"
}

<div id="ContactList">
    <h2>My Contacts</h2>
    <hr />
    <div id="addContainer">
        @{ Html.RenderAction("AddContact"); }
    </div>
    <div id="editContainer" data-amp-url="@Url.Action("Edit", "Contacts")" class="initiallyHidden"></div>
    @foreach (var group in Model.Contacts)
    {
        <div class="PlanContacts">
            <div class="PlanName">@group.Key</div>
            @foreach (var contact in group.Values)
            {
                <div class="Preview">
                    @Html.DisplayFor(m => contact, "Contact")
                </div>
            }
        </div>
    }
</div>

@section PageJavascript
{
    <script src="~/Scripts/AMPContacts.js"></script>
}

控制器发布动作

[HttpPost]
public ActionResult AddContact(AddContactViewModel viewModel)
{
    var partyId = (int) Session["PartyId"];
    if (ModelState.IsValid)
    {
        _contactsManager.AddContact(viewModel, partyId);
        // Here I should return the updated list
    }
    var newViewModel = _createBuilder.Rebuild(viewModel, partyId);
    return PartialView("_AddContact", newViewModel);
}

以及更长的AMPContact.js里面的ajax提交代码

$('#addForm').submit(function (e) {
    e.preventDefault();
    var addContainer = $(document.getElementById('addContainer'));
    $.ajax({
        url: this.action,
        type: this.method,
        data: $(this).serialize(),
        success: function(result) {
            addContainer.html(result);
        }
    });
});
4

1 回答 1

0

我理解这个答案远非好,但在缩小可能的搜索范围内,它可能对某人有用。因为它最终会变得很大,所以我宁愿发布这个更新作为我自己问题的答案,不确定它是否符合礼貌。

解释的问题不是我面临的唯一问题,重置表单以及特别是连续的错误提交(一旦我遇到错误尝试再次提交错误)也很困难,所以我最终弄得一团糟针对不同的问题提出不同的解决方案。希望我能把它清理干净

谢谢

在我现在使用的视图中

<div id="myContacts">
<h2>My Contacts</h2>
<hr />

<div id="addContainer">
    <div class="toggler">
        Add Contact
    </div>
    <div id="addToggling" class="initiallyHidden">
        @{ Html.RenderAction("AddContact"); }
    </div>
</div>

<div id="editContainer" data-amp-url="@Url.Action("Edit", "Contacts")" class="initiallyHidden"></div>

<div id="list">
    @{ Html.RenderPartial("_ContactList", Model); }
</div>

在 .js 中

$('#addContainer').on('submit', '#addForm', ajaxCall);

function ajaxCall(e) {
    e.preventDefault();
    var addToggling = $(document.getElementById('addToggling'));
    var contactList = $(document.getElementById('contactList'));

    $.ajax({
        url: this.action,
        type: this.method,
        data: $(this).serialize(),
        success: function (result) {
            if (result.passedValidation == true) {
                // Json is returned with flag, we get the list from the server and update the list element
                $.get(result.action, function (partial) {
                    contactList.html(partial);
                });

                // Add some effects and clear the form
                $(document).scrollTop(0);
                setTimeout(function () {
                    addToggling.slideUp(300, resetAddForm);
                }, 500);
                setTimeout(function () {
                    contactList.effect("highlight", {}, 3000);
                }, 1000);
            }
            else {
                // The form partial view is returned and displayed in the same element when there are validation errors
                $(document).scrollTop(0);
                addToggling.html(result);
                $.validator.unobtrusive.parse('#addForm');
            }
        }
    });
}

function resetAddForm() {
    var addForm = $(document.getElementById('addForm'));

    // Hhide the error messages
    addForm.find("span.field-validation-error").hide();
    addForm.find("div.validation-summary-errors").hide();

    // Removes the class associated to errors
    addForm[0].reset();

    // Clear the inputs
    addForm.find('input:text, input:password, input:file, select, textarea').val('');
    addForm.find('input:radio, input:checkbox').removeAttr('checked').removeAttr('selected');
}

与现有动作方法略有改变的控制器和一个新的

public ActionResult ContactList()
{
    var partyId = (int)Session["PartyId"];
    var viewModel = _displayBuilder.Build(partyId);
    return PartialView("_ContactList", viewModel);
}

[HttpGet]
public ActionResult AddContact()
{
    var partyId = (int) Session["PartyId"];
    var viewModel = _createBuilder.Build(partyId);
    return PartialView("_AddContact", viewModel);
}
[HttpPost]
public ActionResult AddContact(AddContactViewModel viewModel)
{
    var partyId = (int) Session["PartyId"];

    if (ModelState.IsValid)
    {
        _contactsManager.AddContact(viewModel, partyId);

        if (Request.IsAjaxRequest())
            return Json(new { passedValidation = true, action = Url.Action("ContactList")});

        return RedirectToAction("Index");
    }

    var newViewModel = _createBuilder.Rebuild(viewModel, partyId);
    return PartialView("_AddContact", newViewModel);
}
于 2013-04-28T14:29:53.790 回答