zoukankan      html  css  js  c++  java
  • XmlIncludeAttribute 与 KnownTypeAttribute

    为了实现一个通用的WCF服务调用的Recovery机制,我们定义了下面的实体类,用以表现当初调用服务时的信息,包括服务信息和调用参数。

        public class ServiceInvoikeRecoveryData
    {
    public string Key { get; set; }

    public string ServiceAssembly { get; set; }

    public string ServiceType { get; set; }

    public string Operation { get; set; }

    public object[] Parameters { get; set; }

    public string ExceptionMessage { get; set; }

    public int FailedCount { get; set; }
    }

    由于我们是做一个通用的WCF服务调用的Recovery机制,因此调用参数只能定义成object[] Parameters,然而这样带来的一个问题就是如果Parameters中的对象有一个不是.NET 原生类型的话在序列化的时候就会出错。因为我们不知道object[] P

    arameters里面会存什么类型的Object,所以在序列化的时候如果遇到未知的类型序列化器就会报错。

    这种情况下我们有两种解决方案,一种是静态的解决方案,通过为类型添加XmlIncludeAttribute的方式来告知序列化器可能的类型有哪些;另一种是在创建XmlSerializer的时候可以告诉序列化器可能的类型有哪些。
       方案一:

        [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Method | AttributeTargets.Struct | AttributeTargets.Class, AllowMultiple = true)]
    public class XmlIncludeAttribute : Attribute
        [XmlInclude(typeof(OrderData))]
    public class ServiceInvoikeRecoveryData
    {
    public string Key { get; set; }

    public string ServiceAssembly { get; set; }

    public string ServiceType { get; set; }

    public string Operation { get; set; }

    public object[] Parameters { get; set; }

    public string ExceptionMessage { get; set; }

    public int FailedCount { get; set; }
    }

     方案二:

    public XmlSerializer(Type type, Type[] extraTypes)
    XmlSerializer serializer = new XmlSerializer(typeof(ServiceInvoikeRecoveryData),new Type[]{typeof(OrderData)});

    以上只是说了使用XmlSerializer方式的解决方案,其实使用DataContractSerializer也有同样的问题和类似的解决方案:
     方案一:

        [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
    public sealed class KnownTypeAttribute : Attribute
    {
    }
        [KnownType(typeof(OrderData))]
    [DataContract]
    public class ServiceInvoikeRecoveryData
    {
    [DataMember]
    public string Key { get; set; }

    [DataMember]
    public string ServiceAssembly { get; set; }

    [DataMember]
    public string ServiceType { get; set; }

    [DataMember]
    public string Operation { get; set; }

    [DataMember]
    public object[] Parameters { get; set; }

    [DataMember]
    public string ExceptionMessage { get; set; }

    [DataMember]
    public int FailedCount { get; set; }
    }

     方案二:

    public DataContractSerializer(Type type, IEnumerable<Type> knownTypes);
    DataContractSerializer serializer = new DataContractSerializer(typeof(ServiceInvoikeRecoveryData), new Type[] { typeof(OrderData) });

     

  • 相关阅读:
    Soap 教程
    MAC mysql install
    PHP date
    MAC 终端terminal颜色
    MAC 终端颜色设置
    MAC brew软件安装
    PHP iconv函数
    Java----前端验证之验证码额实现
    Java---Ajax在Struts2框架的应用实例
    Java基础—标识符及命名规范
  • 原文地址:https://www.cnblogs.com/zanxiaofeng/p/2075501.html
Copyright © 2011-2022 走看看