C#动态加载web service
来源:互联网 发布:知乎 房地产文案 编辑:程序博客网 时间:2024/05/14 17:24
我有多个工程,其中一个工程A引用另外一个工程B的代码,而工程B应用了一个web服务。在B中的Config文件中定义了相关引用。但A工程却编译不了,抛出异常:
Could not find default endpoint element that references contract 'XXXX' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.
经查阅相关资料,原来每个使用到这个web服务的项目,都需要在自己的config文件中添加引用。这样就非常凌乱了。
于是,采用动态加载web服务的方法解决这个问题。
动态web服务相关类封装。可能会报错,记得添加引用web.services即可。
using System;using System.Collections;using System.ComponentModel;using System.Data;using System.Linq;using System.Web;using System.Web.Services;using System.Web.Services.Protocols;using System.Xml.Linq; using System.IO;using System.Net;using System.CodeDom;using System.CodeDom.Compiler;using System.Web.Services.Description;using System.Xml.Serialization;using System.Web.Services.Discovery;using System.Xml.Schema;using System.Text;using System.Security.Cryptography;using System.Reflection;using System.Collections.Generic;using System.Xml; namespace KangryUtils{ /// <summary> /// WebServiceProxy 的摘要说明 /// </summary> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [ToolboxItem(false)] // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。 // [System.Web.Script.Services.ScriptService] public class WebServiceProxy : System.Web.Services.WebService { #region 私有变量和属性定义 /// <summary> /// web服务地址 /// </summary> private string _wsdlUrl = string.Empty; /// <summary> /// web服务名称 /// </summary> private string _wsdlName = string.Empty; /// <summary> /// 代理类命名空间 /// </summary> private string _wsdlNamespace = "FrameWork.WebService.DynamicWebServiceCalling.{0}"; /// <summary> /// 代理类类型名称 /// </summary> private Type _typeName = null; /// <summary> /// 程序集名称 /// </summary> private string _assName = string.Empty; /// <summary> /// 代理类所在程序集路径 /// </summary> private string _assPath = string.Empty; /// <summary> /// 代理类的实例 /// </summary> private object _instance = null; /// <summary> /// 代理类的实例 /// </summary> private object Instance { get { if (_instance == null) { _instance = Activator.CreateInstance(_typeName); return _instance; } else return _instance; } } #endregion #region 构造函数 public WebServiceProxy(string wsdlUrl) { this._wsdlUrl = wsdlUrl; string wsdlName = WebServiceProxy.getWsclassName(wsdlUrl); this._wsdlName = wsdlName; this._assName = string.Format(_wsdlNamespace, wsdlName); this._assPath = Path.GetTempPath() + this._assName + getMd5Sum(this._wsdlUrl) + ".dll"; this.CreateServiceAssembly(); } public WebServiceProxy(string wsdlUrl, string wsdlName) { this._wsdlUrl = wsdlUrl; this._wsdlName = wsdlName; this._assName = string.Format(_wsdlNamespace, wsdlName); this._assPath = Path.GetTempPath() + this._assName + getMd5Sum(this._wsdlUrl) + ".dll"; this.CreateServiceAssembly(); } #endregion #region 得到WSDL信息,生成本地代理类并编译为DLL,构造函数调用,类生成时加载 /// <summary> /// 得到WSDL信息,生成本地代理类并编译为DLL /// </summary> private void CreateServiceAssembly() { if (this.checkCache()) { this.initTypeName(); return; } if (string.IsNullOrEmpty(this._wsdlUrl)) { return; } try { //使用WebClient下载WSDL信息 WebClient web = new WebClient(); Stream stream = web.OpenRead(this._wsdlUrl); ServiceDescription description = ServiceDescription.Read(stream);//创建和格式化WSDL文档 ServiceDescriptionImporter importer = new ServiceDescriptionImporter();//创建客户端代理代理类 importer.ProtocolName = "Soap"; importer.Style = ServiceDescriptionImportStyle.Client; //生成客户端代理 importer.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync; importer.AddServiceDescription(description, null, null);//添加WSDL文档 //使用CodeDom编译客户端代理类 CodeNamespace nmspace = new CodeNamespace(_assName); //为代理类添加命名空间 CodeCompileUnit unit = new CodeCompileUnit(); unit.Namespaces.Add(nmspace); this.checkForImports(this._wsdlUrl, importer); ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit); CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp"); CompilerParameters parameter = new CompilerParameters(); parameter.ReferencedAssemblies.Add("System.dll"); parameter.ReferencedAssemblies.Add("System.XML.dll"); parameter.ReferencedAssemblies.Add("System.Web.Services.dll"); parameter.ReferencedAssemblies.Add("System.Data.dll"); parameter.GenerateExecutable = false; parameter.GenerateInMemory = false; parameter.IncludeDebugInformation = false; CompilerResults result = provider.CompileAssemblyFromDom(parameter, unit); provider.Dispose(); if (result.Errors.HasErrors) { string errors = string.Format(@"编译错误:{0}错误!", result.Errors.Count); foreach (CompilerError error in result.Errors) { errors += error.ErrorText; } throw new Exception(errors); } this.copyTempAssembly(result.PathToAssembly); this.initTypeName(); } catch (Exception e) { throw new Exception(e.Message); } } #endregion #region 执行Web服务方法 /// <summary> /// 执行代理类指定方法,有返回值 /// </summary> /// <param name="methodName">方法名称</param> /// <param name="param">参数</param> /// <returns>object</returns> public object ExecuteQuery(string methodName, object[] param) { object rtnObj = null; try { if (this._typeName == null) { //记录Web服务访问类名错误日志代码位置 throw new TypeLoadException("Web服务访问类名【" + this._wsdlName + "】不正确,请检查!"); } //调用方法 MethodInfo mi = this._typeName.GetMethod(methodName); if (mi == null) { //记录Web服务方法名错误日志代码位置 throw new TypeLoadException("Web服务访问方法名【" + methodName + "】不正确,请检查!"); } try { if (param == null) rtnObj = mi.Invoke(Instance, null); else { rtnObj = mi.Invoke(Instance, param ); } } catch (TypeLoadException tle) { //记录Web服务方法参数个数错误日志代码位置 throw new TypeLoadException("Web服务访问方法【" + methodName + "】参数个数不正确,请检查!", new TypeLoadException(tle.StackTrace)); } } catch (Exception ex) { throw new Exception(ex.Message, new Exception(ex.StackTrace)); } return rtnObj; } /// <summary> /// 执行代理类指定方法,无返回值 /// </summary> /// <param name="methodName">方法名称</param> /// <param name="param">参数</param> public void ExecuteNoQuery(string methodName, object[] param) { try { if (this._typeName == null) { //记录Web服务访问类名错误日志代码位置 throw new TypeLoadException("Web服务访问类名【" + this._wsdlName + "】不正确,请检查!"); } //调用方法 MethodInfo mi = this._typeName.GetMethod(methodName); if (mi == null) { //记录Web服务方法名错误日志代码位置 throw new TypeLoadException("Web服务访问方法名【" + methodName + "】不正确,请检查!"); } try { if (param == null) mi.Invoke(Instance, null); else mi.Invoke(Instance, param); } catch (TypeLoadException tle) { //记录Web服务方法参数个数错误日志代码位置 throw new TypeLoadException("Web服务访问方法【" + methodName + "】参数个数不正确,请检查!", new TypeLoadException(tle.StackTrace)); } } catch (Exception ex) { throw new Exception(ex.Message, new Exception(ex.StackTrace)); } } #endregion #region 私有方法 /// <summary> /// 得到代理类类型名称 /// </summary> private void initTypeName() { Assembly serviceAsm = Assembly.LoadFrom(this._assPath); Type[] types = serviceAsm.GetTypes(); string objTypeName = ""; foreach (Type t in types) { if (t.BaseType == typeof(SoapHttpClientProtocol)) { objTypeName = t.Name; break; } } _typeName = serviceAsm.GetType(this._assName + "." + objTypeName); } /// <summary> /// 根据web service文档架构向代理类添加ServiceDescription和XmlSchema /// </summary> /// <param name="baseWSDLUrl">web服务地址</param> /// <param name="importer">代理类</param> private void checkForImports(string baseWsdlUrl, ServiceDescriptionImporter importer) { DiscoveryClientProtocol dcp = new DiscoveryClientProtocol(); dcp.DiscoverAny(baseWsdlUrl); dcp.ResolveAll(); foreach (object osd in dcp.Documents.Values) { if (osd is ServiceDescription) importer.AddServiceDescription((ServiceDescription)osd, null, null); ; if (osd is XmlSchema) importer.Schemas.Add((XmlSchema)osd); } } /// <summary> /// 复制程序集到指定路径 /// </summary> /// <param name="pathToAssembly">程序集路径</param> private void copyTempAssembly(string pathToAssembly) { File.Copy(pathToAssembly, this._assPath); } private string getMd5Sum(string str) { Encoder enc = System.Text.Encoding.Unicode.GetEncoder(); byte[] unicodeText = new byte[str.Length * 2]; enc.GetBytes(str.ToCharArray(), 0, str.Length, unicodeText, 0, true); MD5 md5 = new MD5CryptoServiceProvider(); byte[] result = md5.ComputeHash(unicodeText); StringBuilder sb = new StringBuilder(); for (int i = 0; i < result.Length; i++) { sb.Append(result[i].ToString("X2")); } return sb.ToString(); } /// <summary> /// 是否已经存在该程序集 /// </summary> /// <returns>false:不存在该程序集,true:已经存在该程序集</returns> private bool checkCache() { if (File.Exists(this._assPath)) { return true; } return false; } //私有方法,默认取url入口的文件名为类名 private static string getWsclassName(string wsdlUrl) { string[] parts = wsdlUrl.Split('/'); string[] pps = parts[parts.Length - 1].Split('.'); return pps[0]; } #endregion }}使用方法如下:
WebServiceProxy wsd = new WebServiceProxy("url链接", "方法名");string[] args = { "参数1", "参数2" };pageHtml = (string)wsd.ExecuteQuery("方法名", args); //返回的是一个对象参考链接:
http://heisetoufa.iteye.com/blog/1684456
http://stackoverflow.com/questions/352654/could-not-find-default-endpoint-element
0 0
- C#动态加载web service
- [WEBSERVICE]动态加载Web Service
- C# Winform动态调用Web Service
- c#动态传递URL到Web Service
- 动态调用Web Service
- 动态调用web service
- 动态调用Web Service
- 动态引用Web Service
- c#创建Web Service
- C#调用 Web Service
- c# web service
- C# Web Service 学习
- C# Web Service
- C#动态加载DLL
- C#动态加载DLL
- C# 动态加载类
- C#动态加载DLL
- C#动态加载DLL
- 成为专业程序员的6个技巧---心灵鸡汤
- ios 语音识别
- Android Studio讲解二、快捷键和常用插件
- 深入浅出MIPS 三 MIPS的协处理器CP0 (Section 1)
- Android Fragment 真正的完全解析(上)
- C#动态加载web service
- Android Studio入门到精通
- iOS每日小结-01续
- Eclipse快捷键10个最有用的快捷键
- URLConnection的连接、超时、关闭用法总结(转载)
- JAVA 大数值
- KVO实现原理
- linux下的find文件查找命令与grep文件内容查找命令
- laravel5.0学习系列1之 路由