gpt4 book ai didi

在每个请求问题中创建的 JSON ContractResolver

转载 作者:行者123 更新时间:2023-12-04 17:44:16 24 4
gpt4 key购买 nike

我有一个 .NET Core Web Api 2.1 应用程序,我在其中仅序列化客户端请求的属性。

示例:GET orders/1?select=Id,TotalAmount

示例:GET orders/1?select=Id,CustomerName,DeliveryAddress,Location,ZipCode

为此,应用程序在每个请求(生命周期范围)中创建一个对象以获取请求的属性。

然后,我创建了自定义 ContractResolver 类,它在每个请求中由全局 IResultFilter 实例化:

public class SerializationFilter : IResultFilter
{
private readonly IApiQueryParameters _apiQueryParameters;

public SerializationFilter(IApiQueryParameters apiQueryParameters)
{
this._apiQueryParameters = apiQueryParameters;
}

public void OnResultExecuting(ResultExecutingContext context)
{
var objectResult = context.Result as ObjectResult;

if (objectResult != null)
{
var contractResolver = new SelectiveResourceContractResolver(this._apiQueryParameters);
var serializerSettings = new JsonSerializerSettings
{
ContractResolver = contractResolver
};

var jsonFormatter = new JsonOutputFormatter(
serializerSettings,
ArrayPool<char>.Shared);

objectResult.Formatters.Add(jsonFormatter);
}
}
}

现在,这适用于应用在线后发出的第一个请求。第二个请求正确创建了 ContractResolver,但响应不正确。返回的序列化属性不是客户端请求的属性。

调试代码,我注意到在创建 SelectiveResourceContractResolver 时,它会正确访问构造方法,

    public SelectiveResourceContractResolver(IApiQueryParameters apiQueryParameters)
{
this._apiQueryParameters = apiQueryParameters;
}

此外,它还运行 CreateProperty 重写方法:

 protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)

但是在第二个请求中,CreatePropertyMethod 没有运行。

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);

property.ShouldSerialize =
instance =>
{
...
};

return property;
}

第二次,它只执行 property.ShouldSerialize = instance => 部分。我认为某种缓存是由应用程序完成的,但奇怪的是,当执行过滤器时,ContractResolver 是在每个请求中创建的(它没有在 Startup.cs 中全局设置)。此外,当我在第二个请求中调试它时,ContractResolver 中的属性 IApiQueryParameters 具有第一个请求的所有值,而不是构造函数第二次执行的值。

我在这里缺少什么?

最佳答案

我假设您的 SelectiveResourceContractResolver 继承自 DefaultContractResolver

DefaultContractResolver.ResolveContract,序列化时内部调用,caches contracts in a static, thread-safe dictionary ,因此只要您的 WebAPI 进程运行,CreateContract(进而调用 CreateProperty)将仅针对每种类型调用一次。

这是因为调用CreateContract 代价高昂,不缓存合约会严重影响序列化性能。

如果您只需要为每个响应缓存合约,您可以在 SelectiveResourceContractResolver 中创建自己的实例缓存并覆盖 ResolveContract 以使用您的缓存:

public class InstanceCachingContractResolver : DefaultContractResolver
{
private readonly Dictionary<Type, JsonContract> contractCache = new Dictionary<Type, JsonContract>();

public override JsonContract ResolveContract(Type type)
{
if (!contractCache.TryGetValue(type, out JsonContract contract))
{
contract = CreateContract(type);
contractCache.Add(type, contract);
}
return contract;
}
}

关于在每个请求问题中创建的 JSON ContractResolver,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52899139/

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