Jquery $ .ajax和load函数无法将参数传递给MVC控制器以获取部分视图到模态对话框

时间:2016-03-31 17:39:27

标签: c# jquery ajax asp.net-mvc-4 modal-dialog

当天的好时机,堆栈溢出社区。我正在使用jquery ajax调用构建我的第一个应用程序,但是我在获取客户信息方面遇到了麻烦,从控制器操作方法传递为部分视图以在模态对话框中显示它。

当我使用.load函数时,它按预期工作,但我无法将任何参数传递给我的控制器操作方法。然后我尝试使用$ .ajax,但仍然没有运气。

让我发布我的代码,以便您更好地了解我的问题。

我的主要观点

@model IEnumerable<App.AppService.Customer>


@{
    ViewBag.Title = "GetCustomers";
}

<script type="text/javascript">
    $(document).ready(function() {
        var customerID = 0;
        $("input[type=button]").click(function() {
            customerID = this.id;
            debugger;
            $("#dialogDiv").dialog("open");
        });

        $(function() {
            $('#dialogDiv').dialog({
                autoOpen: false,
                width: 400,
                resizable: false,
                title: 'Update customer information',
                modal: true,
                open: function() {
                    $.ajax({
                        url: '@Url.Action("GetCustomer", "Customer")',
                        contentType: 'application/json; charset=utf-8', 
                        method: "get",
                        data: JSON.stringify({ customerId : customerID }),
                        dataType: 'html'
                    });
                },

                buttons: {
                    "Close": function() {
                        $(this).dialog("close");
                    }
                }
            });
        });
    });
</script>

<h2>GetCustomers</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>

<div class="row">
    <div class="col-md-offset-1 col-md-10">


        <table class="table table-condensed table-striped">
            <tr>
                <th class="text-center">
                    @Html.DisplayNameFor(model => model.CustomerName)
                </th>
                <th class="text-center">
                    @Html.DisplayNameFor(model => model.Company)
                </th>
                <th class="text-center">
                    @Html.DisplayNameFor(model => model.Email)
                </th>
                <th class="text-center">
                    @Html.DisplayNameFor(model => model.PhoneNumber)
                </th>
                <th></th>
            </tr>

            @foreach (var item in Model)
            {
                <tr id="@item.CustomerID">
                    <td>
                        @Html.DisplayFor(modelItem => item.CustomerName)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Company)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Email)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.PhoneNumber)
                    </td>
                    <td>
                        <input type="button" value="edit" id="@item.CustomerID" /> |
                        @Html.ActionLink("Delete", "Delete", new { id = item.CustomerID })
                    </td>
                </tr>
            }

        </table>
    </div>
</div>
<div id="dialogDiv" title="Edit customer">
    <h3>Please wait ...</h3>
</div>

在此视图中,我检索了所有客户,当点击编辑按钮时,我想调用控制器方法并通过模态对话框中的id检索客户。

以下是我的控制器ActionMethod:

[HttpGet]
public ActionResult GetCustomer(int customerId)
{
    Customer customer = repository.GetCustomerById(customerId);
    return PartialView("_GetCustomerPartial", customer);
}

[HttpPost]
public ActionResult GetCustomer(Customer customer)
{
    if (repository.UpdateCustomer(customer))
    {
        return RedirectToAction("GetCustomers");
    }
    return HttpNotFound();
}

我的偏见:

@model App.AppService.Customer


@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Customer</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Company)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Company)
            @Html.ValidationMessageFor(model => model.Company)
        </div>

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

        <div class="editor-label">
            @Html.LabelFor(model => model.CustomerName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.CustomerName)
            @Html.ValidationMessageFor(model => model.CustomerName)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Email)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Email)
            @Html.ValidationMessageFor(model => model.Email)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.PhoneNumber)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.PhoneNumber)
            @Html.ValidationMessageFor(model => model.PhoneNumber)
        </div>

        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
}

使用此代码我得到Null引用错误。我相信这是因为参数没有传递给行动方法。

如果我只使用没有任何参数的加载函数(仅用于测试),它可以完美地工作并将客户对象作为局部视图返回到我的模态对话框。

工作代码:

 $(document).ready(function () {

        $("input[type=button]").click(function () {
            var customerId = this.id;
            debugger;
            $("#dialogDiv").dialog("open");
        });

        $(function () {
            $('#dialogDiv').dialog({
                autoOpen: false,
                width: 400,
                resizable: false,
                title: 'Update customer information',
                modal: true,
                open: function () {
                    debugger;
                    $(this).load("@Url.Action("GetCustomer")");
                },
                buttons: {
                    "Close": function() {
                        $(this).dialog("close");
                    }
                }
            });
        });
    });

控制器操作发生变化。

[HttpGet]
public ActionResult GetCustomer()
{
    Customer customer = repository.GetCustomerById(any int id);
    return PartialView("_GetCustomerPartial", customer);
}

我想实现相同的工作功能,但是使用参数我可以传递给控制器​​操作方法。

我浏览了this帖子,但遗憾的是他们并不理解人们在评论中提供的解决方案。

提前谢谢!

1 个答案:

答案 0 :(得分:1)

在继续研究这个问题后,我终于开始工作了。以下是解决方案:

$("input[type=button]").click(function () {
            var customerId = this.id;
            $.ajax({
                url: '@Url.Action("GetCustomer","Customer")',
                contentType: 'application/json; charset=utf-8',
                method: "get",
                data: ({ customerId: customerId }),
                dataType: 'html',
                success: function (result) {
                    $("#dialogDiv").dialog("open").html(result);
                },
                error: function (jqXHR, exception) {
                    var msg = '';
                    if (jqXHR.status === 0) {
                        msg = 'Not connect.\n Verify Network.';
                    } else if (jqXHR.status == 404) {
                        msg = 'Requested page not found. [404]';
                    } else if (jqXHR.status == 500) {
                        msg = 'Internal Server Error [500].';
                    } else if (exception === 'parsererror') {
                        msg = 'Requested JSON parse failed.';
                    } else if (exception === 'timeout') {
                        msg = 'Time out error.';
                    } else if (exception === 'abort') {
                        msg = 'Ajax request aborted.';
                    } else {
                        msg = 'Uncaught Error.\n' + jqXHR.responseText;
                    }
                    $("#output").html(msg);
                    $("#output").css("visibility", "visible");
                }
            });
        });
        $(function () {
            $('#dialogDiv').dialog({
                autoOpen: false,
                width: 400,
                resizable: false,
                title: 'Update customer information',
                modal: true,
                buttons: {
                    "Close": function() {
                        $(this).dialog("close");
                    }
                }
            });
        });

这里要提到的要点是我在错误的地方使用$ .ajax调用,删除JSON.stringify帮助我避免空引用异常。由于action方法的返回类型是html,我只是用html填充了我的对话框div,一切都像魅力一样。