gpt4 book ai didi

c# - Json.NET 自定义 ValueProvider 将 Objects 转换为 Guid

转载 作者:行者123 更新时间:2023-11-30 21:45:50 25 4
gpt4 key购买 nike

我正在尝试为 Json.NET 创建一个自定义 ValueProvider,它将跳过序列化所有对象,而只会返回一个 Guid 类型的属性来代替它们的主键(作为引用)。

例子:

jsonData: {
myObject: {
id: "23e23-2gg5-6y666556-y6yg33",
property2: ""
}
}

应该变成:

jsonData: {
myObjectId: "23e23-2gg5-6y666556-y6yg33"
}

这是我到目前为止编写的代码。我非常接近让它工作,但在我的 CustomValueProvider 中,我似乎无法获取对象值。我该怎么做?

    private class CustomValueProvider : IValueProvider
{
private readonly MemberInfo _member;

public CustomValueProvider(MemberInfo member)
{
_member = member;
}
public void SetValue(object target, object value)
{
throw new NotImplementedException();
}

public object GetValue(object target)
{
return // WHAT HERE??
}
}

private class CustomResolver : CamelCasePropertyNamesContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var jsonProperty = base.CreateProperty(member, memberSerialization);

if (jsonProperty.PropertyType.IsClass && jsonProperty.PropertyType != typeof(string))
{
jsonProperty = new JsonProperty
{
PropertyName = member.Name.ToFirstCharLower() + "Id",
Readable = true,
ShouldSerialize = value => true,
PropertyType = typeof(Guid),
ValueProvider = new CustomValueProvider(member)
};
}

return jsonProperty;
}
}

private static readonly JsonSerializerSettings JsonSettings = new JsonSerializerSettings
{
ContractResolver = new CustomResolver(),
Formatting = Formatting.Indented
};

最佳答案

您想宣传 "Id"从嵌套对象内部到父对象的值。为此,您需要将两个值(value)提供者链接在一起:

  • 获取成员值(value)的外部值(value)提供者。
  • 获取 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>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; }
}

关于c# - Json.NET 自定义 ValueProvider 将 Objects 转换为 Guid,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39816736/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com