You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

重置Json.NET契约缓存:自定义解析器动态属性更新失效问题

Fixing Json.NET Contract Cache Issues When Custom Properties Change

Hey there, I've run into this exact problem before—Json.NET's contract caching is great for performance, but it's a real pain when your dynamic property configurations change mid-app lifecycle. Let's break down how to fix this:

Option 1: Clear the Built-in Cache (Quick Fix)

The DefaultContractResolver stores generated contracts in a private _contractCache dictionary. Since it's private, we'll need reflection to wipe it clean:

// Grab your custom resolver instance (make sure this is the same one used in your serialization setup!)
var customResolver = new YourCustomContractResolver();

// Use reflection to access the private cache field
var contractCacheField = typeof(DefaultContractResolver)
    .GetField("_contractCache", BindingFlags.Instance | BindingFlags.NonPublic);

if (contractCacheField != null)
{
    var cache = contractCacheField.GetValue(customResolver) as IDictionary;
    cache?.Clear();
}

After running this, the next time Json.NET needs to resolve a contract for your type, it'll re-run your CreateObjectContract method with the updated property list.

Option 2: Build a Cacheable Resolver (Long-Term Solution)

If you're regularly updating property configurations, it's better to take control of the cache yourself instead of relying on Json.NET's internal implementation. Here's how to create a resolver with a public reset method:

public class DynamicContractResolver : DefaultContractResolver
{
    // Our own cache dictionary we can fully control
    private readonly Dictionary<Type, JsonContract> _customContractCache = new();

    protected override JsonContract ResolveContract(Type type)
    {
        // Check our custom cache first
        if (_customContractCache.TryGetValue(type, out var existingContract))
        {
            return existingContract;
        }

        // Generate and cache a new contract if needed
        var newContract = base.ResolveContract(type);
        _customContractCache[type] = newContract;
        return newContract;
    }

    // Public method to reset the cache whenever your properties change
    public void ResetContractCache()
    {
        _customContractCache.Clear();
    }

    protected override JsonObjectContract CreateObjectContract(Type objectType)
    {
        var contract = base.CreateObjectContract(objectType);
        AddSomeMorePropertiesToContract(contract, objectType);
        return contract;
    }

    private void AddSomeMorePropertiesToContract(JsonObjectContract contract, Type objectType)
    {
        // Your logic to add/remove dynamic properties here
    }
}

Now whenever your property list changes, just call dynamicResolver.ResetContractCache()—no reflection hacks needed, and you're insulated from future Json.NET internal changes.

Quick Notes

  • If you're using a global resolver via JsonConvert.DefaultSettings, make sure you're referencing the same instance when resetting the cache (don't create a new one!).
  • The reflection approach works but is fragile—it depends on Json.NET's internal field names. Stick with the custom cache approach for production code.

内容的提问来源于stack exchange,提问作者Alwin S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:17:47