C# Json.NET – 根据另一个属性前缀化属性名称

huangapple go评论69阅读模式
英文:

C# Json.NET - Prefix property names based on another property

问题

I'm trying to serialize an object where the property names are prefixed based on another property in the object. This property will have a dynamic value at runtime, so I can't use the JsonProperty attribute. For example:

public class Example
{
    [JsonIgnore]
    public string Prefix { get; set; }

    public string Name { get; set; }
    public string Value { get; set; }
}
var fooExample = new Example
{
    Prefix = "foo_"
};

JsonConvert.SerializeObject(fooExample);

Output:

{
    foo_Name: ...
    foo_Value: ...
}

I tried to use a ContractResolver and override the CreateProperty method; however, there doesn't seem to be a way to get a reference to the parent object from here to retrieve the value of the Prefix property. Is there any other way to achieve this with Json.NET?

protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
    JsonProperty property = base.CreateProperty(member, memberSerialization);

    // How do I get this value from another property in the parent object?
    string prefix = "";

    property.PropertyName = prefix + property.PropertyName;

    return property;
}
英文:

I'm trying to serialize an object where the property names are prefixed based on another property in the object. This property will have a dynamic value at runtime, so I can't use the JsonProperty attribute. For example:

public class Example
{
    [JsonIgnore]
    public string Prefix { get; set; }

    public string Name { get; set; }
    public string Value { get; set; }
}
var fooExample = new Example
{
    Prefix = "foo_"
};

JsonConvert.SerializeObject(fooExample);

Output:

{
    foo_Name: ...
    foo_Value: ...
}

I tried to use a ContractResolver and override the CreateProperty method, however there doesn't seem to be a way to get a reference to the parent object from here in order to retrieve the value of the Prefix property. Is there any other way to achieve this with Json.NET?

protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
    JsonProperty property = base.CreateProperty(member, memberSerialization);

    // How do I get this value from another property in the parent object?
    string prefix = "";

    property.PropertyName = prefix + property.PropertyName;

    return property;
}

答案1

得分: 2

以下是翻译好的部分:

只需添加一个构造函数
var fooExample = new Example
{
    Prefix = "foo_", Name = "name", Value = "value"
};


var json = JsonConvert.SerializeObject(fooExample,
                                       Newtonsoft.Json.Formatting.Indented,
    new JsonSerializerSettings { ContractResolver =
                                 new PrefixSerializeContractResolver(fooExample.Prefix) });
                                 

public class PrefixSerializeContractResolver : DefaultContractResolver
{
    private readonly string _prefix;

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty property = base.CreateProperty(member, memberSerialization);

        property.PropertyName = _prefix + property.PropertyName;

        return property;
    }

    public PrefixSerializeContractResolver(string Prefix)
    {
        _prefix = Prefix;
    }
}
输出
{
  "foo_Name": "name",
  "foo_Value": "value"
}

这只是一个提示。您可以通过创建一个带有 Prefix 属性和一个通用函数的模型类接口来改进代码。但这将是您的家庭作业。

英文:

just add a constructor

var fooExample = new Example
	{
		Prefix = "foo_", Name="name", Value="value"
	};
	
  
	var json=JsonConvert.SerializeObject(fooExample,
										Newtonsoft.Json.Formatting.Indented,
	new JsonSerializerSettings { ContractResolver = 
                                 new PrefixSerializeContractResolver(fooExample.Prefix) });


public class PrefixSerializeContractResolver : DefaultContractResolver
{
   	private readonly string _prefix;
	 
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
	{
	
		JsonProperty property = base.CreateProperty(member, memberSerialization);

		property.PropertyName= _prefix+ property.PropertyName;

		return  property;
	}
	
	public PrefixSerializeContractResolver(string Prefix)
	{
	 _prefix=Prefix;
	}
}

output

{
  "foo_Name": "name",
  "foo_Value": "value"
}

It is just a hint. You can improve the code by creating a model class interface with a Prefix property and a generic function. But it will be your home work.

答案2

得分: 0

你可以编写一个自定义服务,利用JSON.NET的JsonWriter,并明确编写将特定类的实例(或通用于任何类的内容)转换为JSON字符串的逻辑,控制每个属性的名称WritePropertyName(String),根据传入的前缀或目标类上提供的属性来确定。通过这种方式,您可以完全控制类的JSON序列化过程。该服务可以设计成通用的,以便可以用于任何装饰/标记有您创建的接口的类(例如ICustomJsonKeySerializationPrefix),该接口包含用于提供前缀的属性。

英文:

You could write a custom service that utilizes the JSON.NET JsonWriter and explicitly write the logic for converting an instance of a specific class (or something generic for any class) to a JSON string, controlling which the name of each property WritePropertyName(String) based on your prefix passed in or provided as a property on the target class. With that approach you'd have complete control over the JSON serialization process for the class. The service could be made to be generic so that it could be utilized on any of your classes that decorated/marked with an interface you create (e.g. ICustomJsonKeySerializationPrefix) that contain the property used for sourcing the prefix.

huangapple
  • 本文由 发表于 2023年6月8日 06:00:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/76427368.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定