zoukankan      html  css  js  c++  java
  • C# 动态调用WebService, 不同结果返回值处理

    asp.net中 正常的调用WebService的方法是添加web引用,但是当一些特殊情况就不是很适用了,如果webService的地址经常变化的话,每次都要重新引用编译程序是件很麻烦的事情。这里动态引用ws只需要配置一个地址就可以了。

    在网上找到了许多的文章具体实现都是差不多的,基本都是同一段代码。

    主要参考一下两边文章:

    这个是介绍动态调用,主要用的是这哥们的代码:

    http://hddev.blog.51cto.com/3365350/628288

    这个是介绍利用反射来获取返回的数组,虽然有个地方错了,不过大方向还是对滴:

    http://blog.csdn.net/study_live/article/details/5225073

    主要用的webservice代理类的代码,也可以第一篇文章最下面有下载

    WebServiceProxy
    using System;
    using System.Web.Services.Description;
    using System.IO;
    using System.Net;
    using System.Xml.Serialization;
    using System.CodeDom;
    using System.CodeDom.Compiler;
    using System.Reflection;
    
    public class WebServiceProxy
    {
        private string _className = null;
    
        public string WebServiceUrl
        {
            get;
            private set;
        }
    
        private WebServiceProxy(string webServiceUrl)
        {
            this.WebServiceUrl = webServiceUrl + "?WSDL";
            _className = webServiceUrl.Substring(webServiceUrl.LastIndexOf('/')+1);
            _className = _className.Substring(0, _className.LastIndexOf('.'));
        }
    
        /// <summary>
        /// 根据编译结果生成实例并返回
        /// </summary>
        /// <returns></returns>
        public static object CreateInstance(string webServiceUrl)
        {
            WebServiceProxy proxy = new WebServiceProxy(webServiceUrl);
            CodeCompileUnit unit = proxy.GetServiceCompileUnit(proxy.WebServiceUrl);
            CompilerResults result = proxy.Compile(unit);
            Assembly asm = result.CompiledAssembly;
            object obj = asm.CreateInstance("WebService." + proxy._className);
            return obj;
        }
    
        /// <summary>
        /// 获得CompileUnit
        /// </summary>
        /// <param name="webServiceUrl"></param>
        /// <returns></returns>
        private CodeCompileUnit GetServiceCompileUnit(string webServiceUrl)
        {
            WebClient client = new WebClient();
            Stream stream = client.OpenRead(webServiceUrl);
            //从这个url指向的的是一个xml文件,里面包含了该service的全部信息。
            //进而通过解析xml文件从而可以生成要编译的源码。有兴趣的可以看一下xml的内容
            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, "", ""); //添加WSDL文档。
            CodeNamespace nmspace = new CodeNamespace(); //命名空间
            nmspace.Name = "WebService";
            CodeCompileUnit unit = new CodeCompileUnit();
            unit.Namespaces.Add(nmspace);
            ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit);
            return unit;
        }
    
        /// <summary>
        /// 编译
        /// </summary>
        /// <param name="unit"></param>
        /// <returns></returns>
        private CompilerResults Compile(CodeCompileUnit unit)
        {
            CodeDomProvider codeDomProvider = CodeDomProvider.CreateProvider("CSharp");
            CompilerParameters compilerParameters = new CompilerParameters();
            compilerParameters.GenerateExecutable = false;
            compilerParameters.GenerateInMemory = true;
            // cp.OutputAssembly = "D:\\Test.dll";这里也可以将变异的结果输出到dll文件中,从而可以查看编译的的结果。有兴趣的自己看一下。
            compilerParameters.ReferencedAssemblies.Add("System.dll");
            compilerParameters.ReferencedAssemblies.Add("System.XML.dll");
            compilerParameters.ReferencedAssemblies.Add("System.Web.Services.dll");
            compilerParameters.ReferencedAssemblies.Add("System.Data.dll");
            CompilerResults compilerResults = codeDomProvider.CompileAssemblyFromDom(compilerParameters, unit);
            if (compilerResults.Errors.HasErrors)
            {
                string errors = "";
                foreach (var item in compilerResults.Errors)
                {
                    errors += item.ToString() + Environment.NewLine;
                }
    
                throw new Exception("Compile error:" + errors);
            }
            return compilerResults;
        }
    
    
    }
    WebServiceClient.cs
    using System;
    using System.Reflection;
    
    
    /// <summary>
    /// Summary description for WebServiceClient
    /// </summary>
    public class WebServiceClient
    {
    
        public static string Invoke(string webServiceUrl, string methodName, object[] parameters)
        {
            if (string.IsNullOrEmpty(webServiceUrl))
            {
                throw new Exception("WebService url  required!");
            }
            if (string.IsNullOrEmpty(methodName))
            {
                throw new Exception("Method name required!");
            }
    
            object instance = WebServiceProxy.CreateInstance(webServiceUrl);
            MethodInfo method = instance.GetType().GetMethod(methodName);
            string result = (string)method.Invoke(instance, parameters);
            return result;
        }
    }

    测试方法,分别返回 string,datatable,泛型集合(这里是其实就是实体类的数组)

    string url = "这里是你的webService地址";//可以放配置文件里
            ////返回字符串
            //string s = WebServiceClient.Invoke(url, "GetServerName", null);
            //Response.Write(s);
    
            object instance = WebServiceProxy.CreateInstance(url);
    
            ////返回datatable
            //MethodInfo method = instance.GetType().GetMethod("GetSubStationInfo");//方法名称
            //object[] parameters = { "370102002" };//参数
            //DataTable dt = (DataTable)method.Invoke(instance, parameters);
    
            //返回泛型集合
            MethodInfo method = instance.GetType().GetMethod("GetRealData");//方法名称
            // 如果参数传的是个 dataset , DataSet ds=new DataSet();object[] parameters = {ds};
            object[] parameters = { "1510", "5" };//参数
            //这里返回的是一个 实体类的数组
            object objArray = method.Invoke(instance, parameters);
            Type tp = objArray.GetType();
            if (tp.IsArray)
            {
                object[] dataArray = objArray as object[];
                for (int i = 0; i < dataArray.Length; i++)
                {
                    object s = dataArray[i] as object;
                    Type t = s.GetType();
                    //利用一下方法获取到实体类中的属性的值
                    //PropertyInfo[] fi = t.GetProperties();
                    //string str = fi[0].GetValue(s, null).ToString();
                    
                    string C0001_ITEM_CODE = t.GetProperty("C0001_ITEM_CODE").GetValue(s, null).ToString();
                    string C0007_PNAME = t.GetProperty("C0007_PNAME").GetValue(s, null).ToString();
    
                    //FieldInfo[] fields = t.GetFields();//返回当前type的所有公共字段
                }
    
            }

    C# WebService动态调用

    WebService基于soapheader的身份验证

  • 相关阅读:
    设计模式----单例模式
    C++ 派生类
    C++ 操作符
    构造,清理,拷贝和移动
    php的yii框架开发总结10
    php的yii框架开发总结9
    php的yii框架开发总结8
    php的yii框架开发总结7
    php的yii框架开发总结6
    php的yii框架开发总结5
  • 原文地址:https://www.cnblogs.com/wangjunwei/p/2642696.html
Copyright © 2011-2022 走看看