C# 調用WebService的方法


很少用C#動態的去調用Web Service,一般都是通過添加引用的方式,這樣的話是自動成了代理,那么動態代理調用就是我們通過代碼去調用這個WSDL,然后自己去生成客戶端代理。更多的內容可以看下面的兩個地址:
http://blog.csdn.net/limlimlim/article/details/8651043

http://www.cnblogs.com/VisualStudio/archive/2008/10/29/1322228.html
1.動態調用的url后面注意一定要加上?WSDL 例如:string _url = "http://服務器IP:端口/CITI_TRANS_WH/wsTransData_InWH.asmx?WSDL"; --------------------------------------------------------------------------------------------------- 2.WebService中傳遞List泛型對象 [WebMethod] public List<TestModel> TestTransDataByClass(int _max) 注意TestModel必須是可以序列化的類 //必須可序列化 [Serializable] public class TestModel { public int No { get; set; } public string Des { get; set; } } --------------------------------------------------------------------------------------------------- 3.WebService中不能直接傳遞輸出dictionary<string,object>這樣的泛型對象,必須自定義一個類來輸出,這個類同樣也是可以序列化的 [Serializable] public class MyDictionary { public List<TestModel> Table1 { get; set; } public List<TestModel2> Table2 { get; set; } } --------------------------------------------------------------------------------------------------- 4.動態調用WebService的類封裝 public static class InvokeWebServiceDynamic { /// <summary> /// 動態調用WebService /// </summary> /// <param name="_url">web服務url地址</param> /// <param name="_methodName">web服務中的方法</param> /// <param name="_params">傳遞給方法的參數</param> /// <returns></returns> public static object InvokeWebMethod(string _url ,string _methodName, params object[] _params) { WebClient client = new WebClient(); //String url = "http://localhost:3182/Service1.asmx?WSDL";//這個地址可以寫在Config文件里面 Stream stream = client.OpenRead(_url); ServiceDescription description = ServiceDescription.Read(stream); ServiceDescriptionImporter importer = new ServiceDescriptionImporter();//創建客戶端代理代理類。 importer.ProtocolName = "Soap"; //指定訪問協議。 importer.Style = ServiceDescriptionImportStyle.Client; //生成客戶端代理。 importer.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync; importer.AddServiceDescription(description, null, null); //添加WSDL文檔。 CodeNamespace nmspace = new CodeNamespace(); //命名空間 nmspace.Name = "TestWebService"; //這個命名空間可以自己取 CodeCompileUnit unit = new CodeCompileUnit(); unit.Namespaces.Add(nmspace); ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit); CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp"); CompilerParameters parameter = new CompilerParameters(); parameter.GenerateExecutable = false; parameter.OutputAssembly = "MyTest.dll";//輸出程序集的名稱 parameter.ReferencedAssemblies.Add("System.dll"); parameter.ReferencedAssemblies.Add("System.XML.dll"); parameter.ReferencedAssemblies.Add("System.Web.Services.dll"); parameter.ReferencedAssemblies.Add("System.Data.dll"); CompilerResults result = provider.CompileAssemblyFromDom(parameter, unit); if (result.Errors.HasErrors) { // 顯示編譯錯誤信息 } Assembly asm = Assembly.LoadFrom("MyTest.dll");//加載前面生成的程序集 Type t = asm.GetType("TestWebService.wsTransData_InWH"); //前面的命名空間.類名,類必須是webservice中定義的 object o = Activator.CreateInstance(t); MethodInfo method = t.GetMethod(_methodName);//GetPersons是服務端的方法名稱,你想調用服務端的什么方法都可以在這里改,最好封裝一下 object item = method.Invoke(o, _params); //注:method.Invoke(o, null)返回的是一個Object,如果你服務端返回的是DataSet,這里也是用(DataSet)method.Invoke(o, null)轉一下就行了 //foreach (string str in item) // Console.WriteLine(str); //上面是根據WebService地址,模似生成一個代理類,如果你想看看生成的代碼文件是什么樣子,可以用以下代碼保存下來,默認是保存在bin目錄下面 //TextWriter writer = File.CreateText("MyTest.cs"); //provider.GenerateCodeFromCompileUnit(unit, writer, null); //writer.Flush(); //writer.Close(); return item; } } --------------------------------------------------------------------------------------------------- 5.通過反射提取web方法返回的自定義類數據 說明: <1>.WebService方法TestTransDataByDic返回自定義的MyDictionary對象 <2>.它包含兩個屬性table1,table2 <3>.類定義代碼如下 [Serializable] public class MyDictionary { public List<TestModel> Table1 { get; set; } public List<TestModel2> Table2 { get; set; } } <4>.客戶端調用代碼 private void InvokeDic_Click(object sender, EventArgs e) { //要注意加?WSDL //string _url = "http://localhost:58764/wsTransData_InWH.asmx?WSDL"; int _count = int.Parse(txtCount.Text); object o = InvokeWebServiceDynamic.InvokeWebMethod(_url, "TestTransDataByDic", new object[] { _count }); PropertyInfo _propertyTable1 = o.GetType().GetProperty("Table1"); PropertyInfo _propertyTable2 = o.GetType().GetProperty("Table2"); //讀取Table1屬性中的數據 object[] _table1Items = (object[])_propertyTable1.GetValue(o, null); if(_table1Items.Length>0) { lstData1.Visible = false; lstData1.Items.Clear(); //反射出對象TestModel的屬性 PropertyInfo _propertyNo = _table1Items[0].GetType().GetProperty("No"); PropertyInfo _propertyDes = _table1Items[0].GetType().GetProperty("Des"); for (int i = 0; i < _table1Items.Length; i++) { //根據屬性取值 string _no = _propertyNo.GetValue(_table1Items[i], null).ToString(); string _des = _propertyDes.GetValue(_table1Items[i], null).ToString(); string _format = string.Format("第{0}條:{1}", _no, _des); lstData1.Items.Add(_format); } lstData1.Visible = true; } //讀取Table2屬性中的數據 object[] _table2Items = (object[])_propertyTable2.GetValue(o, null); if (_table2Items.Length > 0) { lstData2.Visible = false; lstData2.Items.Clear(); //反射出對象TestModel2的屬性 PropertyInfo _propertyMyFNo = _table2Items[0].GetType().GetProperty("MyFNo"); PropertyInfo _propertyMyFDes = _table2Items[0].GetType().GetProperty("MyFDes"); for (int i = 0; i < _table1Items.Length; i++) { //根據屬性取值 string _no = _propertyMyFNo.GetValue(_table2Items[i], null).ToString(); string _des = _propertyMyFDes.GetValue(_table2Items[i], null).ToString(); string _format = string.Format("第{0}條:{1}", _no, _des); lstData2.Items.Add(_format); } lstData2.Visible = true; } MessageBox.Show("OK"); } --------------------------------------------------------------------------------------------------- 6.客戶端傳遞序列化對象給webserice方法 /// <summary> /// /// </summary> /// <param name="_dicGet">是一個客戶端傳過來的序列化的對象</param> /// <returns></returns> [WebMethod] public string TestInsertData(byte[] _dicGet) { //反序列化對象 object _dicGetOK = SqlHelper.DeserializeObject(_dicGet); return "ok"; } 注意: <1>.創建一個.NET類庫,把要傳輸的對象做成一個結構或類放在類庫(假設為ClassLib.dll)中。如: <2>.然后在客戶端程序和webservice項目中都引用ClassLib.dll <3>.上面兩步的目的是讓客戶端序列化的對象,在webservice服務端能正常反序列化,不會出現反序列化時找不到命名空間的問題 --------------------------------------------------------------------------------------------------- 7.修改webserivce最大傳輸的長度 <?xml version="1.0" encoding="utf-8"?> <!-- 有關如何配置 ASP.NET 應用程序的詳細消息,請訪問 http://go.microsoft.com/fwlink/?LinkId=169433 --> <configuration> <connectionStrings> <add name="ConStr" connectionString="$(ReplacableToken_ConStr-Web.config Connection String_0)"/> </connectionStrings> <system.web> <compilation debug="true" targetFramework="4.0" /> <httpRuntime maxRequestLength="2147483647" /> </system.web> </configuration> 8.修改webservice的超時時間 <?xml version="1.0" encoding="utf-8"?> <!-- 有關如何配置 ASP.NET 應用程序的詳細消息,請訪問 executionTimeout="120" 超時時間120秒 maxRequestLength="2147483647" 最大請求長度 http://go.microsoft.com/fwlink/?LinkId=169433 --> <configuration> <connectionStrings> <add name="ConStr" connectionString="Data Source=192.128.58.248;Initial catalog=Citibank_test;Uid=sa;pwd=kicpassword"/> </connectionStrings> <system.web> <compilation debug="true" targetFramework="4.0" /> <httpRuntime maxRequestLength="2147483647" executionTimeout="240" /> </system.web> </configuration> 9.序列化,反序列化方法 public static byte[] SerializeObject(object pObj) { if (pObj == null) return null; System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(memoryStream, pObj); memoryStream.Position = 0; byte[] read = new byte[memoryStream.Length]; memoryStream.Read(read, 0, read.Length); memoryStream.Close(); return read; } public static object DeserializeObject(byte[] pBytes) { object newOjb = null; if (pBytes == null) { return newOjb; } System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(pBytes); memoryStream.Position = 0; BinaryFormatter formatter = new BinaryFormatter(); newOjb = formatter.Deserialize(memoryStream); memoryStream.Close(); return newOjb; }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM