ASP.NET MVC 4 - ModelBinder错误

时间:2013-02-27 15:15:19

标签: asp.net-mvc model-binding

所以我正在玩我的ASP.NET MVC 4解决方案。每件事都做得很好,不断添加东西,但奇怪的事情开始发生。

我的一个Models属性为null,即使我将Json中的项目传递给它。

这是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>

这是我的HomeController

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”列表为空。

此外,它可以是以“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"
};

3 个答案:

答案 0 :(得分:5)

安装ImranB.ModelBindingFix nuget package。我想你正在遇到我在this blog post中讨论过的一个错误。

答案 1 :(得分:3)

肯定存在一个错误。我花了好几个小时调试MVC 4源代码以解决同样的问题。主根导致您拥有一个名称是另一个属性名称的开头的集合。在您的示例中:pl和pl-odd-value。

如果你玩了一些,你可能会发现有时它可以正常工作。它看起来是随机的原因是模型绑定器执行二进制搜索以定位要绑定的值。二进制搜索使用“分而治之”方法在已发布的属性的排序列表中查找属性。如果搜索在其除法中测试p1-odd-value并征服,则会出现问题。如果搜索跳过此值,则没问题。

当您只是在对象中包含1个元素和pl-odd-value属性的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,not al [或pl [。通过搜索没有方括号的集合名称,al&lt; alc,不大于alc。问题是我们想要照看alc或pl-odd-value来到集合。

解决方法是确保您的所有属性名称都不以任何集合属性名称的名称开头。将您的al集合重命名为al_collection,将pl集合重命名为pl_collection。

答案 2 :(得分:-1)

很棒的答案!

今天我遇到了同样的问题,我花了近3个小时试图找出问题是什么时突然我意识到具有相同前缀的属性有些奇怪

更多信息: