zoukankan      html  css  js  c++  java
  • 解决WCF接口无法传递object参数的问题

      在某些场合中,我们需要提供以object为参数的方法。不过在WCF中,由于需要序列化与反序列化,因此它要求所有WCF传递的参数类型都是已知的,无法传递object这种未知类型。即使用了KnownType来标记自定义对象,也无法调用。以下代码无法正常执行:
        [DataContract]
        public class Product
        {
            [DataMember]
            public string Name;
        }

        [ServiceContract]
        public interface IProductInfo
        {
            [OperationContract]
            string GetProductTypeName(Object obj);
        }

        [KnownType(typeof(Product))]
        public class ProductInfo : IProductInfo
        {
             public string GetProductTypeName(Object obj)
             {
                   return obj.ToString();
             }
         }

          调用时:
          ProductInfoClient client = new ProductInfoClient ();
          client.GetProductTypeName("传字符串类型,调用成功");
          client.GetProductTypeName(new Product()); //报错

          不过,可以通过定义一个中间类型来传递object对象。方法就是在这个类型中包含一个object的成员,并且定义该成员为KnownType。代码如下:

        [DataContract]
        [KnownType(typeof(Product))] //必须标记Product类型
        public class RequestData
        {
            [DataMember]
            public object RequestObject;
        }

         通过传递RequestData,就能变相实现object对象的传递。

        [ServiceContract]
        public interface IProductInfo
        {
            [OperationContract]
            string GetProductTypeName(RequestData requestData);
        }

        public class ProductInfo : IProductInfo
        {
             public string GetProductTypeName(RequestData requestData)
             {
                   return requestData.RequestObject.ToString();
             }
         }

         不过,你会发现任何自定义对象都必须在RequestData中预先设定为KnownType,否则WCF无法序列化。这显然还不够灵活。为了让方法可以方便的调用,而不需要担心是否标记了KnownType,我们可以通过定义一个方法并把这个方法名作为KnownType参数来解决此问题。这里用到KnownType的另一个重载方法:
          KnownTypeAttribute(string methodName);
         这个方法必须满足以下条件:
         a 必须是static,因为需要在对象实例化之前调用。
         b 必须是不带任何参数的。
         C 返回类型必须是可被IEnumerable接受的,(也就是实现了IEnumerable接口的)。

         改造后RequestData如下:

         [DataContract]
        [KnownType("GetKnownType")]
        public class RequestData
        {
            //增加构造函数方便使用
            public RequestData(object requestObj)
            {
                     RequestObject = requestObj;
             }
            [DataMember]
            public object RequestObject;

            private static Type[] GetKnownType()
            {
                //将自定义对象的程序集下的所有类型标记为KnownType。
                return Assembly.Load("DataEntityAssemblyName").GetTypes();
            }
        }

        在GetKnownType函数中,程序将自定义类型的程序集包含的类型全部返回,这下就省事多了。。

  • 相关阅读:
    树莓派安装aria2轻松下载小资源
    利用树莓派3搭建可以发射无线局域网的微型服务器
    Vue语法
    redis-cluster集群
    分布式锁
    Redis--消息队列
    设计模式---享元模式
    设计模式(单例模式+原型模式)+ c#的内存分配机制
    MVC的ActionFilter
    MVC异常处理的7大场景 + MVC的异常处理的过滤器 + 全局异常
  • 原文地址:https://www.cnblogs.com/guanshan/p/guan041.html
Copyright © 2011-2022 走看看