http动态调用webserive
前言
传统方式调用WebService是直接引用服务,生成客户端代理类类,这种方式将ws进行了再次封装,并以代理的方式进行调用,这种方式的优点是简单,方便。
但是此种方式不足的地方是,当对方ws接口变更时,这边引用的服务同时也需要编译并部署,或者我调用方这边想动态指定不同服务地址时,此方式就不太适应这种场景了。
有一种方式是动态调用ws的方式。就是通过ws的服务描述获取生成客户端的代理并动态编译,通过反射生成实例对象,并完成ws的调用。大致代码如下
/// <summary>
/// 动态调用WebService
/// </summary>
/// <param name="url">WebService地址</param>
/// <param name="classname">类名</param>
/// <param name="methodname">方法名(模块名)</param>
/// <param name="args">参数列表</param>
/// <returns>object</returns>
public static object InvokeWebService(string url, string classname, string methodname, object[] args)
{
string @namespace = "ServiceBase.WebService.DynamicWebLoad";
if (classname == null || classname == "")
{
classname = WebServiceHelper.GetClassName(url);
}
//获取服务描述语言(WSDL)
WebClient wc = new WebClient();
Stream stream = wc.OpenRead(url + "?WSDL");
ServiceDescription sd = ServiceDescription.Read(stream);
ServiceDescriptionImporter sdi = new ServiceDescriptionImporter();
sdi.AddServiceDescription(sd, "", "");
CodeNamespace cn = new CodeNamespace(@namespace);
//生成客户端代理类代码
CodeCompileUnit ccu = new CodeCompileUnit();
ccu.Namespaces.Add(cn);
sdi.Import(cn, ccu);
CSharpCodeProvider csc = new CSharpCodeProvider();
ICodeCompiler icc = csc.CreateCompiler();
//设定编译器的参数
CompilerParameters cplist = new CompilerParameters();
cplist.GenerateExecutable = false;
cplist.GenerateInMemory = true;
cplist.ReferencedAssemblies.Add("System.dll");
cplist.ReferencedAssemblies.Add("System.XML.dll");
cplist.ReferencedAssemblies.Add("System.Web.Services.dll");
cplist.ReferencedAssemblies.Add("System.Data.dll");
//编译代理类
CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu);
if (true == cr.Errors.HasErrors)
{
System.Text.StringBuilder sb = new StringBuilder();
foreach (CompilerError ce in cr.Errors)
{
sb.Append(ce.ToString());
sb.Append(System.Environment.NewLine);
}
throw new Exception(sb.ToString());
}
//生成代理实例,并调用方法
System.Reflection.Assembly assembly = cr.CompiledAssembly;
Type t = assembly.GetType(@namespace + "." + classname, true, true);
object obj = Activator.CreateInstance(t);
System.Reflection.MethodInfo mi = t.GetMethod(methodname);
return mi.Invoke(obj, args);
} private static string GetClassName(string url)
{
string[] parts = url.Split('/');
string[] pps = parts[parts.Length - ].Split('.');
return pps[];
}
但是这种方式,最明显的方式就是性能较差,每次都要重新生成反射调用,所以一般情况不用它。
那还有别的方法吗?
那我就来说说今天在工作中用到的方法。
soap请求
首先需要知道传统的调用方式的通行协议是关键,ws底层也是走的http方式,只是加了多加了soap协议在里面,那怎么拿到它的交互协议呢,有一个神器叫fiddler,它可以监测http请求和响应信息。有了它,就有了协议了,剩下就是拼装协议了。
仔细观察协议后 发现它的交互结构如下
POST /WebServiceTest/Service1.asmx HTTP/1.1
Host: localhost
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/HelloWorld" <?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<HelloWorld xmlns="http://tempuri.org/">
<StudentName>string</StudentName>
<PassWord>string</PassWord>
</HelloWorld>
</soap:Body>
</soap:Envelope>
SOAPAction这个就是表示请求的具体方法,在请求流中,在写入上面的基于xml的soap协议,接下来就可以发起请求了,顺利的话就能拿到响应了。 做事有根有据,仔细并专注,不经意间,就能成功不远了。
http动态调用webserive的更多相关文章
- 动态调用WebService
WebService内容 using Microsoft.CSharp;using System;using System.CodeDom;using System.CodeDom.Compiler; ...
- c# 动态调用WCF方法笔记!
//动态调用wcf方法 string url = "http://localhost:54379/ServiceWCF.svc"; IDoubleService proxy = W ...
- C# 动态调用DLL库
最近经常用到C#动态调用类库,简单的做下记录方便以后查询. 使用下面的几行代码就可以简单实现DLL类库的调用了 using System.Reflection; // 引入该命名空间 // 获取roc ...
- Atitit 动态调用webservice与客户端代理方式调用
Atitit 动态调用webservice与客户端代理方式调用 方式1: 使用call.invoke 直接调用WSDL,缺点:麻烦,不推荐--特别是JAVA调用.NET的WS时,会有不少的问题需要解 ...
- C#动态调用WCF接口,两种方式任你选。
写在前面 接触WCF还是它在最初诞生之处,一个分布式应用的巨作. 从开始接触到现在断断续续,真正使用的项目少之又少,更谈不上深入WCF内部实现机制和原理去研究,最近自己做一个项目时用到了WCF. 从这 ...
- 11月10日上午ajax基础知识、用ajax做登录页面、用ajax验证用户名是否可用、ajax动态调用数据库
1.ajax的基础知识 ajax是结合了jquery.php等几种技术延伸出来的综合运用的技术,不是新的内容.ajax也是写在<script>标签里面的. 如果使用ajax一定是要有1个处 ...
- C# 调用WebService的3种方式 :直接调用、根据wsdl生成webservice的.cs文件及生成dll调用、动态调用
1.直接调用 已知webservice路径,则可以直接 添加服务引用--高级--添加web引用 直接输入webservice URL.这个比较常见也很简单 即有完整的webservice文件目录如下图 ...
- Delphi DLL的创建、静态及动态调用
转载:http://blog.csdn.net/welcome000yy/article/details/7905463 结合这篇博客:http://www.cnblogs.com/xumenger/ ...
- 动态调用WebService(C#) (非常实用)
通常我们在程序中需要调用WebService时,都是通过“添加Web引用”,让VS.NET环境来为我们生成服务代理,然后调用对应的Web服务.这样是使工作简单了,但是却和提供Web服务的URL.方法名 ...
随机推荐
- codeforces 631D. Messenger kmp
题目链接 首先想到kmp, 和普通的不一样的是,中间部分严格相等, 头和尾的字符相等但是数量可以不相等. 所以应该把子串的头和尾先去掉,然后对剩下的部分进行kmp. 子串长度为1或2要特别讨论. 不要 ...
- nyoj 228 士兵杀敌(五)
题目: http://acm.nyist.net/JudgeOnline/problem.php?pid=228 由于该题一开始是进行士兵军功增加,最后才是查找士兵的军功总和,使用一个数组,进行延迟更 ...
- 阅读 - Code Complete 2 - 第33章 - 个人性格
个人性格对于软件项目的开发到底有没有作用或者影响呢? 有的人急于完成自己的工作,当自己的代码遇到问题的时候,不去自己思考并调试而是直接求助于他人,有的人则是自己沉住气,耐心的从头到尾的研究找到错误的所 ...
- Java—异常处理总结
异常处理是程序设计中一个非常重要的方面,也是程序设计的一大难点,从C开始,你也许已经知道如何用if...else...来控制异常了,也许是自发的,然而这种控制异常痛苦,同一个异常或者错误如果多个地方出 ...
- java selenium webdriver实战 应用小结
部分api 1.访问网站 driver.get("http://www.baidu.com"); 或者 driver.navigate().to("http://www. ...
- android数据库持久化框架
android数据库持久化框架
- Installing perl and writing your first perl program in Ubuntu
Installing perl and writing your first perl program in Ubuntu Installing perl and writing your f ...
- Ordering Tasks(拓扑排序+dfs)
Ordering Tasks John has n tasks to do. Unfortunately, the tasks are not independent and the executio ...
- linux网络编程涉及的函数
常用的网络命令: netstat 命令netstat是用来显示网络的连接,路由表和接口统计等网络的信息. netstat有许多的选项我们常用的选项是-an用来显示详细的网络状态.至于其它选项我们使用帮 ...
- HTTP有关知识
Cookie 调用Cookie时,由于可校验Cookie的有效期,以及发送方的域,路径,协议等信息,所以正规发布的Cookie里面的内容不会因来自其他web站点和攻击者的攻击而泄露. Set-Cook ...