契约操作不能使用引用对象作为参数,只允许使用基本类型或数据契约

简介: 今天看了一下wcf服务编程这本书,本来准备大致的浏览一下,但是当我看到了契约操作不能使用引用对象作为参数,只允许使用基本类型或数据契约这句话的时候,我知道契约操作只能是通过数据契约进行数据的传递,但是我也是好奇在电脑上测试了一下,结果发现这句话存在问题,可能是我对这句话的理解不够,或者说这句话隐含着什么别的意思,我没有理解透,下面我们就一起来通过这句话来构建一个测试程序来测试一下这句话的正确性。

今天看了一下wcf服务编程这本书,本来准备大致的浏览一下,但是当我看到了契约操作不能使用引用对象作为参数,只允许使用基本类型或数据契约这句话的时候,我知道契约操作只能是通过数据契约进行数据的传递,但是我也是好奇在电脑上测试了一下,结果发现这句话存在问题,可能是我对这句话的理解不够,或者说这句话隐含着什么别的意思,我没有理解透,下面我们就一起来通过这句话来构建一个测试程序来测试一下这句话的正确性。

 

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.ServiceModel;
 6 using System.Runtime.Serialization;
 7 namespace Chinaer.WcfDemo.Contracts
 8 {
 9     public class BookInfo
10     {
11         public string Title { get; set; }
12 
13         public string Name { get; set; }
14     }
15 
16 
17     [ServiceContract( Namespace = "http://chinaer.com")]
18     public interface IBook
19     {
20         [OperationContract]
21         List<BookInfo> GetBooks(BookInfo info);
22 
23         [OperationContract]
24         void Check(string strMessage);
25     }
26 }

我们首先定义了一个服务契约IBook,然后定义了一个实体类BookInfo,定义了一个方法GetBooks,其中参数为BookInfo类型,我们之所以这样定义是因为契约操作不能使用引用对象作为参数,只允许使用基本类型或数据契约 这句话中不能使用引用对象,而我们使用了一个类的对象,属于引用对象的范畴。

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.ServiceModel;
 6 using Chinaer.WcfDemo.Contracts;
 7 namespace Chinaer.WcfDemo.Services
 8 {
 9     [ServiceBehavior()]
10     public class BookService : IBook
11     {
12         public List<BookInfo> GetBooks(BookInfo bookInfo)
13         {
14             List<BookInfo> listBooks = new List<BookInfo>();
15             for (int i = 0; i < 100; i++)
16             {
17                 BookInfo info = new BookInfo() { Title=i.ToString(), Name="name"+i.ToString() };
18                 listBooks.Add(info);
19             }
20             return listBooks;
21         }
22 
23         public void Check(string strMessage)
24         {
25             bool flag = false;
26             if (strMessage.Equals("guozhiqi", StringComparison.OrdinalIgnoreCase))
27             {
28                 flag = true;
29             }
30         }
31     }
32 }

在服务类中我们实现了契约的方法,这其中没有什么要介绍的。

下一步就是托管代码的实现。

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <configuration>
 3   <system.serviceModel>
 4     <services>
 5       <service name="Chinaer.WcfDemo.Services.BookService">
 6         <endpoint bindingConfiguration="securityMode" 
 7                   address="http://192.168.1.106:88/bookService" 
 8                   binding="wsHttpBinding"
 9                   contract="Chinaer.WcfDemo.Contracts.IBook"></endpoint>
10       </service>
11     </services>
12 
13     <bindings>
14       <wsHttpBinding>
15         <binding name="securityMode">
16           <security mode="None"></security>
17         </binding>
18       </wsHttpBinding>
19     </bindings>
20 
21     <behaviors></behaviors>
22     
23   </system.serviceModel>
24 
25 </configuration>
 1   using (ServiceHost guoHost = new ServiceHost(typeof(BookService)))
 2             {
 3 
 4                 // Chinaer.WcfDemo.Contracts.IGuo
 5                 if (guoHost.Description.Behaviors.Find<ServiceMetadataBehavior>() == null)
 6                 {
 7                     ServiceMetadataBehavior metaDataBehavior = new ServiceMetadataBehavior();
 8                     metaDataBehavior.HttpGetEnabled = true;
 9                     metaDataBehavior.HttpGetUrl = new Uri("http://192.168.1.106:883/mex");
10                     guoHost.Description.Behaviors.Add(metaDataBehavior);
11                 }
12                 guoHost.Opened += delegate { Console.WriteLine("bookService Open"); };
13                 try
14                 {
15                     if (guoHost.State != CommunicationState.Opened || guoHost.State != CommunicationState.Opening)
16                     {
17                         guoHost.Open();
18                         int i = 0;
19                         foreach (ChannelDispatcher channelDispatcher in guoHost.ChannelDispatchers)
20                         {
21                             Console.WriteLine("{0}:{1}", ++i, channelDispatcher.Listener.Uri);
22                         }
23                         Console.Read();
24                     }
25                 }
26                 catch (CommunicationException ex)
27                 {
28                     guoHost.Abort();
29                 }
30                 catch (Exception ex)
31                 {
32                     guoHost.Abort();
33                 }

在托管程序启动以后我们就需要在客户端通过终结点访问服务,请注意我们传递的参数类型为BookInfo的实例,并不是数据契约

下面是客户端实例,其实这种过程都是老一套,只不过是更改了属性或者说是要测试特定的知识点。

 1  //ServiceReference3.BookClient client = new ServiceReference3.BookClient();
 2             //BookInfo info = new BookInfo();
 3             //BookInfo[] arrinfo = client.GetBooks(info);
 4 
 5             using (ChannelFactory<IBook> chann = new ChannelFactory<IBook>("WSHttpBinding_IBook"))
 6             {
 7                 IBook book = chann.CreateChannel();
 8                 using (book as IDisposable)
 9                 {
10                     BookInfo[] arrInfo = book.GetBooks(new BookInfo());
11                     Console.Read();
12                 }
13 
14             }

 

这就说明刚才wcf服务编程上那句话是错误的,可能是我没有真正的理解那句话的真正含义,如果你知道这句话应该如何解释,麻烦你告诉我,谢谢。

 

我又回来了,回到了技术最前线,
相关文章
|
8月前
|
编译器 C++
【C++11特性篇】新的类功能解读:新增加的[移动构造函数/移动赋值运算符重载]
【C++11特性篇】新的类功能解读:新增加的[移动构造函数/移动赋值运算符重载]
|
3月前
|
Java
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性
本文深入探讨了Java中方法参数的传递机制,包括值传递和引用传递的区别,以及String类对象的不可变性。通过详细讲解和示例代码,帮助读者理解参数传递的内部原理,并掌握在实际编程中正确处理参数传递的方法。关键词:Java, 方法参数传递, 值传递, 引用传递, String不可变性。
81 1
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性
|
存储 算法 安全
04-📝C++核心语法|面向对象2【友元、内部类与局部类、强化训练(数组类封装)、运算符重载、仿函数、模板、类型转换、 C++标准、错误&&异常、智能指针】
复习`C++核心语法`,且适当进行汇编探索底层实现原理,进一步夯实基础,为以后的`底层开发`、`音视频开发`、`跨平台开发`、`算法`等方向的进一步学习埋下伏笔。
04-📝C++核心语法|面向对象2【友元、内部类与局部类、强化训练(数组类封装)、运算符重载、仿函数、模板、类型转换、 C++标准、错误&&异常、智能指针】
修饰类属性失败。请确保提案类属性已启用并设置为使用松散模式。要在规范模式下将提案类属性与修饰器一起使用,请在阶段 2 中等待下一个主要版本的装饰器。 #80
修饰类属性失败。请确保提案类属性已启用并设置为使用松散模式。要在规范模式下将提案类属性与修饰器一起使用,请在阶段 2 中等待下一个主要版本的装饰器。 #80
62 0
|
算法 Java 编译器
如何理解对象赋值给接口的操作(关键在对象!)
如何理解对象赋值给接口的操作(关键在对象!)
如何理解对象赋值给接口的操作(关键在对象!)
|
设计模式 前端开发 C#
C#开发中使用委托的作用和好处
先看概念,什么是委托? 从程序的角度来讲:你就可以把委托看成是用来执行方法(函数)的一个“指针” 通俗的说就是:通过委托,我们可以把方法当成参数传递。 这里我举个例子:“设想,如果我们写了一个厨师做菜的方法,里面有拿菜、切菜、配菜、炒菜四个步骤,但编写此方法代码的人想让配菜这个环节让调用方法的人来实现,换句话说,就是想把方法作为参数来传递,那么怎么来实现呢? 方法1:使用接口,这里不是我们讨论的。
7607 0
|
C++
C++两个类互相引用,如何处理最好
C++两个类互相引用,如何处理最好
287 0
|
Java
思想:java中,父类的方法中传入的形参的数据类型是泛型,子类的方法的形参想只要一种确定的数据类型,子类该如何做呢?
解决问题的思想: /* * 思想: * java中,父类的方法传入的形参的数据类型是泛型,子类的方法的形参想只要一种确定的数据类型,子类该如何做呢? *   答:那么子类可以重新写一个方法,形参传入的是一种想要的数据类型,而子类方法里面调用的还是父类的方法。
1265 0