记一次动态调用WebService
这次的使用参考博客园中的ID是 生命不息,折腾不止 http://www.cnblogs.com/leolion/p/4757320.html ,感谢分享
博客园让自己慢慢的成长,少不了这些无私奉献的大牛,很是感谢。
动态调用的具体步骤为:
1)从目标 URL 下载 WSDL 数据;
2)使用 ServiceDescription 创建和格式化 WSDL 文档文件;
3)使用 ServiceDescriptionImporter 创建客户端代理类;
4)使用 CodeDom 动态创建客户端代理类程序集;
5)利用反射调用相关 WebService 方法。
开始咯
Web.config中的配置,里边的代理类名称好像必须的和WebSevice中的服务名称一样。
<appSettings>
<!--WebService地址-->
<add key="WebServiceUrl" value="http://localhost:3933/WebService/InterfaceService.asmx" />
<!--WebService输出dll文件名称-->
<add key="OutputDllFilename" value="TestWebService.dll" />
<!--WebService代理类名称-->
<add key="ProxyClassName" value="InterfaceService" />
</appSettings>
创建一个枚举类,把需要映射WebService的方法名称放进去,调用方法的时候用起来方便
namespace WebConnWebService
{
/// <summary>
/// 方法枚举
/// </summary>
public enum EMethod
{
HelloWorld,
CancelOrder,
GetAllProductInfo,
GetOrderInfo ,
GetProductInfo ,
OrderSubmit,
QueryOrderDetails
}
}
新建类WSHelper.cs,代码如下,精髓
public class WSHelper
{/// <summary>
/// 输出的dll文件名称
/// </summary>
private static string m_OutputDllFilename; /// <summary>
/// WebService代理类名称
/// </summary>
private static string m_ProxyClassName; /// <summary>
/// WebService代理类实例
/// </summary>
private static object m_ObjInvoke; /// <summary>
/// 接口方法字典
/// </summary>
private static Dictionary<EMethod, MethodInfo> m_MethodDic = new Dictionary<EMethod, MethodInfo>(); /// <summary>
/// 创建WebService,生成客户端代理程序集文件
/// </summary>
/// <param name="error">错误信息</param>
/// <returns>返回:true或false</returns>
public static bool CreateWebService(out string error)
{
try
{
error = string.Empty;
m_OutputDllFilename = ConfigurationManager.AppSettings["OutputDllFilename"];
m_ProxyClassName = ConfigurationManager.AppSettings["ProxyClassName"];
string webServiceUrl = ConfigurationManager.AppSettings["WebServiceUrl"];
webServiceUrl += "?WSDL"; // 如果程序集已存在,直接使用
if (File.Exists(Path.Combine(Environment.CurrentDirectory, m_OutputDllFilename)))
{
BuildMethods();
return true;
} //使用 WebClient 下载 WSDL 信息。
WebClient web = new WebClient();
Stream stream = web.OpenRead(webServiceUrl); //创建和格式化 WSDL 文档。
if (stream != null)
{
// 格式化WSDL
ServiceDescription description = ServiceDescription.Read(stream); // 创建客户端代理类。
ServiceDescriptionImporter importer = new ServiceDescriptionImporter
{
ProtocolName = "Soap",
Style = ServiceDescriptionImportStyle.Client,
CodeGenerationOptions =
CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync
}; // 添加 WSDL 文档。
importer.AddServiceDescription(description, null, null); //使用 CodeDom 编译客户端代理类。
CodeNamespace nmspace = new CodeNamespace();
CodeCompileUnit unit = new CodeCompileUnit();
unit.Namespaces.Add(nmspace); ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit);
CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp"); CompilerParameters parameter = new CompilerParameters
{
GenerateExecutable = false,
// 指定输出dll文件名。
OutputAssembly = m_OutputDllFilename
}; parameter.ReferencedAssemblies.Add("System.dll");
parameter.ReferencedAssemblies.Add("System.XML.dll");
parameter.ReferencedAssemblies.Add("System.Web.Services.dll");
parameter.ReferencedAssemblies.Add("System.Data.dll"); // 编译输出程序集
CompilerResults result = provider.CompileAssemblyFromDom(parameter, unit); // 使用 Reflection 调用 WebService。
if (!result.Errors.HasErrors)
{
BuildMethods();
return true;
}
else
{
error = "反射生成dll文件时异常";
}
stream.Close();
stream.Dispose();
}
else
{
error = "打开WebServiceUrl失败";
}
}
catch (Exception ex)
{
error = ex.Message;
}
return false;
} /// <summary>
/// 反射构建Methods
/// </summary>
private static void BuildMethods()
{
Assembly asm = Assembly.LoadFrom(m_OutputDllFilename);
//var types = asm.GetTypes();
Type asmType = asm.GetType(m_ProxyClassName);
m_ObjInvoke = Activator.CreateInstance(asmType); //var methods = asmType.GetMethods();
var methods = Enum.GetNames(typeof(EMethod)).ToList();
foreach (var item in methods)
{
var methodInfo = asmType.GetMethod(item);
if (methodInfo != null)
{
var method = (EMethod)Enum.Parse(typeof(EMethod), item);
if (!m_MethodDic.ContainsKey(method))
{
m_MethodDic.Add(method, methodInfo);
}
}
}
} /// <summary>
/// 获取请求响应
/// </summary>
/// <param name="method">方法</param>
/// <param name="para">参数</param>
/// <returns>返回:Json串</returns>
public static string GetResponseString(EMethod method, params object[] para)
{
string result = null;
if (m_MethodDic.ContainsKey(method))
{
var temp = m_MethodDic[method].Invoke(m_ObjInvoke, para);
if (temp != null)
{
result = temp.ToString();
}
}
return result;
}
}
好了接下来就是调用,简单的测试一下了
protected void Page_Load(object sender, EventArgs e)
{
string error;
bool succ = WSHelper.CreateWebService(out error);//先下载wsdl到本地如果本地已下载直接调用本地已下载好的dll,在把方法放到内存中以便调用
// SOAP 请求响应方式
//TextBox1.Text = WSHelper.GetResponseString(EMethod.Add, Convert.ToInt32(TextBox1.Text), Convert.ToInt32(TextBox2.Text));
TextBox1.Text = WSHelper.GetResponseString(EMethod.HelloWorld);
}
前台显示
758.png)

记一次动态调用WebService的更多相关文章
- Atitit 动态调用webservice与客户端代理方式调用
Atitit 动态调用webservice与客户端代理方式调用 方式1: 使用call.invoke 直接调用WSDL,缺点:麻烦,不推荐--特别是JAVA调用.NET的WS时,会有不少的问题需要解 ...
- 动态调用WebService(C#) (非常实用)
通常我们在程序中需要调用WebService时,都是通过“添加Web引用”,让VS.NET环境来为我们生成服务代理,然后调用对应的Web服务.这样是使工作简单了,但是却和提供Web服务的URL.方法名 ...
- 动态调用webservice(部分转载)
动态调用webservice,做个笔记: public class WSHelper { /// < summary> /// 动态调用web服务 /// < /summary> ...
- C# 动态调用webservice
最近项目中,用到动态调用webservice的内容,此处记录下来,留着以后COPY(我们只需要在XML,config文件,或者数据库中配置webservice连接地址和方法名即可使用): using ...
- 动态调用webservice及WCF服务
动态调用web服务,该方法只针对Web service, WCF的服务不行,如果是WCF的就通过工具直接生产代理类,把代理类配置到调用的项目中,通过配置客户端的终结点动态的取实现: 通过Svcutil ...
- C# .NET 动态调用webservice的三种方式
转载自 百度文库 http://wenku.baidu.com/link?url=Q2q50wohf5W6UX44zqotXFEe_XOMaib4UtI3BigaNwipOHKNETloMF4ax4W ...
- WebService – 2.动态调用WebService
在本节课程中,将演示如何通过程序动态添加.调用.编译.执行WebService并返回结果. WebService动态调用示意图 WebService相关知识 代码文档对象模型CodeDom的使用 编程 ...
- 用C#通过反射实现动态调用WebService 告别Web引用
我们都知道,调用WebService可以在工程中对WebService地址进行WEB引用,但是这确实很不方便.我想能够利用配置文件灵活调用WebService.如何实现呢? 用C#通过反射实现动态调用 ...
- 动态调用Webservice 支持Soapheader身份验证(转)
封装的WebserviceHelp类: using System; using System.CodeDom; using System.CodeDom.Compiler; using System. ...
随机推荐
- C++学习37 string字符串的访问和拼接
访问字符串中的字符 string 字符串也可以像字符串数组一样按照下标来访问其中的每一个字符.string 字符串的起始下标仍是从 0 开始.请看下面的代码: #include <iostrea ...
- [ActionScript] AS3 涂鸦的擦除和撤销功能
package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.BlendMo ...
- jquery mobile导致无法修改textarea的高度
在引用了jquery mobile的js库和样式的页面中,添加textarea标签,会导致无法调整其height属性,不管是用CSS还是JS,最终都会被替换成height=52px 解决办法:在页面中 ...
- Python 描述符(descriptor) 杂记
转自:https://blog.tonyseek.com/post/notes-about-python-descriptor/ Python 引入的“描述符”(descriptor)语法特性真的很黄 ...
- [SQL]一组数据中Name列相同值的最大Je与最小je的差
declare @t table(name varchar(),qy varchar(),je int) insert into @t union all union all union all un ...
- python正则表达式介绍
点击打开链接 1. 正则表达式基础 1.1. 简单介绍 正则表达式并不是Python的一部分.正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的 ...
- (medium)LeetCode 222.Count Complete Tree Nodes
Given a complete binary tree, count the number of nodes. Definition of a complete binary tree from W ...
- zsh配置文件
zsh通过编辑~/.zshrc来配置环境变量,bash通过编辑~/.bash_profile来做同样的事
- 内省—beanutils工具包
Apache组织开发了一套用于操作JavaBean的API,这套API考虑到了很多实际开发中的应用场景,因此在实际开发中很多程序员使用这套API操作JavaBean,以简化程序代码的编写. BeanU ...
- MFC学习 消息钩子使用
HANDLE h_KeyBoard; //当前进程的钩子, 另外WH_KEYBOARD_LL, 与WH_MOUSE_LL参数时, 是获取的底层的消息, 相当于获取的全局的 g_hKeyBoard = ...