在另一个类中使用时,如何实现Id类的以下JSON表示?
class Car
{
public StringId Id { get; set; }
public string Name { get; set; }
}
class StringId
{
public string Value { get; set; }
}
// ---------------------------------------------
// Desired representation
{ "Id": "someId", "Name": "Ford" }
// Default (undesired) representation
{ "Id" : { "Value": "someId" }, "Name": "Ford" }
答案 0 :(得分:4)
您可以为StringId
添加TypeConverter
。 Json.NET将选择类型转换器并使用它将其转换为字符串:
[TypeConverter(typeof(StringIdConverter))]
class StringId
{
public string Value { get; set; }
}
class StringIdConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
return true;
return base.CanConvertFrom(context, sourceType);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(StringId))
return true;
return base.CanConvertTo(context, destinationType);
}
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is string)
{
return new StringId { Value = (string)value };
}
return base.ConvertFrom(context, culture, value);
}
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(string) && value is StringId)
{
return ((StringId)value).Value;
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
如果您的字符串表示包含嵌入的数字或日期/时间数据,请务必使用传入的culture
而不是默认的当前文化来转换该数据。 Json.NET将使用正确的文化which is the invariant culture by default调用转换器,从而确保生成的JSON文件可以在不同文化之间移植。
示例fiddle。
但请注意,如果您使用.Net Core,则仅在Json.NET 10.0.1时添加对类型转换器的支持。从10.0.3开始,Json.NET Portable版本中不支持类型转换器。
或者,如果您不介意在类型中添加特定于Json.NET的属性,则可以使用custom JsonConverter
:
[JsonConverter(typeof(StringIdConverter))]
class StringId
{
public string Value { get; set; }
}
class StringIdConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(StringId);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
var token = JToken.Load(reader);
return new StringId { Value = (string)token };
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var id = (StringId)value;
writer.WriteValue(id.Value);
}
}
您也可以在global settings。
中设置转换器示例fiddle。
答案 1 :(得分:1)
您可以覆盖ToString
类的StringId
方法以返回值
public override string ToString()
{
return this.Value;
}
稍后您需要TypeConverter
将字符串反序列化为StringId
public class StringIdConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is string)
{
return new StringId(value.ToString());
}
return base.ConvertFrom(context, culture, value);
}
}
使用此属性
装饰您的StringId
班级
[TypeConverter(typeof(StringIdConverter))]
public class StringId{
...
}