给定了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. Chain of Responsibility - 责任链模式

    定义 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合度. 案例 比方如今有一个图形界面,它包含一个应用Application类,一个主窗体Window,一个buttonButton ...

  2. php_linux_centos6.4_安装mysql_apache_php

    原文:php_linux_centos6.4_安装mysql_apache_php 原文 : http://blog.csdn.net/xiaoliouc/article/details/176395 ...

  3. Flex自定义组件开发之日周月日期选择日历控件

    原文:Flex自定义组件开发之日周月日期选择日历控件         使用过DateField的我们都知道,DateField 控件是用于显示日期的文本字段,字段右侧带有日历图标.当用户在控件边框内的 ...

  4. GG同步sqlserver报错一个案例 Invalid date format

    在里面Oracle表同步sqlserver时间,在sqlserver当应用程序数据的结束.您可能会遇到这个错误. 2014-05-17 17:20:24 WARNING OGG-01154 SQL e ...

  5. Middleware详解

    Middleware详解 在第1章项目结构分析中,我们提到Startup.cs作为整个程序的入口点,等同于传统的Global.asax文件,即:用于初始化系统级的信息(例如,MVC中的路由配置).本章 ...

  6. linux_shell_根据网站来源分桶

    应用场景: 3kw行url+\t+html记录 [网站混合] 需要:按照网站来源分桶输出 执行shell cat */*pack.html|awk -F '\t' '{ split($1,arr,&q ...

  7. 小强HTML5手机发展之路(52)——jquerymobile触摸互动

    当使用移动设备的触摸操作,最常用的是点击.按住屏幕或手势,jQuery Mobile能够通过触摸事件绑定行为来响应用户的特定触摸. 一个.点击并按住 直接在代码(在代码中的一切,它使产品!) < ...

  8. ar命令提取.a时刻,一个错误 is a fat file (use libtool(1) or lipo(1) and ar(1) on it)

    在减压.a当文件,据报一个类别似 xxx.a is a fat file (use libtool(1) or lipo(1) and ar(1) on it)的错误,经过查找资料,原来是由于该.a文 ...

  9. vistual studio 2012 安装失败,提示Microsoft Vistual Studio 2012 Devenv找不到元素,等错误信息

    在安装vistual studio 2012过程中,出现安装失败,提示Microsoft Vistual Studio 2012 Devenv找不到元素,等错误信息 解决方法是更新相应的server补 ...

  10. 一个意想不到的CDO.Message 错误

    原文:一个意想不到的CDO.Message 错误   几个月之前,写了一个服务从MSMQ取消息发群发邮件的程序,一直也没时间测试,今日一试,出现发送邮件时报错,异常情况如下:   "Syst ...