• 【转】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;
            }

    原文地址:http://www.cnblogs.com/zuiyirenjian/p/3536117.html

  • 相关阅读:
    JVM相关知识
    面试之mysql专题
    Java新特性
    数据结构操作与算法复杂度分析
    IO流
    浅谈Web安全
    面试题2
    需要知道的HTTP 知识
    How JavaScript Work
    webpack 学习笔记
  • 原文地址:https://www.cnblogs.com/mqxs/p/6539257.html
Copyright © 2020-2023  润新知