MVC3 AJAX级联DropDownLists [英] MVC3 AJAX Cascading DropDownLists

查看:190
本文介绍了MVC3 AJAX级联DropDownLists的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个很难搞清楚如何让级联下拉列表,为我的asp.net MVC3应用程序。我有一个弹出框,我想显示2 dropdownlists的基础上,什么是第一个选定的第二所填充。每次我运行应用程序的控制方法返回值的正确列表,但不是打Ajax调用成功的一部分,我打了错误的部分。我已经做了很多的研究和随后的几个例子,我发现,但事情仍然不完全正确,任何帮助将大大AP preciated。

I am having a hard time figuring out how to get cascading drop down lists to work for my asp.net mvc3 application. I have a popup box and I would like to display 2 dropdownlists, the 2nd being populated based on what is selected in the first. Each time I run the application the controller method returns the correct list of values, but instead of hitting the success part of the ajax call I hit the error part. I have done lots of research and followed several examples I have found but something is still not quite right, any help would be greatly appreciated.

编辑:
进一步检查使用Firebug显示了美国错误500内部服务器错误:异常详细信息:System.InvalidOperationException:在序列化类型System.Data.Entity.DynamicProxies.GameEdition的'的对象时检测到循环引用

Further inspection using firebug shows an error 500 internal server error which states: Exception Details: System.InvalidOperationException: A circular reference was detected while serializing an object of type 'System.Data.Entity.DynamicProxies.GameEdition

我有以下的jQuery / AJAX:

I have the following 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');
            }
        });
    });
});

下面是我的控制器的方法:

Here is my controller method:

  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);
  }

下面是我的Web表单的html:

Here is my web form 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>
}

推荐答案

您不能发送JSON连接使用GET动词codeD请求。所以替换键入:GET键入:POST,也将努力。此外,由于您指定一个JSON请求必须,好了,送它与 JSON.stringify实现了JSON请求功能:数据:JSON。字符串化({游戏ID:游戏ID,platformId:platformId})。但是,因为你只有两个值我觉得用GET会更容易些。所以我的建议是删除的contentType:应用/ JSON 参数,让你的AJAX请求是这样的:

You cannot send JSON encoded requests using the GET verb. So replace type: 'GET' with type: 'POST' and it will work. Also since you have specified a JSON request you must, well, send a JSON request which is achieved with the JSON.stringify function: data: JSON.stringify({ gameId: gameId, platformId: platformId }),. But since you only have 2 values I think that using GET would be easier. So my recommendation is to remove the contentType: 'application/json' parameter and have your AJAX request look like this:

$.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 帮助我注意到以下几点:

Also in the DropDownListFor helper in your Razor markup I notice the following:

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

我可以说的是,这并没有做什么,你可能会认为它。

All I can say is that this doesn't do what you might think it does.

更新:

看来你是因为你是通过你的版本域模型将JSON方法得到一个圆形的对象引用错误。循环引用对象层次结构不能JSON序列化。除了不需要通过发送包含在此版本给客户端的所有掷骰子浪费的带宽。所有客户需要的是ID和名称的集合。所以,简单地使用视图模型:

It seems that you are getting a circular object reference error because you are passing your editions domain model to the Json method. Circular reference object hierarchies cannot be JSON serialized. Besides you don't need to waste the bandwidth by sending all the crap contained in this editions to the client. All your client needs is a collection of ids and names. So simply use view models:

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);
}

这篇关于MVC3 AJAX级联DropDownLists的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆