csh*_*irl 4 c# attributes json json.net
我有一个类型的属性,object我必须根据它的类型更改名称.应该与[XmlElement("PropertyName", typeof(PropertyType))]XML的属性非常相似
.
例如,我有一个属性 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;
}
}
Run Code Online (Sandbox Code Playgroud)
这是转换器的代码:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
要使用转换器,首先要向[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; }
}
Run Code Online (Sandbox Code Playgroud)
然后,像往常一样序列化:
string json = JsonConvert.SerializeObject(foo, Formatting.Indented);
Run Code Online (Sandbox Code Playgroud)
这是一个工作演示:https://dotnetfiddle.net/75HwrV
| 归档时间: |
|
| 查看次数: |
1555 次 |
| 最近记录: |