C# 调用WebService的方法

简介: 原文:C# 调用WebService的方法 很少用C#动态的去调用Web Service,一般都是通过添加引用的方式,这样的话是自动成了代理,那么动态代理调用就是我们通过代码去调用这个WSDL,然后自己去生成客户端代理。
原文: 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; }

 

目录
相关文章
|
1月前
|
Java 调度 C#
C#学习系列相关之多线程(一)----常用多线程方法总结
C#学习系列相关之多线程(一)----常用多线程方法总结
|
1月前
|
C#
C#学习相关系列之数组---常用方法使用(二)
C#学习相关系列之数组---常用方法使用(二)
|
1月前
|
存储 C# 数据库
C# 生成唯一ID,有哪些方法?
【2月更文挑战第12天】
151 0
|
3月前
|
编译器 C# 开发者
C# 11.0中的新特性:覆盖默认接口方法
C# 11.0进一步增强了接口的灵活性,引入了覆盖默认接口方法的能力。这一新特性允许类在实现接口时,不仅可以提供接口中未实现的方法的具体实现,还可以覆盖接口中定义的默认方法实现。本文将详细介绍C# 11.0中接口默认方法覆盖的工作原理、使用场景及其对现有代码的影响,帮助开发者更好地理解和应用这一新功能。
|
3月前
|
存储 C#
C# 方法详解:定义、调用、参数、默认值、返回值、命名参数、方法重载全解析
方法是一段代码,只有在调用时才会运行。 您可以将数据(称为参数)传递给方法。 方法用于执行某些操作,也被称为函数。 为什么使用方法?为了重用代码:定义一次代码,然后多次使用。
41 1
|
1月前
|
C#
C#学习相关系列之数据类型类----嵌套类和嵌套方法(三)
C#学习相关系列之数据类型类----嵌套类和嵌套方法(三)
|
1月前
|
开发框架 .NET C#
C#学习相关系列之Linq常用方法---排序(一)
C#学习相关系列之Linq常用方法---排序(一)
|
1月前
|
开发框架 .NET 编译器
C#学习相关系列之匿名方法和Lambda表达式
C#学习相关系列之匿名方法和Lambda表达式
|
1月前
|
XML 开发框架 .NET
C# .NET面试系列八:ADO.NET、XML、HTTP、AJAX、WebService
## 第二部分:ADO.NET、XML、HTTP、AJAX、WebService #### 1. .NET 和 C# 有什么区别? .NET(通用语言运行时): ```c# 定义:.NET 是一个软件开发框架,提供了一个通用的运行时环境,用于在不同的编程语言中执行代码。 作用:它为多语言支持提供了一个统一的平台,允许不同的语言共享类库和其他资源。.NET 包括 Common Language Runtime (CLR)、基础类库(BCL)和其他工具。 ``` C#(C Sharp): ```c# 定义: C# 是一种由微软设计的面向对象的编程语言,专门为.NET 平台开发而创建。 作
174 2
|
1月前
|
C#
C#中保留小数点后N位的方法_kaic
C#中保留小数点后N位的方法_kaic