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函数中,程序将自定义类型的程序集包含的类型全部返回,这下就省事多了。。

  • 相关阅读:
    jcaptcha验证码使用(二)
    jcaptcha验证码使用(一)
    CentOS7 常用命令集合
    VM虚拟机下安装Centos7.0图文教程
    CentOS 6.5远程连接工具x shell
    Mogodb 存储DateTime问题
    RabbitMQ安装教程
    Redis 安装
    Linux平台安装MongoDB
    Windows 平台安装 MongoDB
  • 原文地址:https://www.cnblogs.com/guanshan/p/guan041.html
Copyright © 2011-2022 走看看