4

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

我的模型属性之一为空,即使我在 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>

这是我的家庭控制器

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"
};
4

3 回答 3

5

安装ImranB.ModelBindingFix nuget 包。我认为您遇到了我在此博客文章中讨论过的错误。

于 2013-03-14T06:06:35.147 回答
3

肯定有bug。我只是花了几个小时调试 MVC 4 源代码来解决同样的问题。主要原因是您有一个集合,其名称是另一个属性名称的开头。在您的示例中:pl 和 pl-odd-value。

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

当您仅拥有具有 1 个元素的 pl 集合和对象中的 pl-odd-value 属性时,此问题最容易重复。

这是与此相关的更多信息。有一个返回的所有值的 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 回答