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)