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的身份验证

 

posted @ 2012-08-16 17:22  高山-景行  阅读(2476)  评论(1编辑  收藏  举报