您希望将
"Id"值从嵌套对象内部提升到父对象。为此,您需要将两个价值提供者链接在一起:
- 一个外部值提供者,用于获取成员的值。
- 一个内部值提供程序,用于获取
Id
成员的值。
以下是这样做的:
class NestedValueProvider : IValueProvider{ readonly IValueProvider outerProvider; readonly IValueProvider innerProvider; public NestedValueProvider(IValueProvider outerProvider, IValueProvider innerProvider) { if (outerProvider == null || innerProvider == null) throw new ArgumentNullException(); this.outerProvider = outerProvider; this.innerProvider = innerProvider; } public void SetValue(object target, object value) { throw new NotImplementedException(); } public object GetValue(object target) { var innerTarget = outerProvider.GetValue(target); if (innerTarget == null) return null; return innerProvider.GetValue(innerTarget); }}class CustomResolver : CamelCasePropertyNamesContractResolver{ // Using an inner resolver prevents difficulties with recursion. readonly CamelCasePropertyNamesContractResolver innerResolver = new CamelCasePropertyNamesContractResolver(); protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { var jsonProperty = base.CreateProperty(member, memberSerialization); if (!jsonProperty.PropertyType.IsPrimitive && jsonProperty.PropertyType != typeof(string) && jsonProperty.Readable) { var innerContract = innerResolver.ResolveContract(jsonProperty.PropertyType); if (innerContract is JsonObjectContract) { var objectContract = (JsonObjectContract)innerContract; var idProperty = objectContract.Properties.GetClosestMatchProperty(ResolvePropertyName("Id")); if (idProperty != null && idProperty.Readable && (innerResolver.ResolveContract(idProperty.PropertyType) is JsonPrimitiveContract)) { jsonProperty = new JsonProperty { PropertyName = ResolvePropertyName(member.Name + "Id"), Readable = true, PropertyType = idProperty.PropertyType, ValueProvider = new NestedValueProvider(jsonProperty.ValueProvider, idProperty.ValueProvider), }; } } // Possibly handle innerContract is JsonArrayContract? // Possibly handle innerContract is JsonDictionaryConract? } return jsonProperty; }}注意使用内部合同解析器。这样可以防止递归调用递归类型时出现问题。
您可能还需要考虑处理具有ID的对象的集合或具有ID的对象的字典。例如在以下对象中,
List<MyObject>and
Dictionary<string, MyObject>属性将公开以下内容
MyObject:
public class RootObject{ // Correctly not remapped public string StringValue { get; set; } // Correctly remaps to a GUID. public MyObject MyObject { get; set; } // Remap to a List<Guid> ? public List<MyObject> MyObjectList { get; set; } // Remap to a Dictionary<string, Guid> ? public Dictionary<string, MyObject> MyObjectDictionary { get; set; }}public class MyObject{ public Guid Id { get; set; } public string Property2 { get; set; }}


