C#調用webservice

來源:互聯網
上載者:User

標籤:自動   exe   toe   處理   param   bytes   []   byte   sdn   

經常遇到C#調用webservice的情況,通常來說如果webservice是用vs+c#來開發的,問題一般來說不大,直接web引用,然後調用就OK了。流程如下:

 

 

 

 

下面就是進行調用,就這麼簡單。

但如果webservice是用JAVA或者其它語言或者其它工具產生的話,使用vs+c#來調用就經常遇到問題;就是使用上面的方法顯得很不好使,經常是使用SOAP UI調用沒有問題,但使用上面的方法卻調用報錯,經常是500的錯誤。當你聯絡webservice供應商時通常會說SOAP UI都能調用得到,你們用代碼為啥子調用不到,問題出在你們的調用方法上。

在我們向其它公司提供webservice的時候,經常也會出現這樣的問題,以前我們一直都以為SOAP UI能夠調用,那麼代碼也就一定能夠調用得通,但經過實踐,我們自己寫DEMO調用自己的webservice時才發現,並不是別人的調用代碼寫的有問題,因為我們自己也無法將自己寫的webservice調用得通,或者說沒有找到正確的方法調用得通。這時我們就要思考是否是SOAP UI能夠調用得通的webservice就代碼一定調用沒有問題呢?或者說SOAP UI調用webservice和代碼調用webservice的原理區別到底在哪裡呢?

 

總結一下:

(1)SOAP UI能夠調用成功,代碼不一定能夠調用成功,代碼調用成功並且得到返回結果的前提是webservice可以按標準返回結果,但SOAP UI是只要按信封返回就可以收到結果而不管結果是否標準;

(2)如果webservice的header有使用者名稱和密碼的校正,使用SOAP UI可以調用成功並且得到返回結果,但使用上面web引用的方式卻不行。對於這種情況,有以下方法可以調用成功:

重複上面web引用的方式,另外引用Microsoft.Web.Services3(這個DLL可以CSDN上面下載)。

手工修改Reference.cs

 

以下是調用方法,重點在傳入使用者名稱和密碼,修改繼承類的重點也在於此;

引用完成,調用就會成功了,結果如下:

 

從上面可以看出web引用真的是簡單粗暴,基本不用寫幾句代碼就可以搞定絕大部分的webservice調用。

 

但是web引用卻有在現實開發中常遇到的缺點:

(1)需要開發環境可以訪問到的wsdl地址;

(2)如果webservice有變化需要更新web引用;

 

那有沒有其它方法呢?答案是有的。一種是直接封裝信封,使用WebRequest,代碼如下:

        private void button2_Click(object sender, EventArgs e)        {            StringBuilder soap = new StringBuilder();            soap.Append("<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:zls=\"www.zlsoft.cn\">");            soap.Append("<soap:Header>");            soap.Append("<wsse:Security soap:mustUnderstand=\"true\" xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\" xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\">");            soap.Append("<wsse:UsernameToken wsu:Id=\"UsernameToken-4\">");            soap.Append("<wsse:Username>hjq</wsse:Username>");//使用者名稱            soap.Append("<wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\">123</wsse:Password>");//口令            soap.Append("<wsse:Nonce EncodingType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary\">gC6dDGKjxo0IaRc5KpQU3w==</wsse:Nonce>");            soap.Append("<wsu:Created>2017-11-01T05:11:22.805Z</wsu:Created>");            soap.Append("</wsse:UsernameToken>");            soap.Append("</wsse:Security>");            soap.Append("</soap:Header>");            soap.Append("<soap:Body>");            soap.Append("<zls:getUserInfo>");            soap.Append("<zls:appsys_id>trwetre</zls:appsys_id>");            soap.Append("<zls:appsys_token>sdafdsf</zls:appsys_token>");            soap.Append("<zls:sid>fdsafds</zls:sid>");            soap.Append("</zls:getUserInfo>");            soap.Append("</soap:Body>");            soap.Append("</soap:Envelope>");            string url = "http://127.0.0.1:6998/services/HIPService?wsdl";            var result = GetSOAPReSource(url, soap.ToString());        }         public static string GetSOAPReSource(string url, string datastr)         {             try             {                 //request                 Uri uri = new Uri(url);                 WebRequest webRequest = WebRequest.Create(uri);                webRequest.ContentType = "application/soap+xml; charset=utf-8";                 webRequest.Method = "POST";                 using (Stream requestStream = webRequest.GetRequestStream())                 {                    byte[] paramBytes = Encoding.UTF8.GetBytes(datastr.ToString());                     requestStream.Write(paramBytes, 0, paramBytes.Length);                 }                 //response                 WebResponse webResponse = webRequest.GetResponse();                 using (StreamReader myStreamReader = new StreamReader(webResponse.GetResponseStream(), Encoding.UTF8))                 {                     string result = "";                     return result = myStreamReader.ReadToEnd();                }              }             catch (Exception ex)             {                 throw ex;             }          }

但是上述方式還是存在問題,如果webservice需要校正header裡面的使用者名稱與密碼時,雖然信封中封裝了使用者名稱和密碼,但是一樣調用不成功,同樣的信封內容,使用SOAP UI卻能成功。可見代碼調用和SOAP UI調用還是有一定區別的。

 

另外一種方式是使用動態編譯:

                Uri uri = new Uri(txt_url.Text);                WebRequest webRequest = WebRequest.Create(uri);                webRequest.Credentials = new NetworkCredential("hjq", "123");                System.IO.Stream requestStream = webRequest.GetResponse().GetResponseStream();                // Get a WSDL file describing a service                ServiceDescription sd = ServiceDescription.Read(requestStream);                string sdName = sd.Services[0].Name;                // Add in tree view                // Initialize a service description servImport                ServiceDescriptionImporter servImport = new ServiceDescriptionImporter();                servImport.AddServiceDescription(sd, String.Empty, String.Empty);                servImport.ProtocolName = "Soap";                servImport.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties;                CodeNamespace nameSpace = new CodeNamespace();                CodeCompileUnit codeCompileUnit = new CodeCompileUnit();                codeCompileUnit.Namespaces.Add(nameSpace);                // Set Warnings                ServiceDescriptionImportWarnings warnings = servImport.Import(nameSpace, codeCompileUnit);                if (warnings == 0)                {                    StringWriter stringWriter = new StringWriter(System.Globalization.CultureInfo.CurrentCulture);                    Microsoft.CSharp.CSharpCodeProvider prov = new Microsoft.CSharp.CSharpCodeProvider();                    prov.GenerateCodeFromNamespace(nameSpace, stringWriter, new CodeGeneratorOptions());                    // Compile the assembly with the appropriate references                    //string[] assemblyReferences = new string[2] { "System.Web.Services.dll", "System.Xml.dll" };                    string[] assemblyReferences = new string[3] {"System.dll", "System.dll", "System.dll" };                    CompilerParameters param = new CompilerParameters(assemblyReferences);                    param.GenerateExecutable = false;                    param.GenerateInMemory = true;                    param.TreatWarningsAsErrors = false;                    param.WarningLevel = 4;                    CompilerResults results = new CompilerResults(new TempFileCollection());                    results = prov.CompileAssemblyFromDom(param, codeCompileUnit);                    Assembly assembly = results.CompiledAssembly;                    Type service = assembly.GetType(sdName);                    MethodInfo[] methodInfo = service.GetMethods();                    foreach (MethodInfo t in methodInfo)                    {                        if (t.Name == "Discover")                            break;                        if (t.Name == cbMethods.Text)                        {                            //MessageBox.Show(t.ToString());                            //Invoke Method                                                        Object obj = Activator.CreateInstance(service);                            Object response = t.Invoke(obj, new object[] { "1","2","3"});                            MessageBox.Show("Result = " + response.ToString());                            break;                        }                    }                }            }            catch (Exception ex)            {                MessageBox.Show(ex.Message);            }

從這種方式可以看出,首先是訪問wsdl的地址取回webservice的結構,然後採取動態編譯產生本地程式集的方式去調用webservice,和web引用自動產生Reference.cs的原理類似;但是明顯這種方式也存在問題,如果webservice的header中需要校正使用者名稱與密碼怎麼處理呢?

C#調用webservice

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.