我有一个类定义,其中包含一个返回接口的属性.
public class Foo
{
public int Number { get; set; }
public ISomething Thing { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
尝试使用Json.NET序列化Foo类给出了一条错误消息,例如"无法创建类型为'ISomething'的实例.ISomething可能是一个接口或抽象类."
是否有Json.NET属性或转换器可以让我指定Something在反序列化期间使用的具体类?
我知道ASP.NET Web API本身使用Json.NET来(反)序列化对象,但有没有办法指定JsonSerializerSettings你想要它使用的对象?
例如,如果我想将type信息包含在序列化的JSON字符串中该怎么办?通常我会在.Serialize()调用中注入设置,但Web API会默默地执行此操作.我找不到手动注入设置的方法.
此Imgur api调用返回一个列表,其中包含json中表示的Gallery Image和Gallery Album类.
我不知道如何使用Json.NET自动反序列化这些,因为没有$ type属性告诉反序列化器要表示哪个类.有一个名为"IsAlbum"的属性可用于区分两者.
这个问题似乎显示了一种方法,但它看起来有点像黑客.
我该如何反序列化这些类?(使用C#,Json.NET).
样本数据:
图库图片
{
"id": "OUHDm",
"title": "My most recent drawing. Spent over 100 hours.",
...
"is_album": false
}
Run Code Online (Sandbox Code Playgroud)
画廊专辑
{
"id": "lDRB2",
"title": "Imgur Office",
...
"is_album": true,
"images_count": 3,
"images": [
{
"id": "24nLu",
...
"link": "http://i.imgur.com/24nLu.jpg"
},
{
"id": "Ziz25",
...
"link": "http://i.imgur.com/Ziz25.jpg"
},
{
"id": "9tzW6",
...
"link": "http://i.imgur.com/9tzW6.jpg"
}
]
}
}
Run Code Online (Sandbox Code Playgroud)
}
我正在尝试在我的设置中设置这样的全局序列化设置global.asax.
var formatter = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
formatter.SerializerSettings = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
TypeNameHandling = TypeNameHandling.Objects,
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
Run Code Online (Sandbox Code Playgroud)
使用以下代码序列化对象时,不使用全局序列化程序设置?
return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(JsonConvert.SerializeObject(page))
};
Run Code Online (Sandbox Code Playgroud)
是不是可以像这样设置全局序列化设置,还是我错过了什么?
尝试设置JsonOutputFormatter选项:
var jsonFormatter = (JsonOutputFormatter) options.OutputFormatters.FirstOrDefault(f => f is JsonOutputFormatter);
if (jsonFormatter != null)
{
jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
}
Run Code Online (Sandbox Code Playgroud)
要么
mvcBuilder.AddJsonOptions(jsonOptions =>
{
jsonOptions.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
});
Run Code Online (Sandbox Code Playgroud)
但是,只要我添加这个,我得到:
MissingMethodException:找不到方法:'Newtonsoft.Json.JsonSerializerSettings Microsoft.AspNet.Mvc.Formatters.JsonOutputFormatter.get_SerializerSettings()'.
我正在使用标准 Microsoft.AspNet.Mvc.Formatters.Json (6.0.0-rc1-final)
编辑:通过安装解决它Newtonsoft.Json 6.0.6(降级所有其他参考)
有人已经有了吗?谢谢..
在这个链接上,在备注部分提到了" TypeNameHandling".在什么情况下,如果使用序列化/反序列化来自外部源的JSON会有害SerializationBinder?一个工作的例子将不胜感激.
静态安全扫描器在这一行标记了我的 C# 代码:
var result = JsonConvert.DeserializeObject<dynamic>(response);
Run Code Online (Sandbox Code Playgroud)
response 将包含来自 Web API 的 JSON 响应。
扫描程序将此标记为“不安全的反序列化”。
有人可以帮助我了解如何利用它吗?Web 示例并不清楚漏洞利用是否可以在DeserializeObject方法本身内发生,或者仅在反序列化之后发生。
我正在使用 Json.Net 来序列化一些应用程序数据。当然,应用规范略有变化,我们需要重构一些业务对象数据。将以前序列化的数据迁移到我们的新数据格式有哪些可行的策略?
例如,假设我们最初有一个业务对象,如:
public class Owner
{
public string Name {get;set;}
}
public class LeaseInstrument
{
public ObservableCollection<Owner> OriginalLessees {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
我们使用 Json.Net 将 LeaseInstrument 的一个实例序列化为一个文件。现在,我们将业务对象更改为如下所示:
public class Owner
{
public string Name {get;set;}
}
public class LeaseOwner
{
public Owner Owner { get;set;}
public string DocumentName {get;set;}
}
public class LeaseInstrument
{
public ObservableCollection<LeaseOwner> OriginalLessees {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
我曾考虑为 LeaseInstrument 编写自定义 JsonConverter,但从未命中 ReadJson 方法……而是在反序列化器到达该点之前抛出异常:
Additional information: Type specified in JSON
'System.Collections.ObjectModel.ObservableCollection`1[[BreakoutLib.BO.Owner,
BreakoutLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]],
System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' …Run Code Online (Sandbox Code Playgroud) 我使用TypeNameHandling在json中序列化和反序列化派生类的列表.它与属性和属性完美配合JsonProperty
public abstract class Animal
{
public bool CanFly { get; set;}
}
public class FlyingAnimal : Animal
{
public FlyingAnimal() { this.CanFly = true; }
}
public class SwimmingAnimal : Animal
{
public SwimmingAnimal() { this.CanFly = false; }
}
public class World
{
public World() {
this.Animals = new List<Animal>();
this.Animals.Add(new FlyingAnimal());
this.Animals.Add(new SwimmingAnimal());
}
[JsonProperty(ItemTypeNameHandling = TypeNameHandling.Auto)]
public List<Animal> Animals { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
现在,我需要一个返回派生类列表的WebAPI:
[RoutePrefix("Animals")]
public class AnimalsController : ApiController
{
public …Run Code Online (Sandbox Code Playgroud) 我有一堆域对象,我将它们序列化,发送到其他应用程序,然后使用Json.Net. 这些对象可能具有以下属性
我使用了TypeNameHandling.Auto,它将$type属性添加到与声明类型不同的类型。然而,这个设置对我的动态属性有一个不需要的副作用,即它们的类型也被声明了。
在下面的示例中,model是public dynamic Model { get; set; }在我的 C# 代码中定义的动态属性。
"model":{"$type":"<>f__AnonymousType0`3[[System.String, mscorlib],[System.String, mscorlib],[System.String, mscorlib]], ExampleAssembly","link":"http://www.google.com","name":"John"}
Run Code Online (Sandbox Code Playgroud)
当尝试在另一个程序集中反序列化此字符串时,Json.Net 无法(当然)找到ExampleAssembly. 使用该TypeNameHandling.None属性给出以下属性序列化
"model": {"link":"http://www.google.com","name":"John"}
Run Code Online (Sandbox Code Playgroud)
可以成功反序列化为dynamic. 但是,这会破坏派生类型的反序列化。
关于如何在不实现自定义IContractResolver和可能的其他自定义代码的情况下使其工作的任何想法?
我不拥有域对象,所以我不能用属性装饰它们或它们的属性,也不能允许它们实现接口等。我正在寻找的是序列化程序中省略类型的某种设置dynamics。
恕我直言,这应该可以通过设置以某种方式进行配置,我只是没有找到它。