C# 调用WebService的方法

简介: 很少用C#动态的去调用Web Service,一般都是通过添加引用的方式,这样的话是自动成了代理,那么动态代理调用就是我们通过代码去调用这个WSDL,然后自己去生成客户端代理。更多的内容可以看下面的两个地址:http://blog.
很少用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; }

 

相关文章
|
2月前
|
开发框架 .NET 程序员
C# 去掉字符串最后一个字符的 4 种方法
在实际业务中,我们经常会遇到在循环中拼接字符串的场景,循环结束之后拼接得到的字符串的最后一个字符往往需要去掉,看看 C# 提供了哪4种方法可以高效去掉字符串的最后一个字符
299 0
|
1月前
|
编译器 C#
C#多态概述:通过继承实现的不同对象调用相同的方法,表现出不同的行为
C#多态概述:通过继承实现的不同对象调用相同的方法,表现出不同的行为
116 65
|
11天前
|
JSON 程序员 C#
使用 C# 比较两个对象是否相等的7个方法总结
比较对象是编程中的一项基本技能,在实际业务中经常碰到,比如在ERP系统中,企业的信息非常重要,每一次更新,都需要比较记录更新前后企业的信息,直接比较通常只能告诉我们它们是否指向同一个内存地址,那我们应该怎么办呢?分享 7 个方法给你!
|
13天前
|
C# UED SEO
C# 异步方法async / await任务超时处理
通过使用 `Task.WhenAny`和 `Task.Delay`方法,您可以在C#中有效地实现异步任务的超时处理机制。这种方法允许您在指定时间内等待任务完成,并在任务超时时采取适当的措施,如抛出异常或执行备用操作。希望本文提供的详细解释和代码示例能帮助您在实际项目中更好地处理异步任务超时问题,提升应用程序的可靠性和用户体验。
41 3
|
1月前
|
存储 C#
【C#】大批量判断文件是否存在的两种方法效率对比
【C#】大批量判断文件是否存在的两种方法效率对比
40 1
|
1月前
|
C#
C#的方法的参数传递
C#的方法的参数传递
18 0
|
1月前
|
数据可视化 程序员 C#
C#中windows应用窗体程序的输入输出方法实例
C#中windows应用窗体程序的输入输出方法实例
46 0
|
2月前
|
C#
C#一分钟浅谈:Lambda 表达式和匿名方法
本文详细介绍了C#编程中的Lambda表达式与匿名方法,两者均可用于定义无名函数,使代码更简洁易维护。文章通过基础概念讲解和示例对比,展示了各自语法特点,如Lambda表达式的`(parameters) =&gt; expression`形式及匿名方法的`delegate(parameters)`结构。并通过实例演示了两者的应用差异,强调了在使用Lambda时应注意闭包问题及其解决策略,推荐优先使用Lambda表达式以增强代码可读性。
44 8
|
3月前
|
图形学 C# 开发者
全面掌握Unity游戏开发核心技术:C#脚本编程从入门到精通——详解生命周期方法、事件处理与面向对象设计,助你打造高效稳定的互动娱乐体验
【8月更文挑战第31天】Unity 是一款强大的游戏开发平台,支持多种编程语言,其中 C# 最为常用。本文介绍 C# 在 Unity 中的应用,涵盖脚本生命周期、常用函数、事件处理及面向对象编程等核心概念。通过具体示例,展示如何编写有效的 C# 脚本,包括 Start、Update 和 LateUpdate 等生命周期方法,以及碰撞检测和类继承等高级技巧,帮助开发者掌握 Unity 脚本编程基础,提升游戏开发效率。
82 0
|
3月前
|
C#
C# async await 异步执行方法
C# async await 异步执行方法
54 0