gpt4 book ai didi

c# - C# 对象到 JSON 的模板化序列化

转载 作者:太空狗 更新时间:2023-10-29 17:55:25 24 4
gpt4 key购买 nike

我需要将对象序列化为 JSON。我想用 template 来完成它,而不是使用数据注释(就像大多数框架那样)。有人知道这样做的好方法吗?

一张图片胜过1000个字。我正在寻找看起来像这样的东西:

enter image description here

例如,如果我有这样一个类:

public class Test  
{
public string Key { get; set; }
public string Name { get; set; }
public string Code { get; set; }
public Test Related { get; set; }
}

还有一个模板字符串可能如下所示:

{ 
id: "$Key",
name: "$Name",
related: "$Related.Name"
}

我想获取一个JSON对象,其属性根据对象的KeyNameRelated.Name填写。

基本上,我正在寻找一种支持模板JSON 序列化方法。

最佳答案

我不知道有哪个库可以为您做这件事,但是您自己构建它并不难。

如果您有自己的模板,则需要将其解析为 JSON,然后将所有占位符替换为实际值。为此,您可以使用访问者模式。

由于 JSON.NET(我正在使用的 JSON 库)似乎没有访问者,您可以自己创建一个:

abstract class JsonVisitor
{
public virtual JToken Visit(JToken token)
{
var clone = token.DeepClone();
return VisitInternal(clone);
}

protected virtual JToken VisitInternal(JToken token)
{
switch (token.Type)
{
case JTokenType.Object:
return VisitObject((JObject)token);
case JTokenType.Property:
return VisitProperty((JProperty)token);
case JTokenType.Array:
return VisitArray((JArray)token);
case JTokenType.String:
case JTokenType.Integer:
case JTokenType.Float:
case JTokenType.Date:
case JTokenType.Boolean:
case JTokenType.Null:
return VisitValue((JValue)token);
default:
throw new InvalidOperationException();
}
}

protected virtual JToken VisitObject(JObject obj)
{
foreach (var property in obj.Properties())
VisitInternal(property);

return obj;
}

protected virtual JToken VisitProperty(JProperty property)
{
VisitInternal(property.Value);

return property;
}

protected virtual JToken VisitArray(JArray array)
{
foreach (var item in array)
VisitInternal(item);

return array;
}

protected virtual JToken VisitValue(JValue value)
{
return value;
}
}

然后创建一个用实际值替换占位符的专用访问器:

class JsonTemplateVisitor : JsonVisitor
{
private readonly object m_data;

private JsonTemplateVisitor(object data)
{
m_data = data;
}

public static JToken Serialize(object data, string templateString)
{
return Serialize(
data, (JToken)JsonConvert.DeserializeObject(templateString));
}

public static JToken Serialize(object data, JToken template)
{
var visitor = new JsonTemplateVisitor(data);

return visitor.Visit(template);
}

protected override JToken VisitValue(JValue value)
{
if (value.Type == JTokenType.String)
{
var s = (string)value.Value;

if (s.StartsWith("$"))
{
string path = s.Substring(1);

var newValue = GetValue(m_data, path);

var newValueToken = new JValue(newValue);

value.Replace(newValueToken);

return newValueToken;
}
}

return value;
}

private static object GetValue(object data, string path)
{
var parts = path.Split('.');

foreach (var part in parts)
{
if (data == null)
break;

data = data.GetType()
.GetProperty(part)
.GetValue(data, null);
}

return data;
}
}

使用起来就很简单了。例如,使用以下模板:

{ 
id : "$Key",
name: "$Name",
additionalInfo:
{
related: [ "$Related.Name" ]
}
}

您可以使用这样的代码:

JsonTemplateVisitor.Serialize(data, templateString)

结果是这样的:

{
"id": "someKey",
"name": "Isaac",
"additionalInfo": {
"related": [
"Arthur"
]
}
}

您可能想要添加一些错误检查,但除此之外,代码应该可以工作。此外,它使用反射,因此如果性能很重要,它可能不适合。

关于c# - C# 对象到 JSON 的模板化序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9174540/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com