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

简介: 今天看了一下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服务编程上那句话是错误的,可能是我没有真正的理解那句话的真正含义,如果你知道这句话应该如何解释,麻烦你告诉我,谢谢。

 

我又回来了,回到了技术最前线,
相关文章
|
11月前
|
Serverless 开发工具
ABAP 方法调用的参数传递里,通过引用传递的方式,能修改原始参数值吗?
ABAP 方法调用的参数传递里,通过引用传递的方式,能修改原始参数值吗?
ABAP 方法调用的参数传递里,通过引用传递的方式,能修改原始参数值吗?
|
API C#
C#反射与特性(三):反射类型的成员
C#反射与特性(三):反射类型的成员
266 0
|
1月前
|
JavaScript 前端开发
理解包装对象类型
理解包装对象类型
18 0
|
11月前
|
弹性计算 JavaScript 开发工具
对象和接口-1:对象类型
本实验将介绍TypeScript中的对象类的基本语法
34 0
|
算法 Java 编译器
如何理解对象赋值给接口的操作(关键在对象!)
如何理解对象赋值给接口的操作(关键在对象!)
如何理解对象赋值给接口的操作(关键在对象!)
|
存储
ABAP方法的exporting类型参数,需要在方法实现最开始显式初始化么
ABAP方法的exporting类型参数,需要在方法实现最开始显式初始化么
205 0
ABAP方法的exporting类型参数,需要在方法实现最开始显式初始化么
|
Java
匿名内部类方式构建对象导致序列化失败
###问题描述: 以下代码为问题代码: ``` public class ItemDO implements Serializable { private static final long serialVersionUID=-463144769925355007L; ... private Map langAndTitleMap; ...
2350 0
|
C++
浅析C++的引用与const指针与各种传递方式
转自:https://www.jb51.net/article/120561.htm   首先我们知道 const int *p 与 int const *p 是一样的,即 *p 是常量; 而 int * const p 跟上面是不一样的,即 p 是常量; 我们知道引用只是一个别名,与变量共享存储空间,并且必须在定义的时候初始化,而且不能再成为别的变量的别名,这让我们想到什么呢,貌似跟  int * const p   的性质很像。
1169 0
抽象类的继承,接口的实现,接口类型数组的使用,根据instanceof判断(返回)是否该是哪一个类型,类型的强转.
总觉得之前第2处有点问题,果然. 还需要instanceof判定一下,然后还需要把数组Animal[]转为Pet的才有方法play()~~~!将编程看作是一门艺术,而不单单是个技术。 敲打的英文字符是我的黑白琴键, 思维图纸画出的是我编写的五线谱。
836 0