3

asp.net mvc3 アプリケーションでカスケード ドロップダウン リストを機能させる方法を理解するのに苦労しています。ポップアップ ボックスがあり、2 つのドロップダウン リストを表示したいと考えています。アプリケーションを実行するたびに、コントローラー メソッドは正しい値のリストを返しますが、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');
            }
        });
    });
});

これが私のコントローラーメソッドです:

  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です:

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

4

1 に答える 1

4

GET動詞を使用して、JSONでエンコードされたリクエストを送信することはできません。したがって、に置き換えるtype: 'GET'type: 'POST'機能します。JSON.stringifyまた、JSON リクエストを指定したので、関数で達成される 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');
    }
});

また、DropDownListForRazor マークアップのヘルパーで、次のことに気付きました。

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

私が言えることは、これはあなたが思っていることをしないということだけです。


アップデート:

editionsドメイン モデルを Json メソッドに渡しているため、循環オブジェクト参照エラーが発生しているようです。循環参照オブジェクト階層は、JSON シリアル化できません。さらに、このエディションに含まれるすべてのがらくたをクライアントに送信して帯域幅を浪費する必要はありません。クライアントが必要とするのは、ID と名前のコレクションだけです。したがって、単にビューモデルを使用してください:

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);
}
于 2012-06-19T06:03:50.840 に答える