asp.net-mvc-3 - MVC3 AJAX 级联下拉列表

标签 asp.net-mvc-3 jquery

我很难弄清楚如何让级联下拉列表适用于我的 asp.net mvc3 应用程序。我有一个弹出框,我想显示 2 个下拉列表,第二个下拉列表是根据第一个下拉列表中选择的内容填充的。每次运行应用程序时, Controller 方法都会返回正确的值列表,但不是点击 ajax 调用的成功部分,而是点击错误部分。我做了很多研究,并遵循了我发现的几个例子,但有些东西仍然不太正确,任何帮助将不胜感激。

编辑: 使用 firebug 进行进一步检查显示错误 500 内部服务器错误,其中指出:异常详细信息:System.InvalidOperationException:序列化类型为“System.Data.Entity.DynamicProxies.GameEdition”的对象时检测到循环引用

我有以下 jQuery/AJAX:

<script type="text/javascript">
$(function () {
    $("#PlatformDropDownList").change(function () {
        var gameId = '@Model.GameID';
        var platformId = $(this).val();
        // and send it as AJAX request to the newly created action 
        $.ajax({
            url: '@Url.Action("Editions")',
            type: 'GET',
            data: { gameId: gameId, platformId: platformId },
            cache: 'false',
            success: function (result) {
                $('#EditionDropDownList').empty();
                // when the AJAX succeeds refresh the ddl container with 
                // the partial HTML returned by the PopulatePurchaseGameLists controller action 
                $.each(result, function (result) {
                    $('#EditionDropDownList').append(
                        $('<option/>')
                            .attr('value', this.EditionID)
                            .text(this.EditionName)
                    );

                });
            },
            error: function (result) {
                alert('An Error has occurred');
            }
        });
    });
});

这是我的 Controller 方法:

  public JsonResult Editions(Guid platformId, Guid gameId)
  {
     //IEnumerable<GameEdition> editions = GameQuery.GetGameEditionsByGameAndGamePlatform(gameId, platformId);
     var editions = ugdb.Games.Find(gameId).GameEditions.Where(e => e.PlatformID == platformId).ToArray<GameEdition>();

     return Json(editions, JsonRequestBehavior.AllowGet);
  }

这是我的网络表单 html:

<div id="PurchaseGame">
@using (Html.BeginForm())
{
    @Html.ValidationSummary(true, "Please correct the errors and try again.")
    <div>
        <fieldset>
            <legend></legend>
            <p>Select the platform you would like to purchase the game for and the version of the game you would like to purchase.</p>

            <div class="editor-label">
                @Html.LabelFor(model => model.PlatformID, "Game Platform")
            </div>
            <div class="editor-field">
                @Html.DropDownListFor(model => model.PlatformID, new SelectList(Model.Platforms, "GamePlatformID", "GamePlatformName"), new { id = "PlatformDropDownList", name="PlatformDropDownList" })
            </div>

            <div class="editor-label">
                @Html.LabelFor(model => model.EditionID, "Game Edition")
            </div>
            <div id="EditionDropDownListContainer">
                @Html.DropDownListFor(model => model.EditionID, new SelectList(Model.Editions, "EditionID", "EditionName"), new { id = "EditionDropDownList", name = "EditionDropDownList" })
            </div>

            @Html.HiddenFor(model => model.GameID)
            @Html.HiddenFor(model => model.Platforms)

            <p>
                <input type="submit" name="submitButton" value="Purchase Game" />
                <input type="submit" name="submitButton" value="Cancel" />
            </p>

        </fieldset>
    </div>
}

最佳答案

您无法使用 GET 动词发送 JSON 编码的请求。所以替换type: 'GET'type: 'POST'它会起作用的。此外,由于您已经指定了 JSON 请求,因此您必须发送一个通过 JSON.stringify 实现的 JSON 请求。功能:data: JSON.stringify({ gameId: gameId, platformId: platformId }), 。但由于你只有 2 个值,我认为使用 GET 会更容易。所以我的建议是删除 contentType: 'application/json'参数并使您的 AJAX 请求如下所示:

$.ajax({
    url: '@Url.Action("Editions")',
    type: 'GET',
    data: { gameId: gameId, platformId: platformId },
    cache: 'false',
    success: function (result) {
        $('#EditionDropDownList').empty();
        // when the AJAX succeeds refresh the ddl container with 
        // the partial HTML returned by the PopulatePurchaseGameLists controller action 
        if(result.length > 0)
        {
            $.each(result, function (result) {
                $('#EditionDropDownList').append(
                    $('<option/>')
                         .attr('value', this.EditionID)
                         .text(this.EditionName)
                );
            });
        }
        else
        {
            $('#EditionDropDownList').append(
                $('<option/>')
                    .attr('value', "")
                    .text("No edition found for this game")
            );
        }

    },
    error: function () {
        alert('An Error has occured');
    }
});

也在DropDownListFor中在 Razor 标记中的 helper 我注意到以下内容:

onchange = "Model.PlatformID = this.value;"

我只能说,这并不像你想象的那样。

<小时/>

更新:

您似乎收到了循环对象引用错误,因为您正在传递 editions域模型到 Json 方法。循环引用对象层次结构无法进行 JSON 序列化。此外,您不需要通过将该版本中包含的所有垃圾发送给客户端来浪费带宽。您的客户所需要的只是 ID 和名称的集合。因此只需使用 View 模型即可:

public ActionResult Editions(Guid platformId, Guid gameId)
{
    var editions = ugdb
        .Games
        .Find(gameId)
        .GameEditions
        .Where(e => e.PlatformID == platformId)
        .ToArray<GameEdition>()
        .Select(x => new 
        {
            EditionID = x.EditionID,
            EditionName = x.EditionName
        })
        .ToArray();

    return Json(editions, JsonRequestBehavior.AllowGet);
}

关于asp.net-mvc-3 - MVC3 AJAX 级联下拉列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11093986/

相关文章:

asp.net-mvc - Razor View 中动态定义的内容部分

使用 Enter 键时,HTML 表单不包含表单提交按钮名称

jquery - Asp.net MVC 3 和 Jquery 的图表 API

asp.net-mvc - 如何使 DropDownListFor 在 Razor 中不可选

javascript - 编写第一个 Chrome 扩展程序并尝试根据所选文本执行操作

jquery - Bootstrap 3.0 不适用于母版页

jQuery 视频在不同设备上的高度和宽度?

asp.net-mvc - MVC : Simplest way to create a link to the application base URL?

jquery - 如何使用 JQuery 为大图像创建可拖动页面( map )?

javascript - Knockout 如何使用元素获取数据绑定(bind)键和可观察值?