栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

SignalR类型名称处理

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SignalR类型名称处理

这可以通过利用您的类型和SignalR类型在不同的程序集中的事实来完成。这个想法是要创建一个

JsonConverter
适用于
程序集中所有类型的 。当在对象图中(可能是根对象)首先遇到某个程序集中
jsonSerializer.TypeNameHandling =TypeNameHandling.Auto
的类型时,转换器将临时设置,然后对该类型进行标准序列化,并在一段时间内禁用自身以防止无限递归:

public class PolymorphicAssemblyRootConverter : JsonConverter{    [ThreadStatic]    static bool disabled;    // Disables the converter in a thread-safe manner.    bool Disabled { get { return disabled; } set { disabled = value; } }    public override bool CanWrite { get { return !Disabled; } }    public override bool CanRead { get { return !Disabled; } }    readonly HashSet<Assembly> assemblies;    public PolymorphicAssemblyRootConverter(IEnumerable<Assembly> assemblies)    {        if (assemblies == null) throw new ArgumentNullException();        this.assemblies = new HashSet<Assembly>(assemblies);    }    public override bool CanConvert(Type objectType)    {        return assemblies.Contains(objectType.Assembly);    }    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)    {        using (new PushValue<bool>(true, () => Disabled, val => Disabled = val)) // Prevent infinite recursion of converters        using (new PushValue<TypeNameHandling>(TypeNameHandling.Auto, () => serializer.TypeNameHandling, val => serializer.TypeNameHandling = val))        { return serializer.Deserialize(reader, objectType);        }    }    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)    {        using (new PushValue<bool>(true, () => Disabled, val => Disabled = val)) // Prevent infinite recursion of converters        using (new PushValue<TypeNameHandling>(TypeNameHandling.Auto, () => serializer.TypeNameHandling, val => serializer.TypeNameHandling = val))        { // Force the $type to be written unconditionally by passing typeof(object) as the type being serialized. serializer.Serialize(writer, value, typeof(object));        }    }}public struct PushValue<T> : IDisposable{    Action<T> setValue;    T oldValue;    public PushValue(T value, Func<T> getValue, Action<T> setValue)    {        if (getValue == null || setValue == null) throw new ArgumentNullException();        this.setValue = setValue;        this.oldValue = getValue();        setValue(value);    }    #region IDisposable Members    // By using a disposable struct we avoid the overhead of allocating and freeing an instance of a finalizable class.    public void Dispose()    {        if (setValue != null) setValue(oldValue);    }    #endregion}

然后在启动时,将此转换器添加到默认转换器中

JsonSerializer
,传入要
"$type"
应用的程序集。

更新资料

如果出于某种原因在启动时不方便传递程序集列表,则可以通过启用转换器

objectType.Namespace
。居住在指定名称空间中的所有类型都将自动使用序列化
TypeNameHandling.Auto

或者,您可以引入

Attribute
其目标的组件,类或接口,使
TypeNameHandling.Auto
当与适当的转换器结合使用:

public class EnableJsonTypeNameHandlingConverter : JsonConverter{    [ThreadStatic]    static bool disabled;    // Disables the converter in a thread-safe manner.    bool Disabled { get { return disabled; } set { disabled = value; } }    public override bool CanWrite { get { return !Disabled; } }    public override bool CanRead { get { return !Disabled; } }    public override bool CanConvert(Type objectType)    {        if (Disabled) return false;        if (objectType.Assembly.GetCustomAttributes<EnableJsonTypeNameHandlingAttribute>().Any()) return true;        if (objectType.GetCustomAttributes<EnableJsonTypeNameHandlingAttribute>(true).Any()) return true;        foreach (var type in objectType.GetInterfaces()) if (type.GetCustomAttributes<EnableJsonTypeNameHandlingAttribute>(true).Any())     return true;        return false;    }    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)    {        using (new PushValue<bool>(true, () => Disabled, val => Disabled = val)) // Prevent infinite recursion of converters        using (new PushValue<TypeNameHandling>(TypeNameHandling.Auto, () => serializer.TypeNameHandling, val => serializer.TypeNameHandling = val))        { return serializer.Deserialize(reader, objectType);        }    }    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)    {        using (new PushValue<bool>(true, () => Disabled, val => Disabled = val)) // Prevent infinite recursion of converters        using (new PushValue<TypeNameHandling>(TypeNameHandling.Auto, () => serializer.TypeNameHandling, val => serializer.TypeNameHandling = val))        { // Force the $type to be written unconditionally by passing typeof(object) as the type being serialized. serializer.Serialize(writer, value, typeof(object));        }    }}[System.AttributeUsage(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Interface)]public class EnableJsonTypeNameHandlingAttribute : System.Attribute{    public EnableJsonTypeNameHandlingAttribute()    {    }}

注意-已通过各种测试用例进行了测试,但未对SignalR本身进行过测试,因为我目前尚未安装它。

TypeNameHandling
警告

使用时

TypeNameHandling
,请注意Newtonsoft文档中的这一警告:

当您的应用程序从外部源反序列化JSON时,应谨慎使用TypeNameHandling。反序列化除None以外的其他值时,应使用自定义SerializationBinder验证传入的类型。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/485404.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号