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

ASP.NET WebForms下无权限修改JSON.Net时如何自定义第三方类序列化规则

解决方案

可以通过Json.NET的全局扩展能力调整VendorClassA的序列化/反序列化逻辑,完全满足你提出的所有限制条件,不需要修改第三方代码、Session提供程序或者VendorClassA本身的代码。以下是按优先级排列的可落地方案:

方案1:自定义ContractResolver(最简方案)

Json.NET默认会将实现了IEnumerable接口的类型判定为集合类型,序列化为JSON数组,反序列化时无法映射回原类型。你可以通过自定义ContractResolver强制将VendorClassA按普通对象类型处理,代码如下:

public class IgnoreEnumerableContractResolver : DefaultContractResolver
{
    protected override JsonContract CreateContract(Type objectType)
    {
        // 针对VendorClassA强制生成对象契约,不走集合序列化逻辑
        if (objectType == typeof(VendorClassA))
        {
            return CreateObjectContract(objectType);
        }
        return base.CreateContract(objectType);
    }
}

在站点启动入口(Global.asax的Application_Start方法)注册全局生效的配置:

protected void Application_Start(object sender, EventArgs e)
{
    JsonConvert.DefaultSettings = () => new JsonSerializerSettings
    {
        ContractResolver = new IgnoreEnumerableContractResolver()
    };
}

这个方案不需要额外处理属性读写,Json.NET会自动按照普通对象的规则序列化/反序列化VendorClassA的所有公开成员,完全兼容现有存取逻辑。

方案2:全局注册自定义JsonConverter

如果VendorClassA有特殊的构造逻辑或者非公开成员需要序列化,可以自定义JsonConverter实现完全可控的序列化逻辑:

public class VendorClassAConverter : JsonConverter<VendorClassA>
{
    public override void WriteJson(JsonWriter writer, VendorClassA value, JsonSerializer serializer)
    {
        // 将实例的所有需要保留的属性序列化为JSON对象
        var jObj = new JObject();
        // 示例:序列化所有公开属性,可根据实际需要调整
        foreach (var prop in typeof(VendorClassA).GetProperties(BindingFlags.Public | BindingFlags.Instance))
        {
            if (prop.CanRead)
            {
                jObj[prop.Name] = JToken.FromObject(prop.GetValue(value), serializer);
            }
        }
        jObj.WriteTo(writer);
    }

    public override VendorClassA ReadJson(JsonReader reader, Type objectType, VendorClassA existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        var jObj = JObject.Load(reader);
        // 构造VendorClassA实例,无公开构造函数时可通过反射创建
        var instance = Activator.CreateInstance<VendorClassA>();
        // 给实例属性赋值
        foreach (var prop in typeof(VendorClassA).GetProperties(BindingFlags.Public | BindingFlags.Instance))
        {
            if (prop.CanWrite && jObj.TryGetValue(prop.Name, out var token))
            {
                prop.SetValue(instance, token.ToObject(prop.PropertyType, serializer));
            }
        }
        return instance;
    }
}

同样在Application_Start中注册:

JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
    Converters = { new VendorClassAConverter() }
};

方案3:动态给VendorClassA添加序列化特性(兼容强隔离场景)

如果自定义Session提供程序显式指定了JsonSerializerSettings,未使用全局DefaultSettings,可以通过.NET内置的TypeDescriptor机制动态给VendorClassA添加JsonConverter特性,无需修改类源码:

protected void Application_Start(object sender, EventArgs e)
{
    // 动态给VendorClassA添加JsonConverterAttribute
    TypeDescriptor.AddAttributes(typeof(VendorClassA), 
        new JsonConverterAttribute(typeof(VendorClassAConverter)));
}

Json.NET读取类型特性时会自动识别TypeDescriptor添加的动态特性,就算序列化逻辑未使用全局配置也能生效。

以上三种方案都满足所有限制条件:存取Session的对象始终是VendorClassA实例,第三方代码的强转逻辑完全不需要修改,不需要调整Session提供程序的任何代码。优先使用方案1,实现成本最低,兼容性最好。


内容的提问来源于stack exchange,提问作者Ann L.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 15:36:01