C# 使用JSON.Net反序列化$ref文档指针
我已经起床好几个小时了,想弄明白这件事。似乎有很多贴子都是围绕着我的问题,但没有一篇贴子对我有用 我只想使用json.net反序列化json文档中的$ref字段 JSON示例:C# 使用JSON.Net反序列化$ref文档指针,c#,.net,json,asp.net-web-api,json.net,C#,.net,Json,Asp.net Web Api,Json.net,我已经起床好几个小时了,想弄明白这件事。似乎有很多贴子都是围绕着我的问题,但没有一篇贴子对我有用 我只想使用json.net反序列化json文档中的$ref字段 JSON示例: { "items": [ { "$ref": "#/parameters/RequestId" }, { "name": "user", "in": "body", "description": "User metadata object", "requ
{
"items": [
{ "$ref": "#/parameters/RequestId" },
{
"name": "user",
"in": "body",
"description": "User metadata object",
"required": true
}
],
"parameters": {
"RequestId": {
"name": "X-requestId",
"in": "header",
"description": "this is a request id",
"required": false
}
}
}
示例类:
public class Item
{
public string Name {get;set;}
public string In {get;set;}
public string Description {get;set;}
public bool Required {get;set;}
}
public class RootDoc
{
public List<Item> Items {get;set;}
public Dictionary<string, Item> Parameters {get;set;}
}
公共类项目
{
公共字符串名称{get;set;}
{get;set;}中的公共字符串
公共字符串说明{get;set;}
需要公共bool{get;set;}
}
公共类RootDoc
{
公共列表项{get;set;}
公共字典参数{get;set;}
}
我期待的是:
var doc = JsonConvert.DeserializeObject<RootDoc>(json, new JsonSerializerSettings()
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
Error = delegate (object sender, ErrorEventArgs args)
{
// Handle all errors
args.ErrorContext.Handled = true;
}
});
Assert.IsNotNull(doc);
Assert.IsNotNull(doc.Items);
Assert.IsTrue(doc.Items.Count == 2);
Assert.IsTrue(doc.Items[0].Name == "X-requestId");
Assert.IsTrue(doc.Items[1].Name == "user");
var doc=JsonConvert.DeserializeObject(json,新的JsonSerializerSettings()
{
MetadataPropertyHandling=MetadataPropertyHandling.Ignore,
PreserveReferencesHandling=PreserveReferencesHandling.Objects,
ReferenceLoopHandling=ReferenceLoopHandling.Serialize,
Error=委托(对象发送方,ErrorEventArgs args args)
{
//处理所有错误
args.ErrorContext.Handled=true;
}
});
Assert.IsNotNull(doc);
Assert.IsNotNull(单据项);
Assert.IsTrue(doc.Items.Count==2);
Assert.IsTrue(doc.Items[0].Name==“X-requestId”);
Assert.IsTrue(doc.Items[1].Name==“用户”);
编辑:
我回答了下面的问题。我不敢相信我必须这么做,但它确实有效。哇。。。下面是我为解决这个问题所做的。我不确定是否有更简单的方法,我不敢相信json.net没有提供这种现成的方法
var x = JObject.Parse(json);
var xx = x.Descendants().ToList().Where(d => d.Path.ToLower().EndsWith("$ref"));
foreach (var item in xx)
{
if (!item.HasValues)
continue;
string str = item.First.ToString().TrimStart(new char[] { '#' }).TrimStart(new char[] { '/' });
var split = str.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
JToken token = x;
for (int i = 0;i<split.Length; i++)
{
token = token[split[i]];
}
item.Parent.Replace(token);
}
var doc = JsonConvert.DeserializeObject<RootDoc>(x.ToString(), new JsonSerializerSettings()
{
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
Error = delegate (object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args)
{
// Handle all errors
args.ErrorContext.Handled = true;
}
});
Assert.IsNotNull(doc);
Assert.IsNotNull(doc.Items);
Assert.IsTrue(doc.Items.Count == 2);
Assert.IsTrue(doc.Items[0].Name == "X-requestId");
Assert.IsTrue(doc.Items[1].Name == "user");
var x=JObject.Parse(json);
var xx=x.subjects().ToList(),其中(d=>d.Path.ToLower().EndsWith($ref));
foreach(xx中的var项目)
{
如果(!item.HasValues)
继续;
string str=item.First.ToString().TrimStart(新字符[]{'.'}).TrimStart(新字符[]{'/'});
var split=str.split(新字符[]{'/'},StringSplitOptions.RemoveEmptyEntries);
JToken令牌=x;
对于(inti=0;i您可以使用此代码
JObject o = JObject.Parse(json);
JToken tokenToReplace = o.SelectToken("$..$ref");
string[] s = tokenToReplace.Value<string>().Split('/');
string a = s[s.Length - 1];
JToken newToken = o.SelectToken("$.." + a);
JArray items = (JArray)o["items"];
items.Add(newToken);
tokenToReplace.Parent.Parent.Remove();
string newJson = o.ToString();
JObject o=JObject.Parse(json);
JToken tokenToReplace=o.SelectToken($..$ref”);
字符串[]s=tokenToReplace.Value().Split('/');
字符串a=s[s.长度-1];
JToken newToken=o.SelectToken($..”+a);
JArray items=(JArray)o[“items”];
项目。添加(纽顿);
tokenToReplace.Parent.Parent.Remove();
字符串newJson=o.ToString();
newJson
包含替换的$ref
可能类似于这样的o1.SelectToken(path).Replace(o2.SelectToken(path));
可以简化代码。