using System; using System.CodeDom; using System.CodeDom.Compiler; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Reflection; using System.Text; using System.Web.Services.Description; using System.Xml.Serialization; using Microsoft.CSharp; namespace POSV.Helper { /// /// 动态WebService服务类 /// /// /// SoapHelper oSoap = new SoapHelper("http://www.webxml.com.cn/WebServices/WeatherWS.asmx", "WeatherWS"); /// object oReturn = oSoap.Invoke("getWeather", new object[] { "3118", "1383" }); /// public class SoapHelper { private string WebServiceUrl { get; set; } private string WebServiceNamespace { get; set; } private string WebServiceClassname { get; set; } private CodeCompileUnit SoapCompileUnit; private CodeDomProvider SoapCodeProvider; private CompilerResults SoapCompilerResults; /// /// 动态 WebService 构造函数 /// /// WebService 地址 /// 类名,可省略,可空 public SoapHelper(string pUrl, string pClassname = null) { if (String.IsNullOrEmpty(pClassname)) WebServiceClassname = GetWsClassName(pUrl); else WebServiceClassname = pClassname; WebServiceNamespace = "POSV.Helper"; try { WebClient wc = new WebClient(); Stream stream = wc.OpenRead(pUrl + "?WSDL"); ServiceDescription sd = ServiceDescription.Read(stream); ServiceDescriptionImporter sdi = new ServiceDescriptionImporter(); sdi.AddServiceDescription(sd, "", ""); sdi.ProtocolName = "Soap"; sdi.Style = ServiceDescriptionImportStyle.Client; sdi.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync; CodeNamespace cn = new CodeNamespace(this.WebServiceNamespace); SoapCompileUnit = new CodeCompileUnit(); SoapCompileUnit.Namespaces.Add(cn); sdi.Import(cn, SoapCompileUnit); CSharpCodeProvider csc = new CSharpCodeProvider(); SoapCodeProvider = CodeDomProvider.CreateProvider("CSharp"); CompilerParameters cparam = new CompilerParameters(); cparam.GenerateExecutable = false; cparam.GenerateInMemory = true; cparam.ReferencedAssemblies.Add("System.dll"); cparam.ReferencedAssemblies.Add("System.XML.dll"); cparam.ReferencedAssemblies.Add("System.Web.Services.dll"); cparam.ReferencedAssemblies.Add("System.Data.dll"); SoapCompilerResults = SoapCodeProvider.CompileAssemblyFromDom(cparam, SoapCompileUnit); if (SoapCompilerResults.Errors.HasErrors) { StringBuilder sb = new StringBuilder(); foreach (CompilerError ce in SoapCompilerResults.Errors) { sb.Append(ce.ToString()); sb.Append(Environment.NewLine); } throw new Exception(sb.ToString()); } } catch (Exception ex) { throw new Exception(ex.InnerException.Message, new Exception(ex.InnerException.StackTrace)); } } /// /// 析构函数,ToDo 如何清理 /// ~SoapHelper() { } /// /// 调用远程方法 /// /// 方法名 /// 参数集 /// 调用结果 public object Invoke(string pMethodName, object[] pArgs) { Assembly assembly = SoapCompilerResults.CompiledAssembly; Type type = assembly.GetType(this.WebServiceNamespace + "." + this.WebServiceClassname, true, true); Object instance = Activator.CreateInstance(type); MethodInfo mi = type.GetMethod(pMethodName); return mi.Invoke(instance, pArgs); } /// /// 用于测试,根据WebService地址,模似生成一个代理类,生成的代码可以用以下方法保存下来,默认是保存在bin目录下面 /// public void ExportCShareFile() { //上面是 TextWriter writer = File.CreateText("MyWebServiceFile.cs"); SoapCodeProvider.GenerateCodeFromCompileUnit(SoapCompileUnit, writer, null); writer.Flush(); writer.Close(); } /// /// 如果构造时没有提供类名,则分解URL中的类名 /// /// WebService 地址 /// 类名 private string GetWsClassName(string pUrl) { string[] parts = pUrl.Split('/'); string[] pps = parts[parts.Length - 1].Split('.'); return pps[0]; } } }