但是,如果我们不想通过添加引用的方式,而是在代码中动态引用该怎么办呢?
首先,我们该想到WS的实现也是一个类的形式。
其次,WS在传输过程中是通过WSDL来进行描述的(使用SOAP协议)。
因此,我们需要获取WS的WSDL描述,并通过该描述来动态生成程序集。
最后:通过反射来获取新生成的程序集,并调用其方法!
上述步骤需要引用如下四个名称空间:
using System.Web.Services.Description //WS的描述
//以下几个用于根据描述动态生成代码并动态编译获取程序集
using System.CodeDom
using Microsoft.CSharp
using System.CodeDom.Compiler
上述几个名称空间中包括如下几个重要的类:
using System.Web.Services.Description下:
ServiceDescription //WS描述
ServiceDescriptionImporter //通过描述生成客户端代理类,特别注意其中的Style
以下是MSDN对其的描述:
XML Web services 的接口通常由 Web 服务描述语言 (WSDL) 文件来说明。例如,若要获取有关使用http://localhost/service.asmx 处公开的 ASP.NET 的 Web 服务的 WSDL 说明,只需导航到 http://localhost/service.asmx?WSDL。使用 ServiceDescriptionImporter 类可以方便地将 WSDL 说明中包含的信息导入到System.CodeDom.CodeCompileUnit 对象。通过调整 Style 参数的值,可以指示 ServiceDescriptionImporter 实例生成客户端代理类(通过透明调用该类可提供 Web 服务的功能)或生成抽象类(该类封装 Web 服务的功能而不实现该功能)。如果将 Style 属性设置为 Client,则 ServiceDescriptionImporter 生成客户端代理类,通过调用这些类来提供说明的 Web 服务的功能。如果将Style 属性设置为 Server,则 ServiceDescriptionImporter 实例生成抽象类,这些类表示所说明的 XML Web services 的功能而不进行实现。然后,可以通过编写从这些抽象类继承的类来对其进行实现,并实现相关的方法。
using System.CodeDom下:
CodedomUnit //它用于设定动态代码的名称空间,类名等,可以通过ServiceDescriptionImporter.Import()方法将WS的描述代码写入该类,以作动态编译用
using System.CodeDom.Compiler下:
CodedomProvider //用于创建和检索代码生成器和代码编译器的实例,我们主要用到其实现子类CShareCodeProvider
可以直接用CShareCodeProvider provider=new CShareCodeProvider()来生成,或者用CodedomProvider.CreateProvider("CSharp")来生成
ICodeCompiler //用于编译基于 System.CodeDom 的源代码表示形式。
它通过CodedomProvider的CreateCompiler()方法来
CompilerResults //表示从编译器返回的编译结果。 它由ICodeCompiler根据指定的编译器设置从指定的 CodeCompileUnit 所包含的 System.CodeDom 树中编译程序集并返回。CompiledAssembly 属性指示编译的程序集。
了解如上信息后,就可动态调用WS了。
分析了一下,解决方案如下:1.在应用程序中添加配置文件(如Winform的一般是app.config,webform的一般是web.config),在<appSettings>目录下添加一个配置WebService引用地址的节点,如:<add key="webServiceAddr" value="http://192.168.1.105:800/TestWebService.asmx?wsdl"/>
2.项目添加Web服务引用,如引用名为ServiceCenter,引用成功后,在打开目录Web References》ServiceCenter》Reference.map》Reference.cs的Reference.cs文件,这是一个WebService代理类。
不同的WebService生成的代理类不同。构造函数如:
public TestWebService() {
this.Url = global::WebServiceApp.Properties.Settings.Default.WebServiceApp_ServiceCenter_TestWebService
if ((this.IsLocalFileSystemWebService(this.Url) == true)) {
this.UseDefaultCredentials = true
this.useDefaultCredentialsSetExplicitly = false
}
else {
this.useDefaultCredentialsSetExplicitly = true
}
}
重新添加一个构造函数,带有WebService引用地址的参数:
public TestWebService(string url)
{
if (!string.IsNullOrEmpty(url))
{
this.Url = url
}
else
{
this.Url = global::WebServiceApp.Properties.Settings.Default.WebServiceApp_ServiceCenter_TestWebService
}
if ((this.IsLocalFileSystemWebService(this.Url) == true))
{
this.UseDefaultCredentials = true
this.useDefaultCredentialsSetExplicitly = false
}
else
{
this.useDefaultCredentialsSetExplicitly = true
}
}
3.在应用程序中应用
private void button1_Click(object sender, EventArgs e)
{
string result = string.Empty
string serviceAddr = string.Empty
try
{
serviceAddr = System.Configuration.ConfigurationManager.AppSettings["webServiceAddr"].ToString()
//此处调用的是我们自己定义的构造函数,参数为WebService引用的地址
ServiceCenter.TestWebService webService = new WebServiceApp.ServiceCenter.TestWebService(serviceAddr)
result = webService.Test()
}
catch (Exception ex)
{
result = ex.Message
}
MessageBox.Show(serviceAddr + "++++" + result)
}
4.修改WebService引用地址:
在Winform应用程序中,app.config等应用程序配置文件在生成的时候自动生成到了bin目录下面的应用程序名.exe.config文件,修改里面的webServiceAddr节点即可。
需要注意的一点就是,如果生成的时候把app.config文件也生成到了bin目录下,此时修改app.config里面的配置是无效,还必须得修改(应用程序名.exe.config)这个文件。如果是把webservice引用地址放在自定义的的xml文件中,则生成到bin目录下,响应bin目录下的xml文件即可。
大概的思路是这样的:
使用Jquery绑定所有分享按钮中A标签的mouseover事件,每当想要点击某个分享按钮时,鼠标肯定就会移动到分享按钮所在的a标签上,这样就触发了mouseover事件(Jquery事件,当鼠标指针位于元素上方时,会发生 mouseover 事件);
设置了一个全局变量ShareId,一旦触发事件就获取当前分享按钮a标签的data-id属性,并将data-id赋值给ShareId。data-id保存的是文章的ID。具体的代码是这段:
通过插件本身的事件和Jquery的元素事件,从另一种角度和方式实现了百度分享插件实现自定义URL的功能。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)