8

我的 web api 中有以下方法

public void Put(string id, [FromBody]IContent value) {
    //Do stuff
}

我正在使用主干 js 使用 fiddler 将以下 JSON 发送到服务器,值为 null:

{
    "id": "articles/1",
    "heading": "Bar",
    "$type": "BrickPile.Samples.Models.Article, BrickPile.Samples"
}

但是如果我首先在 JSON 对象中添加 $type 属性,则反序列化可以正常工作,请参阅:

{
 "$type": "BrickPile.Samples.Models.Article, BrickPile.Samples",
  "id": "articles/1",
  "heading": "Bar" 
}

是否可以将 newtonsoft 配置为检查对象中任何位置的 $type 属性而不是第一个属性,或者我可以配置主干以便它始终$type在 JSON 对象中首先添加属性?

4

4 回答 4

4

我强烈建议不要配置任何序列化程序(包括 JSON.NET)来从传入的有效负载中读取对象类型。这在历史上一直是 Web 应用程序中大量漏洞的原因。相反,将公共入口点更改为您的操作以将实际类型作为绑定参数,然后根据需要委托给内部可测试方法。

于 2013-03-22T16:17:42.603 回答
4

首先,AFAIK,Json.NET 的代码经过优化以避免将整个对象保存在内存中只是为了读取它的类型。所以最好放置$type为第一个属性。

其次,您可以编写自己的JsonConverter,首先读取JObject(使用Load方法),手动读取$type属性,从序列化程序获取类型SerializationBinder,创建值并从中填充它JObject

第三,关于安全性。虽然 Json.NET$type听起来是个好主意,但通常并非如此。它允许 Json.NET只需将其类型写入 JSON 文件即可从任何程序集创建任何对象类型。最好将 custom与只允许您指定的类型的字典一起使用。您可以在我的私有框架中找到一个示例(它还支持从 from获取值):SerializationBinder$typeJsonObjectAttribute

https://github.com/Athari/Alba.Framework/blob/742ff1aeeb114179a16ca42667781944b26f3815/Alba.Framework/Serialization/DictionarySerializationBinder.cs

(This version uses some methods from other classes, but they're trivial. Later commits made the class more complex.)

于 2013-04-04T12:16:10.647 回答
3

I had kind of the same question apparently, and someone found an answer. Not sure whats the appropriate way to share an answer and give him ALL the credit, but this is the link: Newtonsoft JSON.net deserialization error where fields in JSON change order

and this is the guy: https://stackoverflow.com/users/3744182/dbc

于 2015-04-09T22:51:05.350 回答
1

这将在主干中起作用,但我不知道每个浏览器的行为是否相同。基本上,不能保证每个浏览器都会按照添加的顺序保留项目。


MyModel = Backbone.Model.extend({

  // ...

  toJSON: function(){
    // build the "$type" as the first parameter
    var json = {"$type": "BrickPile.Samples.Models.Article, BrickPile.Samples"};
    // get the rest of the data
    _.extend(json, Backbone.Model.prototype.toJSON.call(this));
    // send it back, and hope it's in the right order
    return json;
  }


});

不过,最好让 NewtonSoft 的 JSON 反序列化器在不需要它在特定位置的情况下工作。希望这将是可能的。

于 2013-03-22T13:13:32.590 回答