4

そのため、ASP.NET MVC 4 ソリューションをいじっていました。すべてが正常に機能し、追加を続けましたが、奇妙なことが起こり始めました。

Json にアイテムが渡されたにもかかわらず、Models プロパティの 1 つが null でした。

これは、渡された javascript オブジェクト/json でした。

var obj = {
    "plc": "False",
    "al": ["386", "710"],
    "pl": ["9530", "211", "783"]
};

カスタムモデルバインダーを使用していました...それが問題かもしれないと思ったので、オフにしました。

.NET の JavaScriptSerializer を使用して、動作することを確認しました。

var reader = new StreamReader(Request.InputStream);
Request.InputStream.Position = 0;
var readToEnd = reader.ReadToEnd();

var javaScript = new JavaScriptSerializer();
var searchFarmOptions = javaScript.Deserialize<Test>(readToEnd);

すべてのプロパティが設定されました... WOOT。

そこで、クリーンな ASP.NET MVC 4 ソリューションを試しました。バグを再現します。

これは Index.cshtml ビューからのものです

@{
    ViewBag.Title = "title";
}

<h1>Title</h1>
Testing ... 
<script src="/Scripts/jquery-1.8.2.min.js" type="text/javascript"></script>
<script>
$(function() {
    var obj = {
        "1pllort": "False",
        "1plc": "true",
        "al": ["386", "710"],
        "pl": ["9530", "211", "783"]
    };

    var options = {
        "contentType": "application/json; charset=UTF-8",
         "type": "POST",
         "data" : JSON.stringify(obj)
    };
    $.ajax("/Home/TestPost", options).done(function(data) {
        console.log(data);
    });
});
</script>

これは私のホームコントローラーです

using System.Collections.Generic;
using System.Web.Mvc;

namespace MvcApplication3.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View("Index");
        }

        [HttpPost]
        public ActionResult TestPost(Test model)
        {
            return Json(model);
        }
    }

    public class Test
    {
        public List<int> PL { get; set; }
        public List<int> AL { get; set; }
        public bool PLC { get; set; }
        public bool ALC { get; set; }
    }
}

はい、バグはまだあります。

リスト名が「pl」で始まるプロパティがあるときはいつでも..「pl」リストはnullです。

また、「pl」で始まる任意の名前にすることもできます...「plchecked」のように

「plc」の名前を「cpl」に変更すると、機能します。

では、ここで何が起こっているのでしょうか... モデル バインダーに名前付けの制限はありますか? ここで何が欠けていますか?

更新 1

仕事

PL サーバー側には、null ではなく、数値のリストなどの正しい値が含まれるようになりました。

var obj = {
    "pl": ["9530", "211", "783"],
    "1plc": "false",
    "pl-some-odd-value": "false",
    "al": ["386", "710"],
    "alc": "false"
};

働かないで

PL サーバー側にnull価値があるようになりました。

var obj = {
    "pl": ["9530", "211", "783"],
    "al": ["386", "710"],
    "alc": "false",
    "pl-odd-value": "false"
};

仕事

PLには、jsonオブジェクト文字列から3つの値があります...

var obj = {
    "pl": ["9530", "211", "783"],
    "al": ["386", "710"],
    "alc": "false",
    "odd-value-pl": "false"
};
4

3 に答える 3

5

ImranB.ModelBindingFix nuget パッケージをインストールします。このブログ投稿で説明したバグに遭遇していると思います。

于 2013-03-14T06:06:35.147 に答える
3

間違いなくバグがあります。同じ問題について、MVC 4 ソース コードのデバッグに何時間も費やしました。プライマリ ルートは、名前が別のプロパティ名の先頭であるコレクションがあることを引き起こします。あなたの例では:plとpl-odd-value。

もう少しいじってみると、時々正しく動作することがわかるかもしれません。ランダムに見える理由は、モデル バインダーがバインドする値を見つけるためにバイナリ検索を実行するためです。二分探索は、「分割統治」アプローチを使用して、投稿されたプロパティのソートされたリストでプロパティを見つけます。分割統治で p1-odd-value を検索すると、問題が発生します。検索でこの値をスキップしても問題ありません。

この問題は、オブジェクトに pl-odd-value プロパティと 1 つの要素を持つ pl コレクションがある場合に最も再現性があります。

これに関連するもう少し情報があります。ポストバックされたすべての値の sortedList があります。テストが失敗した場合、ソートされたリストは次のようになります。

alc, "false",
al[0], "386"
al[1], "710"
pl-odd-value, "false"
pl[0], "9530"
pl[1], "211"
pl[2], "783"

ソート順は StringComparer.OrdinalIgnoreCase を使用していることに注意してください。これは、テキストのみのアイテムの後に角括弧アイテムを配置します。MVC が al または pl コレクションのバイナリ検索を実行している場合、al[ または pl[ ではなく、al または pl を検索しています。角括弧なしでコレクション名を検索することにより、al < alc、alc 以下。問題は、コレクションに到達するために alc または pl-odd-value を処理する必要があることです。

回避策は、どのプロパティ名もコレクション プロパティ名の名前で始まらないようにすることです。al コレクションの名前を al_collection に、pl コレクションの名前を pl_collection に変更します。

于 2013-03-14T02:36:24.177 に答える
-1

素晴らしい答えです!

私は今日同じ問題を抱えていて、同じ接頭辞を持つプロパティに何か奇妙なものがあることに突然気づいたとき、問題が何であるかを把握するためにほぼ3時間を費やしました

詳細はこちら:

于 2015-04-21T18:48:15.680 に答える