C# 通过web api使无模式json可序列化
我有一个JSON字符串,其中包含一个复杂的嵌套对象,并且将来可能会更改模式。我想把它交给一个web API,以便根据需要在内容协商管道中序列化 有什么简单的方法可以做到这一点吗?我已经阅读了关于这个问题的其他答案,但它们只讨论了您事先知道所需模式的情况(例如使用C# 通过web api使无模式json可序列化,c#,asp.net-web-api,json.net,deserialization,content-negotiation,C#,Asp.net Web Api,Json.net,Deserialization,Content Negotiation,我有一个JSON字符串,其中包含一个复杂的嵌套对象,并且将来可能会更改模式。我想把它交给一个web API,以便根据需要在内容协商管道中序列化 有什么简单的方法可以做到这一点吗?我已经阅读了关于这个问题的其他答案,但它们只讨论了您事先知道所需模式的情况(例如使用JsonConvert.DeserializeAnonymousType反序列化)或您知道要反序列化的嵌套深度的情况 例如,假设我有以下字符串: @"{ name: "Dan" children: [
JsonConvert.DeserializeAnonymousType
反序列化)或您知道要反序列化的嵌套深度的情况
例如,假设我有以下字符串:
@"{
name: "Dan"
children: [
{
name: 'Fred',
},
{
name: 'Fannie',
age: 30,
children: {
own: [
{name: "Barney"},
{name: "Angela"}
],
adopted: {
{name: "Sven"}
}
}
}
}"
我不知道它的模式是什么,它可以随时更改,我只希望能够通过web api通过适当的内容协商发送它
我可以做
JObject.Parse(…)
但web api不能正确处理JObject
s。它可以正确处理字典,但我似乎不知道如何使用JSON.Net对任意嵌套深度的字典进行反序列化。我通过将动态对象转换为列表
实现了这一点。请澄清这是否是您需要的
好的,在你更新了你的问题之后,很明显你甚至不需要将它序列化到字典中。只需使用(它内置于WebApi中,并被用作默认JSON序列化程序btw)
另外,请确保将来您通过考试
工作示例(WebApi2)
JSON负载
{
"name": "Dan",
"children": [
{
"name": "Fred"
},
{
"name": "Fannie",
"age": 30,
"children": {
"own": [
{
"name": "Barney"
},
{
"name": "Angela"
}
],
"adopted": [
{
"name": "Sven"
}
]
}
}
]
}
代码
回应
作为他们的客户,Json.NET可以直接从Json转换为XML。以下是他们文档中的示例:
string json = @"{
'?xml': {
'@version': '1.0',
'@standalone': 'no'
},
'root': {
'person': [
{
'@id': '1',
'name': 'Alan',
'url': 'http://www.google.com'
},
{
'@id': '2',
'name': 'Louis',
'url': 'http://www.yahoo.com'
}
]
}
}";
XmlDocument doc = (XmlDocument)JsonConvert.DeserializeXmlNode(json);
// <?xml version="1.0" standalone="no"?>
// <root>
// <person id="1">
// <name>Alan</name>
// <url>http://www.google.com</url>
// </person>
// <person id="2">
// <name>Louis</name>
// <url>http://www.yahoo.com</url>
// </person>
// </root>
stringjson=@”{
“?xml”:{
“@version”:“1.0”,
“@standalone”:“否”
},
“根”:{
“人”:[
{
“@id”:“1”,
“姓名”:“艾伦”,
“url”:”http://www.google.com'
},
{
“@id”:“2”,
“姓名”:“路易斯”,
“url”:”http://www.yahoo.com'
}
]
}
}";
XmlDocument doc=(XmlDocument)JsonConvert.DeserializeXmlNode(json);
//
//
//
//艾伦
// http://www.google.com
//
//
//路易
// http://www.yahoo.com
//
//
因此,要么将JSON作为字符串传递(未经修改),要么根据请求的内容类型转换为XML。因此,经过长时间的调查,我设法将问题归结为:
- 当指定xml的内容类型时,默认情况下Web Api使用(现在基本上放弃了)
XmlSerializer
无法序列化XmlSerializer
sJObject
- 没有内置的方法将任意嵌套深度的
s转换为字典(尽管使用自定义递归函数来实现这一点并不十分困难)JObject
最后,我简单地删除了xml格式化程序,因为它对于我的api来说并不是绝对必要的,而且比它的价值更麻烦。你刚才说要将JSON字符串序列化为JSON吗?你可以始终使用
JObject.Parse(JSON)
返回解析后的JObject(它还实现了IDictonary).但我不明白您想如何在不知道任何信息的情况下从中获取属性。@L.B.我想使用web api将其发送到客户端。Web Api可以将其序列化为xml或json或其他形式,具体取决于可用的处理程序。然而,它不能从JObject
@georgemauer-OK转换成xml,但是你的问题是“我有一个JSON字符串……我想把它交给web API序列化为xml或JSON”。不管怎样,你甚至会如何处理这样的对象?如果不知道它的模式,就不知道它的属性。你只是完全通过反射与它进行交互吗?@GeorgeMauer那么为什么不将JSON转换成一个对象,然后根据需要将该对象序列化为JSON到XML呢?我认为你把所有人都弄糊涂了,因为你没有简明扼要地描述这个问题。是的,但这如何与web api内容协商相适应呢?@GeorgeMauer当然会有所帮助<代码>内容协商不是魔术。您将从请求中读取Accept
标题,然后相应地序列化内容(xml或json)(顺便说一句:我已经用WCF手动完成了很多次)@L.B是的,我可以手动完成各种事情-如果我想,我甚至可以编写一个超级手动完成事情的OWIN组件。但我正试图以WebApi特有的方式来实现它,我不知道这将如何融入到这个方案中。@GeorgeMauer您必须编写它:)@GeorgeMauer我知道您的期望,但不认为您会以您期望的方式实现它。@GeorgeMauer检查答案如果您发送一个包含application/xml
to your Test method?@BrianRogers默认情况下,WebApi无法反序列化未定义为xml的对象。无论如何,您可以删除默认的XML序列化程序并添加自己的序列化程序。这只是重申了我提到的WebApi可以将JObject
序列化为json而不是xml的问题。令人沮丧的是,匿名类型或字典可以序列化。所以诀窍是将JObject
转换为其中之一。JsonConvert.DeserializeObject(json)
不能处理任意嵌套深度字典吗?我听说可以,但我自己还没试过。我可能被误导了。@NickDeserializeObject
可能能够处理它,但这是专门针对另一个方向的——序列化。您说过“没有内置的方法将任意嵌套深度的作业对象转换为字典(尽管要实现这一点,自定义递归函数并不十分困难)。”这就是反序列化。@尼克:不,反序列化是从字符串(或字节等其他平面格式)到结构化对象。Ser
string json = @"{
'?xml': {
'@version': '1.0',
'@standalone': 'no'
},
'root': {
'person': [
{
'@id': '1',
'name': 'Alan',
'url': 'http://www.google.com'
},
{
'@id': '2',
'name': 'Louis',
'url': 'http://www.yahoo.com'
}
]
}
}";
XmlDocument doc = (XmlDocument)JsonConvert.DeserializeXmlNode(json);
// <?xml version="1.0" standalone="no"?>
// <root>
// <person id="1">
// <name>Alan</name>
// <url>http://www.google.com</url>
// </person>
// <person id="2">
// <name>Louis</name>
// <url>http://www.yahoo.com</url>
// </person>
// </root>