2017手机qq全透明主题2017主题透明到桌面怎么弄

 上传我的文档
 下载
 收藏
该文档贡献者很忙,什么也没留下。
 下载此文档
正在努力加载中...
下载积分:3000
内容提示:WCF笔记
文档格式:DOCX|
浏览次数:1|
上传日期: 14:56:44|
文档星级:
该用户还上传了这些文档
官方公共微信  使用WCF发布的Web服务可以被各种技术平台远程调用,关键就是WCF发布了符合业界标准的WSDL(Web Service Description Language),各种技术平时使用各自的工具将这种WSDL解释成自身所能接受的编程对象,让后对其进行服务调用。本系列文章旨在学习控制WCF生成WSDL。
  为了实验之用,我首先写了一个很简单的WCF应用程序,同样由契约类库、服务实现类库、服务宿主程序、客户端程序组成。(项目文件在下载区,文章中只贴出关键代码)
以下是服务契约的定义:
namespace WCF_Study3.Contracts{[ServiceContract]public interface IContract{[OperationContract]void NoArgsOperation();[OperationContract]void OneArgOperation(int arg1);[OperationContract]void TwoArgOperation(int arg1, string arg2);[OperationContract]void MultiArgsOperation(params double[] args);[OperationContract]object OperationWithReturnArg(object argObj1);}}
契约中定义的方法签名都是一些比较典型的例子,不过在这里没有涉及以自定义类型为参数或返回值的方法签名,因为我还不想马上就要进行数据契约的内容。注意到我在以上的例子中没有添加任何附加的WSDL元数据(例如Name、Namespace等等),这些元数据在后面加入,我觉得这样可以更加清晰地看出这些元数据在WCF中被加入后,如何反映到WSDL。我对这个服务契约的实现非常简单(几乎跟没实现一样。。),因此就不发出来了,同样,部署服务宿主的代码暂时与本文主题无关,因此也不发了,如果想要知道怎么部署服务细节,请参考我的其他文章。以下就是这个服务契约生成的部分WSDL(顺带一句,本人愚钝,想了快10分钟才知道怎么可以看到WSDL的内容,因此在这里分享一下,就是在浏览器中输入发布元数据的URL。。):
&wsdl:portType name="IContract"&&wsdl:operation name="NoArgsOperation"&&wsdl:input wsaw:Action=""
message="tns:IContract_NoArgsOperation_InputMessage"/&&wsdl:output wsaw:Action=""
message="tns:IContract_NoArgsOperation_OutputMessage"/&&/wsdl:operation&&wsdl:operation name="OneArgOperation"&&wsdl:input wsaw:Action=""
message="tns:IContract_OneArgOperation_InputMessage"/&&wsdl:output wsaw:Action=""
message="tns:IContract_OneArgOperation_OutputMessage"/&&/wsdl:operation&&wsdl:operation name="TwoArgOperation"&&wsdl:input wsaw:Action=""
message="tns:IContract_TwoArgOperation_InputMessage"/&&wsdl:output wsaw:Action=""
message="tns:IContract_TwoArgOperation_OutputMessage"/&&/wsdl:operation&&wsdl:operation name="MultiArgsOperation"&&wsdl:input wsaw:Action=""
message="tns:IContract_MultiArgsOperation_InputMessage"/&&wsdl:output wsaw:Action=""
message="tns:IContract_MultiArgsOperation_OutputMessage"/&&/wsdl:operation&&wsdl:operation name="OperationWithReturnArg"&&wsdl:input wsaw:Action=""
message="tns:IContract_OperationWithReturnArg_InputMessage"/&&wsdl:output wsaw:Action=""
message="tns:IContract_OperationWithReturnArg_OutputMessage"/&&/wsdl:operation&&/wsdl:portType&
这就是全部定义了吗?它甚至连每个服务操作的签名信息都不齐全呢,很明显这不是全部的内容,更多细节的WSDL马上就发出来,但在此之前,首先看下这部分的WSDL有什么有趣的地方也好。
  1.最外层的节点&wsdl:portType&,在上面的WSDL中,它只有一个属性name被设置为"IContract&,没错,这个节点就是代表这我所发布的服务契约,而它的name属性被默认的设置为接口的直接名称(而不是连同命名空间的完整名称)。
  2.在portType节点内部的5个&wsdl:operation&节点,很明显,它们的name属性的值,就告知所有人,它们代表着我在服务契约中定义的5个被公开做服务操作的方法。&
  3.在operation节点里面的&wsdl:input&和&wsdl:output&节点。在WSDL中,这两个节点的顺序就可以代表着一种消息交换模式(Message Exchange Pattern MEP),例如这里使用的是一个input,一个output的标准请求-响应模式。这个定义就意味着,当调用这个服务操作的时候,会首先从客户端发送一个"input"消息;操作结束后服务端会生成一个"output"消息,并返回到客户端,往后还会看到其他的MEP,但它们都是利用这些input、output节点的定义来说明的。
  4.无论是input还是output节点,都设置了Action属性,这个属性很重要,它代表了调用服务过程中,往来的消息(可能从Server到Client,也可能相反)各自代表了怎么样的&动作&。例如OperationWithReturnArg这个操作,当一个发送到服务端的消息的首部设置有Action=""的时候,WCF知道如果把该消息分发到相应的服务操作中,这也就说明了,这个Action首部可以被用于消息筛选。而作为响应的消息,它的Action首部的值被默认设置为:请求消息的Action首部值 + "Response"。
  同样在input和output节点中,均有一个message属性,被设置为:"tns:&portType名称&_&operation名称&_&(Input/Ouput)Message&",这是什么呢?这就是对定义这些操作的细节的XML Schema的引用。接下来就发出这些XML Schema的内容:(为了避免太难看,我以操作为单位,逐个发出它们的XML Schema代码段,but keep it in mind,这些代码是在同一份XML Schema文件中的。)
&& 首先是NoArgsOperation,它的XML Schema代码是最简单的,因为没有返回值,也没有参数:
[OperationContract]void NoArgsOperation();
&xs:element name="NoArgsOperation"&&xs:complexType&&xs:sequence/&&/xs:complexType&&/xs:element&&xs:element name="NoArgsOperationResponse"&&xs:complexType&&xs:sequence/&&/xs:complexType&&/xs:element&
这段XML代码中,定义了两个&xs:element&节点,从它们的name属性马上就可以推断出,它们是对应操作NoArgsOperation的一种XML自定义元素(我先把它们分别称作负载元素)。这两个负载元素中没有任何有趣的内容,因为这个操作本来就没有返回值和参数。
  接下来看一下为OneArgOperation操作所定义的XML元素:
[OperationContract]void OneArgOperation(int arg1);
&xs:element name="OneArgOperation"&&xs:complexType&&xs:sequence&&xs:element minOccurs="0" name="arg1" type="xs:int"/&&/xs:sequence&&/xs:complexType&&/xs:element&&xs:element name="OneArgOperationResponse"&&xs:complexType&&xs:sequence/&&/xs:complexType&&/xs:element&
这个操作只有一个参数,同样没有返回值。在代表请求负载的负载元素中的&xs:sequence&孙节点中(因为中间还有个&xs:complexType)子节点),又出现了一个XML自定义元素(这个我称作参数元素),参数元素有三个属性&&minOccurs、name、type,回顾一下前面的服务契约C#代码,就会知道,这三个属性都是对操作方法中参数的描述,分别是:请求消息中,代表该参数的XML节点至少出现多少个、该参数的名称(很明显默认是使用了程序代码中的名称arg1)、该参数的类型。这里有一个很奇怪的地方,那就是允许参数最少出现的次数为0,而事实上这个参数是必须要提供的,在生成的客户端代理中,也必须提供这个参数。
  接下来是两个参数的操作TwoArgOperation对应的消息元素定义:
[OperationContract]void TwoArgOperation(int arg1, string arg2);
&xs:element name="TwoArgOperation"&&xs:complexType&&xs:sequence&&xs:element minOccurs="0" name="arg1" type="xs:int"/&&xs:element minOccurs="0" name="arg2" nillable="true" type="xs:string"/&&/xs:sequence&&/xs:complexType&&/xs:element&&xs:element name="TwoArgOperationResponse"&&xs:complexType&&xs:sequence/&&/xs:complexType&&/xs:element&
从该操作的负载元素定义可以看出,&xs:sequence&节点所包含的就是负载携带的参数的列表。这个操作中,arg2的CLR类型为string,由于默认可以为null,因此设置了参数元素的nillable属性为true。这个操作在响应消息元素中同样没有什么有趣的地方。
  下面是MultiArgsOperation操作的消息元素定义:
[OperationContract]void MultiArgsOperation(params double[] args);
&xs:element name="MultiArgsOperation"&&xs:complexType&&xs:sequence&&xs:element minOccurs="0"
          name="args"
nillable="true"
type="q1:ArrayOfdouble"
xmlns:q1="/2003/10/Serialization/Arrays"/&&/xs:sequence&&/xs:complexType&&/xs:element&&xs:element name="MultiArgsOperationResponse"&&xs:complexType&&xs:sequence/&&/xs:complexType&&/xs:element&
在服务契约的C#代码中,我使用了C#的params关键字来定义该操作的参数可以为任意多个double类型的值。其实最后这个可变长参数只是作为一个数组来使用(或者说它其实就是一个数组),当然这在元数据中需要特殊对待,但在编程的时候真的使用一个数组参数没什么区别。因此,在XML中定义的负载元素,也是把该参数元素的类型定义为一个"ArrayOfdouble",这个名字很奇怪,很明显,它不是微软提供的XML预定义数据类型,那这样就必定在某处WSDL中存在这个XML数据类型的定义。关于这个内容,在后面再研究。
  继续看下一个操作&&OperationWithReturnArg:
[OperationContract]object OperationWithReturnArg(object argObj1);
&xs:element name="OperationWithReturnArg"&&xs:complexType&&xs:sequence&&xs:element minOccurs="0"
            name="argObj1"
nillable="true"
type="xs:anyType"/&&/xs:sequence&&/xs:complexType&&/xs:element&&xs:element name="OperationWithReturnArgResponse"&&xs:complexType&&xs:sequence&&xs:element minOccurs="0"
name="OperationWithReturnArgResult"
nillable="true"
type="xs:anyType"/&&/xs:sequence&&/xs:complexType&&/xs:element&
这个操作是具有一个参数和CLR的object类型返回值的,参数已经没有什么值得研究的地方,看下该操作的响应负载元素的定义,所携带的参数的类型为xs:anyType,在CLR中,object类型是一切类型的基类,任何类型(值类型或引用类型)的对象都可以安全转换为object类型来处理,因此在XML标准数据类型中,可以使用这个anyType来代表object类型的数据。 
  值得一提的是,服务操作的返回值的定义方式,跟之前看到的操作参数定义方式完全一样。前面已经提到,WSDL标准中,使用input、output两个XML元素来表示一个服务操作的MEP,所以尽管我在服务契约的C#代码中只是定义了一个方法,它具有参数和返回值,但参数跟返回值只是程序语言上的概念;当我为服务操作定义的MEP是请求-响应模式时,在WSDL中就已经把这个单一的方法分解成两个消息传输模式(一个input,一个output),无论是哪个消息传输模式,它所代表的都是消息的传输,而对于消息来说,没有所谓的返回值,只有携带的参数。因此在服务操作对应的负载元素(请求消息负载和响应消息负载)定义中,操作中的参数和返回值都是以一致的方式被定义,因为它们都只是消息所携带的参数(内容)。
  还记得刚才的"ArrayOfdouble" ,现在来研究下这个数据类型到底怎么出来的。相信有XML基础的读者都知道,XML具有高扩展性,可以自定义各种标记和XML数据类型,而通常由XML Schema来描述XML文件中各种标记或XML数据类型的细节。那么在所生成WSDL中,在哪里引用外部的(或者生成的)XML Schema呢?先看下下面的WSDL代码:
&wsdl:types&&xsd:schema targetNamespace="http://tempuri.org/Imports"&&xsd:import schemaLocation="http://localhost:8090/mex?xsd=xsd0" namespace="http://tempuri.org/"/&&xsd:import schemaLocation="http://localhost:8090/mex?xsd=xsd1" namespace="/2003/10/Serialization/"/&&xsd:import schemaLocation="http://localhost:8090/mex?xsd=xsd2" namespace="/2003/10/Serialization/Arrays"/&&/xsd:schema&&/wsdl:types&
在&wsdl:types&节点中定义了所有该WSDL所引用的XML Schema,其中包括根据服务契约生成的XML Schema(上面代码中的第一个&xsd:import&)和微软预定义的XML Schema(上面代码中的后两个&xsd:import&)。同时这个被定义的XML Schema通过targetNamespace属性,被导入到命名空间中。命名空间为的XML Schema文件其实就是定义之前所有负载元素的文件,里面根据每个服务操作的MEP,定义所需的负载元素。而第二个&xsd:import&所导入的XML Schema就是微软定义的一些基础XML数据类型。而最后一个&xsd:import&所导入的XML Schema就是"ArrayOfdouble"的定义,下面发出其代码:
&?xml version="1.0" encoding="utf-8"?&&xs:schema elementFormDefault="qualified"
      targetNamespace=
      xmlns:xs=
      xmlns:tns="/2003/10/Serialization/Arrays"&&xs:complexType name="ArrayOfdouble"&&xs:sequence&&xs:element minOccurs="0" maxOccurs="unbounded" name="double" type="xs:double"/&&/xs:sequence&&/xs:complexType&&xs:element name="ArrayOfdouble" nillable="true" type="tns:ArrayOfdouble"/&&/xs:schema&
一个值得注意的地方是,这个XML Schema定义了"ArrayOfdouble"后,是把它的定义放入到中,而不是本服务的命名空间中(例如)。
  前面说过,WCF自动为每个服务操作生成对应的负载元素,那在WSDL中是怎么把服务操作元素&wsdl:operation&与负载元素&xs:element&关联起来呢?答案是通过&wsdl:message&元素。以MultiArgsOperation为例:
&wsdl:operation name="MultiArgsOperation"&&wsdl:input wsaw:Action=
           message="tns:IContract_MultiArgsOperation_InputMessage"/&&wsdl:output wsaw:Action=
           message="tns:IContract_MultiArgsOperation_OutputMessage"/&&/wsdl:operation&&wsdl:message name="IContract_MultiArgsOperation_InputMessage"&&wsdl:part name="parameters" element="tns:MultiArgsOperation"/&&/wsdl:message&&wsdl:message name="IContract_MultiArgsOperation_OutputMessage"&&wsdl:part name="parameters" element="tns:MultiArgsOperationResponse"/&&/wsdl:message&&xs:element name="MultiArgsOperation"&&xs:complexType&&xs:sequence&&xs:element minOccurs="0"
name="args"
nillable="true"
type="q1:ArrayOfdouble"
xmlns:q1="/2003/10/Serialization/Arrays"/&&/xs:sequence&&/xs:complexType&&/xs:element&&xs:element name="MultiArgsOperationResponse"&&xs:complexType&&xs:sequence/&&/xs:complexType&&/xs:element&
从上面的WSDL代码,简单总结就是:服务操作定义了消息的输入管道元素、输出管道元素及其顺序;每个输入/输出管道元素引用了一个消息元素;每个消息元素包装着它的负载元素。
  这篇文章还没有提及对各种契约进行元数据配置的情况,还记得我用的服务契约(包括其操作契约)是完全没有经过定制配置的。下一篇文章将尝试进行一些定制配置,然后研究一下WSDL会有什么相应的变化。
阅读(...) 评论()WCF - 只读属性
WCF - 只读属性
  在设计数据实体(Entity)时,某些属性必须是只读的,比如 CreateTime、LastLogonTime 等。但 DataContract 并不允许我们这么做。[DataContract]public class Data{  private int x;  public Data()  {    x = new Random(DateTime.Now.Millisecond).Next(10000);  }  [DataMember]  public int X  {    get { return x; }  }}  运用
上面这个 DataContract,你能得到的只能是下面这个的结果。   未处理 System.Runtime.Serialization.InvalidDataContractException  Message="No set method for property 'X' in type 'Data'."  Source="System.Runtime.Serialization"  改成 XmlSerializer 序列化引擎会如何
样呢?public class Data{  private int x;  public Data()  {    x = new Random(DateTime.Now.Millisecond).Next(10000);  }  public int X  {    get { return x; }  }}[ServiceContract, XmlSerializerFormat]public interface IService{  [OperationContract]  void Test(Data d);}  编译能通过,看看生成的客户端代理是什么样子?public partial class Data : object, IExtensibleDataObject{  [NonSerializedAttribute()]  private ExtensionDataObject extensionDataF  public ExtensionDataObject ExtensionData  {    get    {      return this.extensionDataF    }    set    {      this.extensionDataField =     }  }}
很糟糕,属性 X "丢失"。
在 MSDN 上有这样一句话,"XML 序列化不转换要领
、索引器、私有字段或只读属性(只读集合除外)"。  接下来,我们改用 "Serializable",结果会如何
呢?[Serializable]public class Data{  private int x;  public Data()  {    x = new Random(DateTime.Now.Millisecond).Next(10000);  }  public int X  {    get { return x; }  }}[ServiceContract]public interface IService{  [OperationContract]  void Test(Data d);}  这次生成的代理倒是有 Data.X,只可惜不是只读的。 public partial class Data : object, IExtensibleDataObject{  [NonSerializedAttribute()]  private ExtensionDataObject extensionDataF  private int xF  public ExtensionDataObject ExtensionData  {    get    {      return this.extensionDataF    }    set    {      this.extensionDataField =     }  }  [DataMemberAttribute(IsRequired = true)]  public int x  {    get    {      return this.xF    }    set    {      this.xField =     }  }}
看来,生成客户端代理文件这条路走不通了。我们必须把开发模式转回到 ChannelFactory ,也就是说共享元数据。即便是这样,DataContract 依然行不通,只好再次试试 XmlSerializer。public class Data{  private int x;  public Data()  {    Console.WriteLine("Constructor:{0}", x);    x = new Random(DateTime.Now.Millisecond).Next(10000);  }  public int X  {    get { return x; }  }}[ServiceContract, XmlSerializerFormat]public interface IService{  [OperationContract]  void Test(Data d);}public class Service : IService{  [OperationBehavior]  public void Test(Data d)  {    Console.WriteLine("Server:{0}", d.X);  }}public class WcfTest{  public static void Test()  {    AppDomain.CreateDomain("Server").DoCallBack(delegate    {      ServiceHost host = new ServiceHost(typeof(Service), new Uri(//localhost:8080"));      host.AddServiceEndpoint(typeof(IService), new BasicHttpBinding(), "");      host.Open();    });    IService client = ChannelFactory&IService&.CreateChannel(new BasicHttpBinding(),       new EndpointAddress(//localhost:8080"));          using (client as IDisposable)    {      Data d = new Data();      Console.WriteLine("Client:{0}", d.X);      client.Test(d);    }  }}
输出结果:Constructor:0Client:2819Constructor:0Server:1939  通过输出结果,我们会发觉
XmlSerializer 引擎在反序列化时会再次调用构造要领
。通过消息跟踪,我们得到的结果会更失望。因为 d.X 的值根本没有传递到服务器。
就是上面我们所提到 MSDN 里面的那句话,XmlSerializer 是不会 "搭理" 只读属性的。 &MessageLogTraceRecord&  &s:Envelope xmlns:s="..."&    &s:Header&      &Action s:mustUnderstand="1" xmlns="..."&;/Action&    &/s:Header&    &s:Body xmlns:xsi="..." xmlns:xsd="..."&      &Test xmlns=""&        &d&&/d&      &/Test&    &/s:Body&  &/s:Envelope&&/MessageLogTraceRecord&  最后一条路,就是 Serializable。[Serializable]public class Data{  private int x;  public Data()  {    Console.WriteLine("Constructor:{0}", x);    x = new Random(DateTime.Now.Millisecond).Next(10000);  }  public int X  {    get { return x; }  }}[ServiceContract]public interface IService{  [OperationContract]  void Test(Data d);}public class Service : IService{  [OperationBehavior]  public void Test(Data d)  {    Console.WriteLine("Server:{0}", d.X);  }}public class WcfTest{  public static void Test()  {    AppDomain.CreateDomain("Server").DoCallBack(delegate    {      ServiceHost host = new ServiceHost(typeof(Service), new Uri(//localhost:8080"));      host.AddServiceEndpoint(typeof(IService), new BasicHttpBinding(), "");      host.Open();    });    IService client = ChannelFactory&IService&.CreateChannel(new BasicHttpBinding(),       new EndpointAddress(//localhost:8080"));          using (client as IDisposable)    {      Data d = new Data();      Console.WriteLine("Client:{0}", d.X);      client.Test(d);    }  }}输出:Constructor:0Client:7644Server:7644  反序列化时没有再次调用构造要领
,消息跟踪结果也正常。&MessageLogTraceRecord&  &s:Envelope xmlns:s="..."&    &s:Header&      &Action s:mustUnderstand="1" xmlns="..."&;/Action&    &/s:Header&    &s:Body&      &Test xmlns=""&        &d xmlns:d4p1="..." xmlns:i="..."&          &d4p1:x&7644&/d4p1:x&        &/d&      &/Test&    &/s:Body&  &/s:Envelope&&/MessageLogTraceRecord&  绕来绕去,还是回到 "Remoting" 了,呵呵~~~~
H3C认证Java认证Oracle认证
基础英语软考英语项目管理英语职场英语
.NETPowerBuilderWeb开发游戏开发Perl
二级模拟试题一级模拟试题一级考试经验四级考试资料
软件测试软件外包系统分析与建模敏捷开发
法律法规历年试题软考英语网络管理员系统架构设计师信息系统监理师
高级通信工程师考试大纲设备环境综合能力
路由技术网络存储无线网络网络设备
CPMP考试prince2认证项目范围管理项目配置管理项目管理案例项目经理项目干系人管理
职称考试题目
招生信息考研政治
网络安全安全设置工具使用手机安全
生物识别传感器物联网传输层物联网前沿技术物联网案例分析
Java核心技术J2ME教程
Linux系统管理Linux编程Linux安全AIX教程
Windows系统管理Windows教程Windows网络管理Windows故障
数据库开发Sybase数据库Informix数据库
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&

我要回帖

更多关于 2017巴黎全透明时装周 的文章

 

随机推荐