给定了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); }