我有以下类结构。我试图实现的是,不是将Bar
序列化为JSON中的对象,而是将其序列化为具有内部属性Name
值的字符串,并忽略Id
属性。我没有需要对其进行反序列化的场景,但我必须从具有其他属性的数据库中加载Bar
对象,并进行一些内部操作,但不能将其用于传输。
class Foo
{
[JsonProperty("bar")]
public Bar Bar { get; set; }
}
class Bar
{
[JsonIgnore]
public Guid Id { get; set; }
[JsonProperty]
public string Name { get; set; }
}
预期JSON:
{
bar: "test"
}
使用自定义JsonConverter
,您可以控制转换以输出您想要的任何内容。
类似于:
public class BarConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Bar);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var bar = value as Bar;
serializer.Serialize(writer, bar.Name);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
// Note: if you need to read to, you'll need to implement that here too
// otherwise just throw a NotImplementException and override `CanRead` to return false
throw new NotImplementedException();
}
}
然后,您可以使用JsonConverterAttribute
:装饰您的属性或Bar
类(取决于您是否总是希望Bar
像这样序列化,或者仅针对此属性)
[JsonConverter(typeof(BarConverter))]
public Bar Bar { get; set; }
或者:
[JsonConverter(typeof(BarConverter))]
public class Bar
另一种"快速而肮脏"的方法是只拥有一个将被序列化的shadow属性:
public class Foo
{
[JsonProperty("bar")] // this will be serialized as "bar"
public string BarName
{
get { return Bar.Name; }
}
[JsonIgnore] // this won't be serialized
public Bar Bar { get; set; }
}
请注意,如果您希望能够读取,那么您还需要提供一个setter,并找出如何将字符串名称转换回Bar
的实例。这就是快速而肮脏的解决方案变得有点令人不快的地方,因为没有一种简单的方法可以将BarName
设置为仅在反序列化期间。