C # Call webservice,
We often encounter the situation that C # Calls webservice. Generally, if webservice is developed with vs + c #, the problem is generally not serious. Direct web reference and then the call will be OK. The process is as follows:
The following is a simple call.
However, if webservice is generated using JAVA, other languages, or other tools, it is often difficult to use vs + c # For calling, it is often the use of soap ui call, but the above method is used to call an error, often 500 error. When you contact the webservice provider, it is often said that the soap ui can be called. You cannot use the code to call anything. The problem lies in your call method.
This problem often occurs when we provide webservice to other companies. We used to think that the soap ui can be called, so the code can be called. However, after practice, we did not find a problem when calling our own webservice by writing a DEMO, because we cannot call our own webservice, or you cannot find the correct method to call. In this case, we need to consider whether the webservice that can be called by the soap ui must be called without any problems? Or what is the difference between the principle of webservice calling by soap ui and webservice calling by code?
Summary:
(1) The soap ui can be called successfully, and the Code may not be called successfully. The premise that the Code call is successful and the returned result is that webservice can return the result according to the standard, however, the soap ui can receive the result as long as it is returned by an envelope, regardless of whether the result is standard or not;
(2) If the webservice header has a user name and password verification, you can use the soap ui to call it successfully and get the returned results, but the web reference method above is not supported. In this case, the following methods can be called successfully:
Repeat the web reference method above and reference Microsoft. Web. Services3 (This DLL can be downloaded from CSDN ).
Manually modify Reference. cs
The following is the call method, which focuses on passing in the user name and password. This is also the focus of modifying the inheritance class;
After the reference is completed, the call succeeds. The result is as follows:
From the above we can see that web references are really simple and crude, and most webservice calls can be done without writing a few lines of code.
However, web references have some shortcomings that are often encountered in real development:
(1) The wsdl address that can be accessed by the development environment;
(2) update the web reference if the webservice changes;
Is there any other way? The answer is yes. One is to directly encapsulate the envelope and use WebRequest. The Code is as follows:
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>"); // user name 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>"); // 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 ;}}
However, the above method still has a problem. If webservice needs to verify the user name and password in the header, although the user name and password are encapsulated in the envelope, the same call fails, and the same envelope content, soap ui can be used successfully. It can be seen that there are some differences between code calls and soap ui calls.
Another way is to use dynamic compilation:
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); }
From this method, we can see that the first step is to access the wsdl address to retrieve the webservice structure, and then use dynamic compilation to generate a local assembly to call webservice, and the web Reference will automatically generate a Reference. the cs principle is similar, but this method also has problems. If the webservice header needs to verify the user name and password, how can this problem be solved?