给定了WebService地址和调用接口后动态的生成DLL,第二次再请求时会先判断DLL是否存在,以提高执行效率

核心代码下:

/// <summary>
/// 动态生成WebService服务客户端
/// </summary>
/// <param name="serviceProvider">WebService服务的提供者</param>
/// <param name="url">WebService具体地址</param>
/// <param name="serviceName">需要调用的类名</param>
/// <param name="actionName">需要请求的方法</param>
/// <param name="args">方法参数列表</param>
/// <returns></returns>
public static object InvokeWebService(string serviceProvider, string url, string serviceName, string actionName, object[] args)
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException("url");
} if (string.IsNullOrEmpty(serviceName))
{
serviceName = GetWsClassName(url);
} var shortUrl = BuildShortUrl(url); var nameSpace = string.Format("{0}_{1}_{2}", serviceProvider, serviceName, shortUrl);
var binDir = HttpRuntime.AppDomainId == null ? AppDomain.CurrentDomain.BaseDirectory : HttpRuntime.BinDirectory;
var asmFullPath = System.IO.Path.Combine(binDir, string.Format("{0}.dll", nameSpace)); #region
if (!File.Exists(asmFullPath))
{
if (!url.ToLower().EndsWith("?wsdl"))
{
url += "?wsdl";
} //获取WSDL
WebClient webClient = new WebClient(); try
{
#region 动态生成DLL
Stream wsdlStream = webClient.OpenRead(url); //服务描述
ServiceDescription serviceDesc = ServiceDescription.Read(wsdlStream); //生成客户端代理类
ServiceDescriptionImporter clientBuilder = new ServiceDescriptionImporter()
{
CodeGenerationOptions = System.Xml.Serialization.CodeGenerationOptions.GenerateNewAsync | System.Xml.Serialization.CodeGenerationOptions.GenerateProperties,
ProtocolName = "Soap",
Style = ServiceDescriptionImportStyle.Client
};
clientBuilder.AddServiceDescription(serviceDesc, null, null); //生成客户端代理类代码
CodeNamespace ns = new CodeNamespace(nameSpace);
CodeCompileUnit ccu = new CodeCompileUnit();
ccu.Namespaces.Add(ns); //按照clientBuilder的配置来生成代码
clientBuilder.Import(ns, ccu); //C#代码容器
var sourceCodeProvider = new CSharpCodeProvider(); //设定编译参数
var comParams = new CompilerParameters();
comParams.GenerateExecutable = false;//如果此属性的值为 false,则生成 DLL
comParams.GenerateInMemory = false;
comParams.OutputAssembly = asmFullPath; // 可以指定你所需的任何文件名。
comParams.ReferencedAssemblies.Add("System.dll");
comParams.ReferencedAssemblies.Add("System.XML.dll");
comParams.ReferencedAssemblies.Add("System.Web.Services.dll");
comParams.ReferencedAssemblies.Add("System.Data.dll");
comParams.CompilerOptions = "/optimize"; //编译
var comResult = sourceCodeProvider.CompileAssemblyFromDom(comParams, ccu); if (comResult.Errors.HasErrors)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder(); foreach (System.CodeDom.Compiler.CompilerError ce in comResult.Errors)
{
sb.Append(ce.ToString());
sb.Append(System.Environment.NewLine);
} throw new Exception(sb.ToString());
}
#endregion
}
catch (Exception ex)
{
}
finally
{
webClient.Dispose();
}
}
#endregion //生成代理实例,并调用方法
var asm = System.Reflection.Assembly.LoadFile(asmFullPath);
Type t = asm.GetType(nameSpace + "." + serviceName, true, true);
object obj = Activator.CreateInstance(t);
System.Reflection.MethodInfo mi = t.GetMethod(actionName);
return mi.Invoke(obj, args);
}

辅助代码:简化WebService地址,类似生成短链的功能

// Hash an input string and return the hash as
// a 32 character hexadecimal string.
static string getMd5Hash(string input)
{
// Create a new instance of the MD5CryptoServiceProvider object.
System.Security.Cryptography.MD5 md5Hasher = System.Security.Cryptography.MD5.Create(); // Convert the input string to a byte array and compute the hash.
byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input)); // Create a new Stringbuilder to collect the bytes
// and create a string.
StringBuilder sBuilder = new StringBuilder(); // Loop through each byte of the hashed data
// and format each one as a hexadecimal string.
for (int i = ; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
} // Return the hexadecimal string.
return sBuilder.ToString();
} static string BuildShortUrl(string url)
{
// 可以自定义生成 MD5 加密字符传前的混合 KEY string key = "fF{#E@#:RJP(#!$"; // 要使用生成 URL 的字符
string[] chars = new string[] { "a" , "b" , "c" , "d" , "e" , "f" , "g" , "h" ,
"i" , "j" , "k" , "l" , "m" , "n" , "o" , "p" , "q" , "r" , "s" , "t" ,
"u" , "v" , "w" , "x" , "y" , "z" , "" , "" , "" , "" , "" , "" ,
"" , "" , "" , "" , "A" , "B" , "C" , "D" , "E" , "F" , "G" , "H" ,
"I" , "J" , "K" , "L" , "M" , "N" , "O" , "P" , "Q" , "R" , "S" , "T" ,
"U" , "V" , "W" , "X" , "Y" , "Z"}; // 对传入网址进行 MD5 加密
string hex = getMd5Hash(url + key); string[] resUrl = new string[]; for (int i = ; i < ; i++)
{
// 把加密字符按照 8 位一组 16 进制与 0x3FFFFFFF 进行位与运算
string sTempSubString = hex.Substring(i * , ); // 这里需要使用 long 型来转换,因为 Inteper .parseInt() 只能处理 31 位 , 首位为符号位 , 如果不用 long ,则会越界
long lHexLong = 0x3FFFFFFF & long.Parse(sTempSubString, System.Globalization.NumberStyles.AllowHexSpecifier); string outChars = ""; for (int j = ; j < ; j++)
{
// 把得到的值与 0x0000003D 进行位与运算,取得字符数组 chars 索引
long index = 0x0000003D & lHexLong; // 把取得的字符相加
outChars += chars[(int)index]; // 每次循环按位右移 7 位
lHexLong = lHexLong >> ;
} // 把字符串存入对应索引的输出数组
resUrl[i] = outChars;
} return string.Join("", resUrl);
}

测试结果:

动态生成WebService的客户端的更多相关文章

  1. Atitit 动态调用webservice与客户端代理方式调用

    Atitit 动态调用webservice与客户端代理方式调用 方式1: 使用call.invoke  直接调用WSDL,缺点:麻烦,不推荐--特别是JAVA调用.NET的WS时,会有不少的问题需要解 ...

  2. 利用wsdl2java工具生成webservice的客户端代码

    1.JDK环境  2.下载apache-cxf发布包:http://cxf.apache.org/download.html 目前最新版本为3.2.6, 解压后如下: 解压发布包,设置CXF_HOME ...

  3. 使用axis1.4生成webservice的客户端代码

    webservice服务端: https://blog.csdn.net/ghsau/article/details/12714965 跟据WSDL文件地址生成客服端代码: 1.下载 axis1.4 ...

  4. gsoap生成webservice调用客户端接口

    1.下载gsoap2.8 2.运行 wsdl2h.exe -o XXX.h XXX.wsdl wsdl文件可以是本地文件,也可以是服务器的wsdl,比如http://192.168.0.122:333 ...

  5. java应用maven插件动态生成webservice代码

    pom.xml如下 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www ...

  6. 根据wsdl文件生成WebService客户端代码

    有时候在项目中,一个项目可能有好几个公司在做.系统之间难免会出现互相调用接口的现象,这时候有一种办法就是使用webService.本篇文章将介绍如何将对接系统提供的WebService接口,根据对方提 ...

  7. 动态调用WebService 通用方法Moss 中 传统开发中都可用。

    WebService是啥大家都知道了,这里不做过多的解释.通常我们使用WebService的做法基本都是在我们的项目中添加Web引用的方式,首先找到WebService的地址,然后定义命名空间,这样会 ...

  8. C# 调用WebService的3种方式 :直接调用、根据wsdl生成webservice的.cs文件及生成dll调用、动态调用

    1.直接调用 已知webservice路径,则可以直接 添加服务引用--高级--添加web引用 直接输入webservice URL.这个比较常见也很简单 即有完整的webservice文件目录如下图 ...

  9. Jquery.Qrcode在客户端动态生成二维码并添加自定义Logo

    0 Jquery.Qrcode简介 Jquery.Qrcode.js是一个在浏览器端基于Jquery动态生成二维码的插件,支持Canvas和Table两种渲染方式,它的优点是在客户端动态生成,减轻了服 ...

随机推荐

  1. 在Jenkins中配置运行远程shell命令

    用过Jenkins的都知道,在Build配置那里有一个Add buld step, 有这样两个选项: 1. Execute Windows batch command 2. Execute shell ...

  2. 微信JS-SDK“分享信息设置”API及数字签名生成方法(NodeJS版本)

    原文:微信JS-SDK"分享信息设置"API及数字签名生成方法(NodeJS版本) 先上测试地址以示成功: 用微信打开下面地址测试 http://game.4gshu.com/de ...

  3. Android一些解决方案内存问题(一)

    通常我们遇到内存问题时,,解决方案一般有以下的例子: 1.做一些处理上的内存引用,经常使用软引用.加强引用.弱引用: 2.加载在内存中的照片时,它可以处理直接在内存,例如:压缩边界. 3.内存的动态恢 ...

  4. 【Flume NG用户指南】(2)构造

    作者:周邦涛(Timen) Email:zhoubangtao@gmail.com 转载请注明出处:  http://blog.csdn.net/zhoubangtao/article/details ...

  5. c/c++和java达到swap不同功能

    首先我们来看看c/c++实施swap性能 void swap ( int & a, int & b) { int Temp; temp = a; a = b; b = temp; } ...

  6. OpenVPN多处理之-最新架构

    好久没有更新这个系列了,由于我之前也说过,前段时间实在太忙了,并且早在一个月前就预示着本月将更加忙!事实也确实如此!最终在国庆前夕完毕了既定的计划,心里也最终能够长出一口气了.近期在忙什么呢?事实上就 ...

  7. 怎样选择PHP的版本

    原文:怎样选择PHP的版本 IIS 如果想使用IIS配置PHP的话,那么需要选择Non-Thread Safe(NTS)版本的PHP Apache 如果你是用的Apache的版本来自Apache Lo ...

  8. Milo的游戏开发的一些链接资料

    http://www.cnblogs.com/miloyip/default.aspx?page=1 http://www.cnblogs.com/miloyip/archive/2010/06/14 ...

  9. windows phone开发-Webbrowser使用技巧

    原文:windows phone开发-Webbrowser使用技巧 5月份开发了脸萌WP版,其中需要使用web技术来绘制图像,于是就使用了原生webbrowser控件.在使用webbrowser co ...

  10. [强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!)

    原文:[强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!) [强烈推荐]ORACLE PL/SQL编程详解之七: 程序包的创建与应用(聪明在于学习,天 ...