WCF 之 生成元数据和代理
在WCF开发概述中讲解了手工方式的WCF应用,其实实际开发中使用更多的使用配置方式和元数据来实现WCF,下面我们来看一个具体的Demo,这个例子和WCF开发概述中使用的是同一个例子,只是实现方式不同,然后来再来讲解。
Demo
首先在Host项目中添加一个App.config文件,可以参照下图方式:
添加后工程如下:
App.config代码 <?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="WCF.Demo.HelloWorldService" behaviorConfiguration="serviceBehavior">
<endpoint binding="wsHttpBinding" contract="WCF.Demo.IService" address="HelloWorld" />
<endpoint binding="mexHttpBinding" contract="IMetadataExchange" address="mex" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:9000"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
下面解释一下文件的内容:
service name="WCF.Demo.HelloWorldService"指定到Service类。
behaviorConfiguration="serviceBehavior"指定到下面的<ServiceBehaviors>。
<endpoint binding="wsHttpBinding" contract="WCF.Demo.IService" address="HelloWorld" />这个endpoint是指定Service的邦定方式和契约还有地址。
<endpoint binding="mexHttpBinding" contract="IMetadataExchange" address="mex" />这个endpoint是WCF内建的邦定方式和契约,主要用来完成元数据的传递。
add baseAddress="http://localhost:9000" 这个指定访问Service的服务器地址
上面就把Service部分配置好了。
对于ServiceBehaviors部分很简单,serviceMetadata httpGetEnabled="true" 就表示Service可以采取http的Get方式来传递元数据。
由于已经通过配置的方式,是实现了endpoint的东西,所以host.cs中就不用再添加和定义endpoint了。
Host.cs代码 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel; namespace WCF.Demo
{
public class Host
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(WCF.Demo.HelloWorldService)))
{
host.Open();
Console.WriteLine("Host in started successful!");
Console.Read();
}
}
}
}
现在启动host程序,程序可以成功运行。
并且由于配置了http相关的访问方式和协议,此时我们可以通过IE中输入 http://localhost:9000/来查看这个Sevice的相关信息。
信息如下:
******************************************************************************************************
HelloWorldService Service
You have created a service.
To test this service, you will need to create a client and use it to call the service. You can do this using the svcutil.exe tool from the command line with the following syntax:
svcutil.exe http://localhost:9000/?wsdl
This will generate a configuration file and a code file that contains the client class. Add the two files to your client application and use the generated client class to call the Service. For example:
C#
class Test
{
static void Main()
{
ServiceClient client = new ServiceClient(); // Use the 'client' variable to call operations on the service. // Always close the client.
client.Close();
}
}
Visual Basic
Class Test
Shared Sub Main()
Dim client As ServiceClient = New ServiceClient()
' Use the 'client' variable to call operations on the service. ' Always close the client.
client.Close()
End Sub
End Class
******************************************************************************************************
为什么不是http://localhost:9000/HelloWorld那?点击上边的http://localhost:9000/?wsdl 可以查看这个Service的WSDL描述,
你会发现HelloWorld其实是在真正调用Service通信是的地址,它是内部使用的。
现在扫除两个概念问题:
WSDL:Web Services Description Language的缩写,是一个用来描述Web服务和说明如何与Web服务通信的XML语言。怎样向别人介绍你的Web service有什么功能,
以及每个函数调用时的参数呢?你可能会自己写一套文档,你甚至可能会口头上告诉需要使用你的Web service的人。这些非正式的方法至少都有一个严重的问题:
当程序员坐到电脑前,想要使用你的Web service的时候,他们的工具(如Visual Studio)无法给他们提供任何帮助,
因为这些工具根本就不了解你的Web service。解决方法是:用机器能阅读的方式提供一个正式的描述文档。
Web service描述语言(WSDL)就是这样一个基于XML的语言,用于描述Web service及其函数、参数和返回值。因为是基于XML的,
所以WSDL既是机器可阅读的,又是人可阅读的,这将是一个很大的好处。一些最新的开发工具既能根据你的Web service生成WSDL文档,
又能导入WSDL文档,生成调用相应Web service的代码。
元数据:元数据最本质、最抽象的定义为:data about data (关于数据的数据)。它是一种广泛存在的现象,
在许多领域有其具体的定义和应用。在软件构造领域,元数据被定义为:在程序中不是被加工的对象,而是通过其值的改变来改变程序的行为的数据。
它在运行过程中起着以解释方式控制程序行为的作用。在程序的不同位置配置不同值的元数据,就可以得到与原来等价的程序行为。
元数据是一种二进制信息,用以对存储在公共语言运行库可移植可执行文件 (PE) 文件或存储在内存中的程序进行描述。
将您的代码编译为 PE 文件时,便会将元数据插入到该文件的一部分中,而将代码转换为 Microsoft 中间语言 (MSIL) 并将其插入到该文件的另一部分中。
在模块或程序集中定义和引用的每个类型和成员都将在元数据中进行说明。当执行代码时,运行库将元数据加载到内存中,
并引用它来发现有关代码的类、成员、继承等信息。
其实使用配置方式是不需要编写代码的。
本例中的Service不变:
Service.cs代码
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace WCF.Demo
{
[ServiceContract(Namespace="http://www.cnblogs.com/charlesliu")]
public interface IService
{
[OperationContract]
string HelloWorld(string message);
}
public class HelloWorldService : IService
{
public string HelloWorld(string message)
{
return string.Format("At {0}, I will say {1}", DateTime.Now, message);
}
}
}
下面来看看Client端如何使用这个服务,首先把Service启动起来,然后在Client工程中添加一个Service的引用。
如果添加Service引用的时候出现下面的问题,可以用这个命令来解决:D:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe /resetskippkgs
正常情况下可以看到下面的对话框:
此时Client工程会变成下图,很多东西已经自动创建了,其会根据WSDL自动生成相应的Proxy文件和配置文件。可以显示所有文件然后查看,其中Reference.cs就是Proxy文件。
修改namespace为SRHelloWorld,原因是自动生成的namespace自动加了Client.前缀(代码中的相关引用也要对应的改掉),和程序定义的Client冲突了(如果没有名字冲突问题可以不考虑这个)。然后可以在Cleint.cs中调用相关的对象和方法了。
因为配置文件和代理文件都是自动生成的,所以大大简化了客户端的编成方式。若个Service发生了变化,可以重新运行host程序,然后再client的Service Reference下的那个绿色的引用上右击鼠标选择Update Service Reference即可。
Client.cs代码 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel; namespace WCF.Demo
{
class Client
{
static void Main(string[] args)
{
SRHelloWorld.ServiceClient proxy = new SRHelloWorld.ServiceClient();
string message = proxy.HelloWorld("Hello, World");
Console.WriteLine(message);
Console.Read();
}
}
}
运行Client程序,一切正常,服务调用成功,并返回了结果。
下面对于这个配置方式作一下总结,请看下图:
对于上面的图不再做过多说明了,其实就是实现了Service和Client的松耦合。Client并不直接与Service或者Endpoint交互,而是通过WSDL以元数据的方式通信,也就说只要WSDL不变化,Client就不会受到影响,
即使Service或者Ednpoint变化了。
到目前为止就把WCF的原理和开发方式介绍完了,具体到WCF还有很多的知识,今后的文章中在介绍。祝大家工作愉快!!!(完)
WCF 之 生成元数据和代理的更多相关文章
- WCF公开服务元数据方式
一般我们使用了scvutil命令自动生成了服务的客户端代理类: 例如:svcutil http://localhost:8000/?wsdl /o:FirstServiceClient.cs 命令中h ...
- WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[扩展篇]
原文:WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[扩展篇] 通过<实现篇>对WSDL元素和终结点三要素的之间的匹配关系的介绍,我们知道了WSDL的Binding ...
- WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[实现篇]
原文:WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[实现篇] 元数据的导出就是实现从ServiceEndpoint对象向MetadataSet对象转换的过程,在WCF元数据框 ...
- 修改tt模板让ADO.NET C# POCO Entity Generator With WCF Support 生成的实体类继承自定义基类
折腾几天记载一下,由于项目实际需要,从edmx生成的实体类能自动继承自定义的基类,这个基类不是从edmx文件中添加的Entityobject. 利用ADO.NET C# POCO Entity Gen ...
- 利用反射生成JDK动态代理
利用反射生成JDK动态代理 在Java的java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口可以生成JDK动态代理类和动态代理 ...
- JavaSE---使用反射生成JDK动态代理
1.概述 1.1 在Java.lang.reflect包下,提供了Proxy类.InvocationHandler接口,使用它们可以生成JDK动态代理类或动态代理对象: 1.2 [Proxy类] 1. ...
- spring-boot如何生成元数据与javaBean进行关联用作配置文件提示
spring-boot如何生成元数据与javaBean进行关联用作配置文件提示 首先需要引入一个jar依赖包,以及一个maven plugin如下所示 <dependency> <g ...
- Java基础之反射生成JDK动态代理
在Java的java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口.通过这个类和接口可以生成JDK动态代理类或动态代理对象. JDK动态代理例子: / ...
- WCF服务引用之后自动生成的泛型代理类名称太长的解决方案
问题:WCF服务引用之后会将原来的泛型类自动生成一个代理类,但是有时候名称太长怎么办? 解决方案: 1.方案一: 调用客户端同样也引用这个泛型类的类库. 2.方案二: 找到这个泛型类,然后在上面的[D ...
随机推荐
- linux下如何配置TCP参数设置详解
设置tcp参数一定要小心谨慎,轻易不要更改线上环境,我贴一下我们线上环境中,sysctl.conf的内容,见文章底部 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tc ...
- 【BZOJ 3561】 3561: DZY Loves Math VI (莫比乌斯,均摊log)
3561: DZY Loves Math VI Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 205 Solved: 141 Description ...
- NOIP2017 D1T2时间复杂度
这道题在考试时看到感觉与第一题放反了位置(因为我还没有看到第一题是结论题) 对于每个语句进行栈的模拟,而如果有语法错误就特判. 对于每一条for语句我们将其与栈顶元素连边,复杂度是1的我们不用考虑,如 ...
- 「清华集训2015」V
「清华集训2015」V 题目大意: 你有一个序列,你需要支持区间加一个数并对 \(0\) 取 \(\max\),区间赋值,查询单点的值以及单点历史最大值. 解题思路: 观察发现,每一种修改操作都可以用 ...
- [ZJOI2007]最大半连通子图
[ZJOI2007]最大半连通子图 题目大意: 一个有向图称为半连通的,当且仅当对于任意两点\(u,v\),都满足\(u\)能到达\(v\)或者\(v\)能到达\(u\). 给定一个\(n(n\le1 ...
- 求n的阶乘 (python实现)
描述 给定一个数n,范围为0≤n≤100,请你编程精确的求出n的阶乘n!. 输入 输入数据有多行,每行一个整数n,当n<0时输入结束. 输出 输出n的阶乘. 样例输入 1234-1 样例输出 1 ...
- bzoj1502 simpson求面积
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1502 题解: simpson积分求面积,s = (f(a)+f(b)+4*f(c))/6*Δx ...
- Swify闭包
闭包:是字包含的匿名函数代码块,可以做为表达式.函数参数和函数返回值,闭包表达式的运算结果是一种函数类型.类似于 C# Lambda 表达式. 闭包表达式: {(参数列表)->返回类型 in 语 ...
- tomcat使用Eclipse进行远程调试(线上调试)
什么是远程调试,就是在A机器上利用Eclipse单步跟踪调试B机器上的Web应用,当然调试A机器上Web应用也是没有问题的,90%我都是调试本机的Web应用,远程调试的意义我想我不用说了,大家都会想到 ...
- SqlServer 2008无法远程连接到服务器
其他的什么先别说,上来第一点,看看服务器防火墙,是否把SqlServer的端口号例外了. 别弄了半天发现防火墙问题,那就得不偿失了. 用户在使用SQL Server 2008远程链接时,可能会弹出如 ...