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

简介: 今天看了一下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月前
|
存储
创建一个对象用什么运算符?对象实体与对象引用有何不同?
创建一个对象用什么运算符?对象实体与对象引用有何不同?
|
9月前
|
弹性计算 JavaScript 开发工具
对象和接口-1:对象类型
本实验将介绍TypeScript中的对象类的基本语法
31 0
|
算法 Java 编译器
如何理解对象赋值给接口的操作(关键在对象!)
如何理解对象赋值给接口的操作(关键在对象!)
如何理解对象赋值给接口的操作(关键在对象!)
|
JavaScript 前端开发
证明函数是对象的特殊子类型和函数的对象属性
证明函数是对象的特殊子类型和函数的对象属性
|
C++
C++两个类互相引用,如何处理最好
C++两个类互相引用,如何处理最好
220 0
|
JavaScript 前端开发 C++
cheerp数据类型包装
这个文章主要描述在cheerp环境下, js和c++侧数据类型的转换和包装内容。 1 基础数据类型 首先我们知道javascript是弱类型的脚本语言,开发者在开发的时候不必关注数据的类型和边界,而c++是静态编程语言, 在编译阶段就需要确定类型,在编译器处理的时候可以获得更好的优化。
1700 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   的性质很像。
1151 0
|
存储 关系型数据库 MySQL
Mysql存储过程无法传递、转换数组类型参数解决方案
mysql存储过程功能弱问题一直是大家关注的问题,今天讲一下Mysql存储过程无法传递数组类型参数的解决方案。 在很多的情况下,在编写存储过程中往往会用到数组,但是mysql中存储过程传入参数并没有可以直接传入数组的方法。
2692 0