通過使用自定義轉換器,你將能夠實現你所需要的。
基於屬性的以下組件套件可能適合您的需求,並且在需要擴展它時非常通用。
基本屬性類
定義IsMatch
它允許您定義如果對象屬性的JSON屬性相匹配。
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)]
public abstract class JsonDeserializationPropertyMatchAttribute : Attribute
{
protected JsonDeserializationPropertyMatchAttribute() { }
public abstract bool IsMatch(JProperty jsonProperty);
}
樣品實施:多反序列化的名字
定義它可以讓你有相關的財產多個名稱的屬性。 IsMatch
實現簡單地遍歷它們並嘗試找到匹配。
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)]
public class JsonDeserializationNameAttribute : JsonDeserializationPropertyNameMatchAttribute
{
public string[] PropertyNames { get; private set; }
public JsonDeserializationNameAttribute(params string[] propertyNames)
{
this.PropertyNames = propertyNames;
}
public override bool IsMatch(JProperty jsonProperty)
{
return PropertyNames.Any(x => String.Equals(x, jsonProperty.Name, StringComparison.InvariantCultureIgnoreCase));
}
}
變換器以結合兩個屬性的JSON反序列化,需要以下轉換器:使用上述粘貼的代碼
public class JsonDeserializationPropertyMatchConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType.IsClass;
}
public override bool CanWrite
{
get
{
return false;
}
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var constructor = objectType.GetConstructor(new Type[0]);
if (constructor == null)
throw new JsonSerializationException("A parameterless constructor is expected.");
var value = constructor.Invoke(null);
var jsonObject = JObject.Load(reader);
var jsonObjectProperties = jsonObject.Properties();
PropertyInfo[] typeProperties = objectType.GetProperties();
var typePropertyTuples = new List<Tuple<PropertyInfo, Func<JProperty, bool>>>();
foreach (var property in typeProperties.Where(x => x.CanWrite))
{
var attribute = property.GetCustomAttribute<JsonDeserializationPropertyMatchAttribute>(true);
if (attribute != null)
typePropertyTuples.Add(new Tuple<PropertyInfo, Func<JProperty, bool>>(property, attribute.IsMatch));
else
typePropertyTuples.Add(new Tuple<PropertyInfo, Func<JProperty, bool>>(property, (x) => false));
}
foreach (JProperty jsonProperty in jsonObject.Properties())
{
var propertyTuple = typePropertyTuples.FirstOrDefault(x => String.Equals(jsonProperty.Name, x.Item1.Name, StringComparison.InvariantCultureIgnoreCase) || x.Item2(jsonProperty));
if (propertyTuple != null)
propertyTuple.Item1.SetValue(value, jsonProperty.Value.ToObject(propertyTuple.Item1.PropertyType, serializer));
}
return value;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
樣品,並且通過裝飾類作爲遵循,我設法得到的對象反序列化正確:
[JsonConverter(typeof(JsonDeserializationPropertyMatchConverter))]
public class Package
{
public string Carrier { get; set; }
[JsonDeserializationName("Tracking_Number","anotherName")]
public string TrackingNumber { get; set; }
}
輸出1
var input = "{ carrier: \"fedex\", trackingNumber: \"123123123\" }";
var output = JsonConvert.DeserializeObject<Package>(input); // output.TrackingNumber is "123123123"
輸出2
var input = "{ carrier: \"fedex\", tracking_Number: \"123123123\" }";
var output = JsonConvert.DeserializeObject<Package>(input); // output.TrackingNumber is "123123123"
輸出3
var input = "{ carrier: \"fedex\", anotherName: \"123123123\" }";
var output = JsonConvert.DeserializeObject<Package>(input); // output.TrackingNumber is "123123123"
[JsonProperty(屬性名= 「TRACKING_NUMBER」)] – Kalyan