c#通过 wsdl调用Webservice 源码

1. 将网上查找的C# 通过WSDL调用WEBSERVICE代码整理如下:

   

 /// <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 = System.Environment.CurrentDirectory + "\\" + this._assName + getMd5Sum(this._wsdlUrl) + ".dll";


            MISLog.GetInstance().Write(MISLog.MSG_LEVEL.FLUSH, _assPath);
            if (wsdlUrl.Contains("?wsdl"))
            {
                this.CreateServiceAssembly();
            }
            else if (wsdlUrl.Contains(".dll"))
            {
                CreateDllAssembly();
            }
        }


        #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编译客户端代理类                   


                MISLog.GetInstance().Write(MISLog.MSG_LEVEL.FLUSH, "CodeNamespace");




                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;
                    }


                    MISLog.GetInstance().Write(MISLog.MSG_LEVEL.FLUSH, errors);
                }
                this.copyTempAssembly(result.PathToAssembly);
                this.initTypeName();
            }
            catch (Exception e)
            {
                MISLog.GetInstance().Write(MISLog.MSG_LEVEL.FLUSH, e.ToString());
            }
        }


        private void CreateDllAssembly()
        {            
            Assembly serviceAsm = Assembly.LoadFrom(System.Environment.CurrentDirectory + "\\" + _wsdlUrl);
            _typeName = serviceAsm.GetType(MISConfig.GetInstance().db.Database);
        }
        #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服务访问类名错误日志代码位置 
                    MISLog.GetInstance().Write(MISLog.MSG_LEVEL.FLUSH, "服务访问类名【" + this._wsdlName + "】不正确,请检查!");
                    System.Windows.Forms.MessageBox.Show(MultiLanguage.GetString("MIS_Connect_FAIL"));


                    return null;                   
                }
                //调用方法  
                MethodInfo mi = this._typeName.GetMethod(methodName);
                if (mi == null)
                {
                    //记录Web服务方法名错误日志代码位置  
                    MISLog.GetInstance().Write(MISLog.MSG_LEVEL.FLUSH, "Web服务访问方法名【" + methodName + "】不正确,请检查!");
                    System.Windows.Forms.MessageBox.Show(MultiLanguage.GetString("MIS_Connect_FAIL"));


                }
                try
                {
                    if (param == null)
                        rtnObj = mi.Invoke(Instance, null);
                    else
                    {
                        rtnObj = mi.Invoke(Instance, param);
                    }
                }
                catch (TypeLoadException tle)
                {
                    //记录Web服务方法参数个数错误日志代码位置  
                    MISLog.GetInstance().Write(MISLog.MSG_LEVEL.FLUSH, "Web服务访问方法【" + methodName + "】参数个数不正确,请检查!");
                     System.Windows.Forms.MessageBox.Show(MultiLanguage.GetString("MIS_Connect_FAIL"));
                     Log.GetInstance().WriteSYS(tle.ToString());
                }
            }
            catch (Exception ex)
            {
                MISLog.GetInstance().Write(MISLog.MSG_LEVEL.FLUSH, ex.ToString());
                System.Windows.Forms.MessageBox.Show(MultiLanguage.GetString("MIS_Connect_FAIL"));


            }
            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服务访问类名错误日志代码位置
                    MISLog.GetInstance().Write(MISLog.MSG_LEVEL.FLUSH, "Web服务访问类名【" + this._wsdlName + "】不正确,请检查!");
                    System.Windows.Forms.MessageBox.Show(MultiLanguage.GetString("MIS_Connect_FAIL"));
                    return;
                }
                //调用方法  
                MethodInfo mi = this._typeName.GetMethod(methodName);
                if (mi == null)
                {
                    //记录Web服务方法名错误日志代码位置  
                    MISLog.GetInstance().Write(MISLog.MSG_LEVEL.FLUSH, "Web服务访问方法名【" + methodName + "】不正确,请检查!");
                    System.Windows.Forms.MessageBox.Show(MultiLanguage.GetString("MIS_Connect_FAIL"));
                }
                try
                {
                    if (param == null)
                        mi.Invoke(Instance, null);
                    else
                        mi.Invoke(Instance, param);
                }
                catch (TypeLoadException tle)
                {
                    //记录Web服务方法参数个数错误日志代码位置  
                    MISLog.GetInstance().Write(MISLog.MSG_LEVEL.FLUSH, "Web服务访问方法【" + methodName + "】参数个数不正确,请检查!");
                    System.Windows.Forms.MessageBox.Show(MultiLanguage.GetString("MIS_Connect_FAIL"));
                    Log.GetInstance().WriteSYS(tle.ToString());
                }
            }
            catch (Exception ex)
            {
                MISLog.GetInstance().Write(MISLog.MSG_LEVEL.FLUSH, ex.ToString());
                System.Windows.Forms.MessageBox.Show(MultiLanguage.GetString("MIS_Connect_FAIL"));
            }
        }
        #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
    }


上面这部分可以直接使用。

2.下面这部分为网上看到类似的代码,并含有备注。用于备忘 【点击打开链接

public static class WebServiceHelper
       {
             /// <summary>
             /// 动态调用WebService
             /// </summary>
             /// <param name="url">WebService地址</param>
             /// <param name="methodname">方法名(模块名)</param>
             /// <param name="args">参数列表,无参数为null</param>
             /// <returns>object</returns>
             public static object InvokeWebService(string url, string methodname, object[] args)
             {
                   return InvokeWebService(url, null, methodname, args);
             }
             /// <summary>
             /// 动态调用WebService
             /// </summary>
             /// <param name="url">WebService地址</param>
             /// <param name="classname">类名</param>
             /// <param name="methodname">方法名(模块名)</param>
             /// <param name="args">参数列表</param>
             /// <returns>object</returns>
             public static object InvokeWebService(string url, string classname, string methodname, object[] args)
              {
                    string @namespace = "fangqm.Netbank.WebService.webservice";
                    if (classname == null || classname == "")
                    {
                          classname = WebServiceHelper.GetClassName(url);
                    }
                   //获取服务描述语言(WSDL)
                      WebClient wc = new WebClient();
                    Stream stream = wc.OpenRead(url+"?WSDL");//【1】
                   ServiceDescription sd = ServiceDescription.Read(stream);//【2】
                    ServiceDescriptionImport er sdi = new ServiceDescriptionImport er();//【3】
                    sdi.AddServiceDescription(sd, "", "");
                    CodeNamespace cn = new CodeNamespace(@namespace);//【4】
                    //生成客户端代理类代码
                    CodeCompileUnit ccu = new CodeCompileUnit();//【5】
                   ccu.Namespaces.Add(cn);
                    sdi.Import(cn, ccu);
                   CSharpCodeProvider csc = new CSharpCodeProvider();//【6】
                    ICodeCompiler icc = csc.CreateCompiler();//【7】
                    //设定编译器的参数
                    CompilerParameters cplist = new CompilerParameters();//【8】
                    cplist.GenerateExecutable = false;
                    cplist.GenerateInMemory = true;
                    cplist.ReferencedAssemblies.Add("System.dll");
                    cplist.ReferencedAssemblies.Add("System.XML.dll");
                    cplist.ReferencedAssemblies.Add("System.Web.Services.dll");
                    cplist.ReferencedAssemblies.Add("System.Data.dll");
                    //编译代理类
                    CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu);//【9】
                    if (true == cr.Errors.HasErrors)
                   {
  System.Text.StringBuilder sb = new StringBuilder();
                         foreach (CompilerError ce in cr.Errors)
                          {
                                sb.Append(ce.ToString());
                                sb.Append(System.Environment.NewLine);
                          }
                          throw new Exception(sb.ToString());
                    }
 
                   //生成代理实例,并调用方法
                    System.Reflection.Assembly assembly = cr.CompiledAssembly;
                    Type t = assembly.GetType(@namespace+"."+ classname, true, true);
                    object bj = Activator.CreateInstance(t);//【10】
                    System.Reflection.MethodInfo mi = t.GetMethod(methodname);//【11】
                    return mi.Invoke(obj, args);
 
              }
             private static string GetClassName(string url)
             {
                   //假如URL为"http://localhost/InvokeService/Service1.asmx"
                   //最终的返回值为 Service1
                   string[] parts = url.Split('/');
                   string[] pps = parts[parts.Length - 1].Split('.');
                   return pps[0];
             }
       }
}
 
  上面的注释已经很好的说明了各代码段的功能,下面给个例子看看,这个例子是通过访问http://www.webservicex.net/globalweather.asmx服务来获取各大城市的天气状况。
                    stringurl="http://www.webservicex.net/globalweather.asmx";
                   string[] args=newstring[2] ;
                    args[0]=this.textBox_CityName.Text ;
                    args[1]="China";
                   objectresult=WebServiceHelper.InvokeWebService(url ,"GetWeather",args) ;
                   this.label_Result.Text=result.ToString() ;
如果没有参数,则参数为null


        上述的例子中,调用web服务使用了两个参数,第一个是城市的名字,第二个是国家的名字,Web服务返回的是XML文档,可以从其中解析出温度、风力等天气情况。
      
     关于这段代码的注释

【2】      ServiceDescription类提供一种方法,以创建和格式化用于描述 XML Web services 的有效的 Web 服务描述语言 (WSDL) 文档文件,该文件是完整的,具有适当的命名空间、元素和特性。 无法继承此类。
ServiceDescription.Read 方法 (Stream) 通过直接从 Stream实例加载 XML 来初始化ServiceDescription类的实例。
  【3】      ServiceDescriptionImport er 类 公开一种为 XML Web services 生成客户端代理类的方法。
ServiceDescriptionImport er.AddServiceDescription 方法 将指定的ServiceDescription添加到要导入的ServiceDescriptions值的集合中。
  【4】    CodeNamespace表示命名空间声明。
  【5】    CodeCompileUnit会提供一个CodeDOM程式圆形的容器,CodeCompileUnit含有一个集合,可以储存含有CodeDOM原始程式码原形,专案参考的组件集合以及专案组件属性集合的CodeNamespace物件。
  【6】    CSharpCodeProvider类提供存取C#程式码产生器和程式码编译器的执行个体。
  【7】    取得C#程式码编译器的执行个体
  【8】    创建编译器的参数实例
  【9】    CompilerResults表示从编译器返回的编译结果。使用指定的编译器设定,根据CodeCompileUnit物件之指定阵列所包含的System.CodeDom树状结构,编译一个组件。
  【10】 Activator类包含特定的方法,用以在本地或从远程创建对象类型,或获取对现有远程对象的引用。无法继承此类Activator.CreateInstance 方法   使用与指定参数匹配程度最高的构造函数创建指定类型的实例。
  【11】 MethodInfo 的实例可以通过调用GetMethods或者Type对象或派生自Type的对象的GetMethod方法来获取,还可以通过调用表示泛型方法定义的 MethodInfo 的MakeGenericMethod方法来获取。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#调用WebService有三种方式:直接引用、引用wsdl和soap请求。如果开发者可以直接访问到webservice,可以使用直接引用的方式。在Visual Studio中,可以通过添加服务引用来直接引用webservice,系统会自动生成引用代码。然后可以实例化引用的webservice对象来使用。\[2\] 如果无法直接访问webservice,可以使用引用wsdl文件的方式。首先需要获取webservicewsdl文件,可以通过浏览器打开webservice服务,然后查看服务说明,这就是整个wsdl的内容。将wsdl文件保存为文本文件,然后将后缀名改为wsdl。在Visual Studio中,同样可以通过添加服务引用来引用wsdl文件,将wsdl文件的路径输入到URL中即可。然后可以实例化引用的webservice对象来使用。\[3\] 最后一种方式是使用SOAP请求来调用webservice。这种方式适用于无法直接引用webservicewsdl文件的情况。可以使用HttpPost请求来发送SOAP请求,并解析返回的SOAP响应。这种方式需要手动构建SOAP请求和解析SOAP响应,相对复杂一些。 总结起来,C#调用webservice可以通过直接引用、引用wsdl和soap请求三种方式来实现。具体选择哪种方式取决于开发者的需求和情况。 #### 引用[.reference_title] - *1* [【C#调用 webservice 的三种方法总结](https://blog.csdn.net/weixin_44231544/article/details/124922474)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [C#调用WebService的三种方式](https://blog.csdn.net/m0_43398336/article/details/105082177)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值