[英]How to change property names depending on the type when serializing with Json.net?
我有一個object
類型的object
,我必須根據它的類型更改名稱。 應該與XML的[XmlElement("PropertyName", typeof(PropertyType))]
屬性非常相似。
例如,我有一個屬性public object Item { get; set; }
public object Item { get; set; }
如果在運行時我的屬性有一種類型的Vehicle
,我想將我的屬性名稱更改為“Vehicle”; 如果它有一種類型的Profile
,我想將我的屬性名稱更改為“配置文件”。
沒有基於其運行時類型動態更改屬性名稱的內置方法,但您可以使自定義JsonConverter
與自定義Attribute
類結合使用以執行您想要的操作。 需要使轉換器在類級別操作,以便能夠控制寫入JSON的屬性的名稱。 它可以使用反射迭代目標類的屬性,並檢查聲明為object
任何屬性是否已應用自定義屬性。 如果是,並且對象的運行時類型與屬性中指定的類型匹配,則使用屬性中的屬性名稱,否則只使用原始屬性名稱。
以下是自定義屬性的外觀:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
class JsonPropertyNameByTypeAttribute : Attribute
{
public string PropertyName { get; set; }
public Type ObjectType { get; set; }
public JsonPropertyNameByTypeAttribute(string propertyName, Type objectType)
{
PropertyName = propertyName;
ObjectType = objectType;
}
}
這是轉換器的代碼:
public class DynamicPropertyNameConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
Type type = value.GetType();
JObject jo = new JObject();
foreach (PropertyInfo prop in type.GetProperties().Where(p => p.CanRead))
{
string propName = prop.Name;
object propValue = prop.GetValue(value, null);
JToken token = (propValue != null) ? JToken.FromObject(propValue, serializer) : JValue.CreateNull();
if (propValue != null && prop.PropertyType == typeof(object))
{
JsonPropertyNameByTypeAttribute att = prop.GetCustomAttributes<JsonPropertyNameByTypeAttribute>()
.FirstOrDefault(a => a.ObjectType.IsAssignableFrom(propValue.GetType()));
if (att != null)
propName = att.PropertyName;
}
jo.Add(propName, token);
}
jo.WriteTo(writer);
}
public override bool CanRead
{
get { return false; }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
// ReadJson is not called if CanRead returns false.
throw new NotImplementedException();
}
public override bool CanConvert(Type objectType)
{
// CanConvert is not called if a [JsonConverter] attribute is used
return false;
}
}
要使用轉換器,首先將[JsonConverter]
屬性添加到包含要動態命名的屬性(或多個屬性)的目標類。 然后,將自定義屬性添加到該類中的目標屬性(或屬性)。 您可以根據需要添加任意數量的屬性,以涵蓋您期望的類型范圍。
例如:
[JsonConverter(typeof(DynamicPropertyNameConverter))]
class Foo
{
public int Id { get; set; }
public string Name { get; set; }
[JsonPropertyNameByType("Vehicle", typeof(Vehicle))]
[JsonPropertyNameByType("Profile", typeof(Profile))]
public object Item { get; set; }
}
然后,像往常一樣序列化:
string json = JsonConvert.SerializeObject(foo, Formatting.Indented);
這是一個工作演示: https : //dotnetfiddle.net/75HwrV
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.