那些年,我们一起学WCF--(5)数据契约继承

         这一节探讨下关于数据契约继承的问题,关于数据契约的继承,主要包括以下几个方面

             1.数据契约继承

             2.KnowType的使用

             3.ServiceKnownType的使用

       接下下来我们一一了解

       1.数据契约的继承

           一个被声明为数据契约的类型,可以被另一个数据契约继承。子类的数据契约包含继承父类的所有数据契约。

        

 /// <summary>
    /// 水果
    /// </summary>
    [DataContract]
    public class Fruits
    {
        /// <summary>
        /// 名称
        /// </summary>
        [DataMember(IsRequired = true, Order = 0)]
        public string Name
        {
            get;
            set;
        }

        /// <summary>
        /// 颜色
        /// </summary>
         [DataMember(IsRequired = true, Order = 1)]
        public string Color
        {
            get;
            set;
        }
        /// <summary>
        /// 形状
        /// </summary>
         public string Shape
         {
             get;
             set;
         }
    }

    [DataContract]
    public class Apple:Fruits
    {
        /// <summary>
        /// 描述信息
        /// </summary>
        [DataMember]
        public string Des
        {
            get;
            set;
        }
    }

            上面的代码中,Apple契约继承了Fruits契约,也就是说Fruits契约里面的所有属性,在APPLE契约里面都可以使用。

           IsRequired属性表示当服务器端契约添加了新的属性,客户端没有更新契约版本的时候,如果IsRequired=true,就会报错,TRUE代表在通信过程中,此属性一定要被序列化才能进行通信,如果为FALSE,通信过程中不需要对此属性进行序列化,默认值为属性所在类型的默认值,字符串为空,整形为0.

           Order表示在序列化后,源数据在XSD文件中的排列顺序,值越小,在XSD文件中位置越靠前。

         接下来我们采用如下方式调用契约

    [ServiceContract]
    public interface IDataService
    {
        [OperationContract]
        Fruits GetFruits(Apple app);
    }

    

  public class DataService : IDataService
    {
 
        #region IDataService 成员


        public Fruits GetFruits(Apple app)
        {
            app.Name = app.Name + "one";
            app.Des = "收到IPHONE";
            return app;
        }

        #endregion
    }

  以上方法在编译的时候一切运行正常,但是如果客户端调用的时候,就会抛出异常,原因契约是面向服务的,不能像面向对象语言那样,直接可以将子类转换为父类。

如果需要在WCF中,可以将子类契约转换为父类契约,需要使用KnownType.

    2.KnownType用法
      在面向对象的语言中,可以使用多态,将子类转换为父类,但是WCF属于面向服务的设计架构,牺牲了面向对象的一些优点。由于客户端和服务端进行通信的时候,要进行

一系列的序列化和反序列化,所以不能使用多态,但是我们可以通过另一种方式来实现。使用KnownType标记继承当前类的所有子类,这样在使用的时候就可以使用多态

[KnownType(typeof(Apple))],也就是说,如果一个类被多个类继承,需要提前知道继承该类的所有子类。

       

 [KnownType(typeof(Apple))]
    public class Fruits
    {
        /// <summary>
        /// 名称
        /// </summary>
        [DataMember(IsRequired = true, Order = 0)]
        public string Name
        {
            get;
            set;
        }

        /// <summary>
        /// 颜色
        /// </summary>
         [DataMember(IsRequired = true, Order = 1)]
        public string Color
        {
            get;
            set;
        }
        /// <summary>
        /// 形状
        /// </summary>
         public string Shape
         {
             get;
             set;
         }
    }


这样,我们在客户端使用的时候,就不会抛出异常了

   客户端代码

        private void button2_Click(object sender, EventArgs e)
        {
            DaService.DataServiceClient client = new DaService.DataServiceClient();
            DaService.Apple app = new DaService.Apple();
            app.Name = "苹果";
            app.Des = "IPHONE5";
          DaService.Fruits fruits=client.GetFruits(app);
          MessageBox.Show(fruits.Name);
           
        }

  3.ServiceKnownType

    使用ServiceKnownType可以起到与KnownType一样的作用,但ServiceKnownType需要声明在服务契约上或者服务契约特定的操作上。声明在服务契约上,说着在整个服务契约范围内都有效,声明在操作契约上,只在当前操作契约方法内有效。ServiceKnownType与KnownType两者使用其一即可.

 [ServiceContract]
    [ServiceKnownType(typeof(Apple))]
    public interface IDataService
    {
        [OperationContract]
        Fruits GetFruits(Apple app);
    }



 DEMO:http://download.csdn.net/detail/zx13525079024/4583274

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果你希望通过 WCF 接收 `uni.uploadFile` 的数据,而不仅仅是文件,你可以按照以下步骤进行操作: 1. 在 WCF 服务的契约中,定义一个操作合同,用于接收文件数据。可以使用 `byte[]` 类型的参数来接收数据。例如: ```csharp [ServiceContract] public interface IFileService { [OperationContract] void UploadFileData(byte[] fileData); } ``` 2. 在服务实现类中,实现该操作合同,并将 `byte[]` 类型的参数用于处理数据。例如: ```csharp public class FileService : IFileService { public void UploadFileData(byte[] fileData) { // 处理文件数据 // 可以进行自定义操作,如保存到数据库、解析数据等 } } ``` 3. 在服务的配置文件中,配置绑定和终结点。可以使用基于 HTTP 的绑定,如 `basicHttpBinding` 或 `webHttpBinding`。例如: ```xml <system.serviceModel> <bindings> <basicHttpBinding> <binding name="BasicHttpBinding_IFileService" /> </basicHttpBinding> </bindings> <services> <service name="YourNamespace.FileService"> <endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IFileService" contract="YourNamespace.IFileService" /> </service> </services> </system.serviceModel> ``` 4. 在客户端调用代码中,引用服务契约并创建代理对象。然后,可以使用代理对象调用 `UploadFileData` 方法并传递数据。例如: ```csharp using (var client = new FileServiceClient()) { byte[] fileData = Encoding.UTF8.GetBytes("Your file data"); client.UploadFileData(fileData); } ``` 这样,你就可以在 WCF 中成功接收 `uni.uploadFile` 的数据。记得根据实际需求进行适当的异常处理和数据操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值