【问题标题】:List with datamodel won't get bound to json object带有数据模型的列表不会绑定到 json 对象
【发布时间】:2012-06-16 17:15:42
【问题描述】:

我以前遇到过这个问题,但我从来没有很好地解决它。

这是我的 JSON 对象:

{ Targets: [{ Target: { Id: -1, EditUrl: editUrl}}] }

这些是我使用的模型:

public class TargetList
{
    public List<Target> Targets { get; set; }
}

public class Target
{
    public int Id { get; set; }
    public string EditUrl { get; set; }
}

这是动作:

    [HttpPost]
    public PartialViewResult GetSpecifics(TargetList targetList)
    {
        //Code and stuff
    }

TargetList 总是为空。我从来没有使用过这样的列表,即使它应该可以工作 OOTB(对吗?)。只有属性而没有列表的“普通”数据模型可以完美运行。

我在这里看到了一些相关的问题,其中一些建议在$.post 中添加traditional: true。不工作。我已经对数据进行了字符串化并且没有对数据进行字符串化,但无济于事。如果在传统设置为 true 时未进行字符串化,则 json 对象将变为 Targets: [Object object],所以我猜它与帖子有关。

我可以以某种方式手动绑定我的对象吗?在某些情况下覆盖工厂?我觉得我需要更多地控制这个功能。

我正在使用 MVC3、.NET4 和 jQuery-1.7.2。

我真的非常感谢任何帮助。

【问题讨论】:

    标签: c# jquery json asp.net-mvc-3 post


    【解决方案1】:

    Target: 是多余的。代表您的模型的 Json 字符串应该是

    {"Targets":[{"Id":1,"EditUrl":"aaa"},{"Id":2,"EditUrl":"bbb"}]}
    

    如果可以,请将其从您的 Json 字符串中删除。否则将您的类声明为:

    public class TargetList
    {
        public List<Target1> Targets { get; set; }
    }
    
    public class Target1
    {
        public Target2 Target;
    }
    
    public class Target2
    {
        public int Id { get; set; }
        public string EditUrl { get; set; }
    }
    

    我测试过

    string json = "{ Targets: [{ Target: { Id: -1, EditUrl: \"aaaa\"}}] }";
    var validObj = new JavaScriptSerializer().Deserialize<TargetList>(json);
    

    【讨论】:

    • 感谢您的回复,但是,它对我不起作用。我试过你的测试,我确实得到了一个目标,但属性是空的。你在使用 MVC3 吗?我想这实际上可能是一个错误......
    • 我使用最后两行来反序列化您的测试字符串。你也可以通过var jsonstr = new JavaScriptSerializer().Serialize(targetList);进行反向测试
    • 如果我将 json 字符串作为操作的参数,然后手动反序列化该字符串,它会起作用。这很丑陋,但现在可以了。感谢您为我指明正确的方向。我仍然很好奇为什么直接绑定到 TargetList 不起作用...
    【解决方案2】:

    不确定为什么您的 TargetList 没有被正确反序列化。您可以尝试创建一个自定义 ModelBinder,然后在活页夹中手动反序列化您的 JSON。这将使您的控制器保持清洁。我在我的项目中使用Json.NET 作为序列化程序。只需创建您自己的 ModelBinder:

    public class CustomModelBinder : IModelBinder
    {
      public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
      {
        string inputContent;
        using (var sr = new StreamReader(controllerContext.HttpContext.Request.InputStream))
        {
          inputContent = sr.ReadToEnd();
        }
        //JsonConvert is part of Json.NET
        var result = JsonConvert.DeserializeObject(inputContent, bindingContext.ModelType);
        return result;
      }
    }
    

    然后在 Global.asax.cs 中为 TargetList 设置你的 ModelBinder:

    protected void Application_Start()
    {
      ModelBinders.Binders[typeof(TargetList)] = new CustomModelBinder();
    }
    

    您还可以将 ModelBinder 用于需要反序列化的任何其他模型。

    【讨论】:

      猜你喜欢
      • 2014-02-25
      • 1970-01-01
      • 2011-02-20
      • 1970-01-01
      • 1970-01-01
      • 2012-03-31
      • 2021-12-21
      • 2023-03-31
      • 2014-06-29
      相关资源
      最近更新 更多