博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
解决WCF接口无法传递object参数的问题
阅读量:5124 次
发布时间:2019-06-13

本文共 1873 字,大约阅读时间需要 6 分钟。

  在某些场合中,我们需要提供以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函数中,程序将自定义类型的程序集包含的类型全部返回,这下就省事多了。。

转载于:https://www.cnblogs.com/guanshan/p/guan041.html

你可能感兴趣的文章
这周工作
查看>>
HDU2602Bone Collector 简单0-1背包
查看>>
【贪心】赶作业
查看>>
分布模式
查看>>
currentTitle的用法
查看>>
poj1703_Find them, Catch them_并查集
查看>>
centos 6.5 安装redis
查看>>
WEB_头等舱
查看>>
第九周 10.25-10.31
查看>>
Activity的四种加载模式(转载)
查看>>
【转载】MongoDB 1000W级数据 Insert和Query和Delete性能测试
查看>>
SSM项目中整合WebService
查看>>
SQL批量提交修改业务
查看>>
谈谈我对Javascript中This对象的理解
查看>>
(专题二)01 矩阵的处理-特殊矩阵
查看>>
Tomcat项目部署过程中的问题
查看>>
Unreal4(虚幻4抽茧剥丝)——02章格式化C++和蓝图
查看>>
移动端弹出层加遮罩后禁止滑动
查看>>
C# VS2017 winForm 使tableLayoutPanel 不闪烁
查看>>
执行异常ORA-00918: column ambiguously defined
查看>>