原文:C# 调用Webservice并传递序列化对象

C#动态调用WebService注意要点



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;

        }

C# 调用Webservice并传递序列化对象的更多相关文章

  1. Android剪切板传递数据传递序列化对象数据

    一.剪切板的使用介绍 1. 剪切板对象的创建 使用剪切板会用到,ClipboardManager对象,这个对像的创建不可以使用构造方法,主要是由于没有提供public的构造函数(单例模式),需要使用A ...

  2. CXF WebService中传递复杂对象(List、Map、Array)

    转自:https://wenku.baidu.com/view/047ce58ed0d233d4b14e69eb.html 现在开始介绍传递复杂类型的对象.如JavaBean.Array.List.M ...

  3. jQuery调用WCF服务传递JSON对象

    下面这个示例使用了WCF去创建一个服务端口从而能够被ASP.Net页面通过jQuery的AJAX方法访问,我们将在客户端使用Ajax技术来 与WCF服务进行通信.这里我们仅使用jQuery去连接Web ...

  4. Webservice SOAP传输序列化总结 以及webservice之序列化以及反序列化实例

    一.所有Webservice中传递的对象都必须能够序列化,这个是作为在网络之间传输的必要条件.XML WebService和SOAP标准支持的数据类型如下: 1.基本数据类型. 标准类型,如:int ...

  5. C# 调用WebService的方法

    很少用C#动态的去调用Web Service,一般都是通过添加引用的方式,这样的话是自动成了代理,那么动态代理调用就是我们通过代码去调用这个WSDL,然后自己去生成客户端代理.更多的内容可以看下面的两 ...

  6. 【转】C# 调用WebService的方法

    很少用C#动态的去调用Web Service,一般都是通过添加引用的方式,这样的话是自动成了代理,那么动态代理调用就是我们通过代码去调用这个WSDL,然后自己去生成客户端代理.更多的内容可以看下面的两 ...

  7. Android通过ksoap2这个框架调用webservice大讲堂

    昨天有人问我Android怎么连接mysql数据库,和对数据库的操作呀,我想把,给他说说json通信,可是他并不知道怎么弄,哎算了吧,直接叫他用ksoap吧,给他说了大半天,好多零碎的知识,看来还是有 ...

  8. Jquery调用Webservice传递Json数组

    Jquery由于提供的$.ajax强大方法,使得其调用webservice实现异步变得简单起来,可以在页面上传递Json字符串到Webservice中,Webservice方法进行业务处理后,返回Js ...

  9. cxf 调用 webservice服务时传递 服务器验证需要的用户名密码

    cxf通过wsdl2java生成客户端调用webservice时,如果服务器端需要通过用户名和密码验证,则客户端必须传递验证所必须的用户名和密码,刚开始想通过url传递用户名和密码,于是在wsdl文件 ...

随机推荐

  1. 漫话Unity3D(三)

    八.预制(Prefab) 这个单独提出来,是由于它太经常使用了.也是Unity 的核心要素之中的一个.原本Unity中的一个物体是你拖拽一个模型到场景中,或者创建一个几何体,或者灯光地形等,然后设置这 ...

  2. DEMO阶段已完成,今天,要深入钻

    今天老师整理我的代码,发现,当时我没搞清楚这是正常的,由于我没有在一开始发挥到其翻译,而没有分析. 只要,研究底部是正确的.为了更好地理解代码. 上午:OSGEARTH视频教程. 上午,DX11机械仿 ...

  3. 8.19! 今天我有18生日,点击阅读或顶部 尾随幸运的一天!生日知识!↓——【Badboy】

    话说得生疼.我已经想到了17那年,那是一年的时间!我在这里7.24我认为这是我的生日 结果到处宣传 ,首页疑问发现自己是错的生日 按照农历计勒把我羞辱. 不依照原农历7.24的  今天的国家今天的日历 ...

  4. PC远程调试设备(转)

    我们在移动端进行前端开发时,会遇到一个让人头痛但不得不面对的问题——调试. 在 PC 机器上,我们有功能强大的 Chrome DevTools.Firebug,即便是老版本的 IE ,我们也可以安装微 ...

  5. 【CTO辩论】移动创业大军:谁斗争or变更代理

    众创时代.英雄辈出. 但千军万马过独木桥,竞争厮杀也异常残酷.有人说,这个时代不宜创业,由于技术门槛高了.推广难度高了.盈利模式没了.创业变重了.玩法变了...... 也有人说,时势造英雄.天时地利人 ...

  6. Building Redis for use on Cygwin(转)

    This is the second time I have installed Redis for use on Cygwin in the last several months. It seem ...

  7. git寻根——^和~的区别(转)

    一. 引子 在git操作中,我们可以使用checkout命令检出某个状态下文件,也可以使用reset命令重置到某个状态,这里所说的“某个状态”其实对应的就是一个提交(commit). 我们可以把一个g ...

  8. Oracle性能优化学习笔记WHERE在连接顺序的条款

     ORACLE自下而上分析顺序WHERE条款,根据这一原理,表之间的连接必须写在其它WHERE先决条件, 这些条件可以过滤掉要被写入记录的最大数目WHERE在条款结束. 比如:        (低效, ...

  9. mac在查看jre通路

    于Finder于command+shift+G 选/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home 版权声明:本文博主原创 ...

  10. eclipse+Java2WSDL+WSDL2Java 2012-12-06 12:32:43| 分类: j2ee |报道|字体大小 认购 一、eclipse如何使用低axis生成wsdl 可以使用

    eclipse+Java2WSDL+WSDL2Java 一.eclipse下怎样用axis生成wsdl 能够使用axis提供的Java2WSDL功能生成所要公布类的 WSDL,过程例如以下:  1.在 ...