动态调用WebService

1.大多数情况下,我们都是在VS里面通过添加Web引用的方式,在客户端自动生成客户端代理去调用WebService的,

有时候,服务器端的地址可能会经常变,这里就需要动态的调用WebService,

一种是服务没有变化只是IP地址变化了,这样我们只需要在获取客户端代理的时候,将其URL地址修改即可。

另一种可能服务参数等发生变化了,这样我们可以通过CodeDOMega,反射灯相关技术实现动态调用,步骤如下:

1.下载WSDL文档

2.创建ServiceDescription描述对象

3.创建服务客户端代理

4.编译客户端代理

5.反射调用服务方法。

这里创建一个测试用的WebService,里面有一个方法 SayHello().生成并发布,

源码如下:

WebService:

View Code
using System;
using System.Data;
using System.Web;
using System.Collections;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.ComponentModel;

namespace testInvokeWebSerivce
{
    /// <summary>
    /// Service1 的摘要说明
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    public class Service1 : System.Web.Services.WebService
    {

        [WebMethod]
        public string SayHello(string name)
        {
            return "Hello " + name;
        }
    }
}

Client:

View Code
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Net;
using System.IO;
using System.Web.Services;
using System.Web.Services.Description;
using System.Xml.Serialization;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Reflection;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            Program pro = new Program();
            pro.InvokeMethod("http://localhost/testInvokeWebService/TestSrv.asmx", "Service1", "SayHello", "阿牛哥");
        }

        public void InvokeMethod(string uri, string serviceName, string methodName, string parameters)
        { 
            //下载WSDL描述信息
            WebClient web = new WebClient();
            Stream stream = web.OpenRead(uri + @"?WSDL");

            //创建ServiceDescription描述
            ServiceDescription description = ServiceDescription.Read(stream);
            
            //创建客户端代理
            ServiceDescriptionImporter import = new ServiceDescriptionImporter();
            import.ProtocolName = "SOAP";
            import.Style = ServiceDescriptionImportStyle.Client;
            //import.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync;//这个是来自于 System.Xml.Serialization命名空间下
            import.AddServiceDescription(description, null, null);

            //编译客户端
            CodeNamespace ns = new CodeNamespace();//使用默认全局命名空间
            CodeCompileUnit unit = new CodeCompileUnit();
            unit.Namespaces.Add(ns);//少了这句不能获得类型了
            ServiceDescriptionImportWarnings warnings = import.Import(ns, unit);

            CompilerParameters para = new CompilerParameters();
            para.GenerateInMemory = true;
            para.GenerateExecutable = false;
            //这个地方注意引用的DLL,少一个都会出错的。。。我就是少了个System.XML.Dll
            para.ReferencedAssemblies.Add("System.dll");
            para.ReferencedAssemblies.Add("System.XML.dll");
            para.ReferencedAssemblies.Add("System.Data.dll");
            para.ReferencedAssemblies.Add("System.Web.Services.dll");

            //CodeDomProvider provider = CodeDomProvider.CreateProvider("C#");
            CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
            CompilerResults results = provider.CompileAssemblyFromDom(para, unit);
            if (!results.Errors.HasErrors)
            {
                Assembly ass = results.CompiledAssembly;
                Type[] sss = ass.GetTypes();
                Type type = ass.GetType(serviceName);
                Object obj = Activator.CreateInstance(type, null);

                MethodInfo method = type.GetMethod(methodName);
                string ss = method.Invoke(obj, new string[] { parameters }).ToString();
                Console.WriteLine(ss);
            }
            results.Errors.ToString();
        }
    }
}

效果图:

posted @ 2012-09-01 18:11  大侠的哥哥是菜鸟  阅读(305)  评论(0编辑  收藏  举报