C# 动态调用WebService代码

项目中调用WebService,如果发布的WebService地址改变,那么就要重新添加WebService的引用。如果是现有的WebService发生了改变,也要更新现有的服务引用,所以整理了一套动态调用WebService的代码

  • Huawei
  • 发布:2022-02-17
  • 1760次
  • 动态调用WebService
  • 配置文件设置:


    <appSettings>

        <!--WebService地址-->

        <add key="WebServiceAddress" value="http://localhost:9008/TestWeb.asmx"/>

        <!--WebService提供的类名-->

        <add key="ClassName" value="TestWeb"/>

        <!--WebService方法名-->

        <add key="MethodName" value="Test"/>

        <!--存放dll文件的地址-->

        <add key="FilePath" value="E:\Test"/>

    </appSettings>


    后台代码:


    using System;

    using System.CodeDom;

    using System.CodeDom.Compiler;

    using System.IO;

    using System.Net;

    using System.Text;

    using System.Web;

    using System.Web.Caching;

    using System.Web.Services.Description;

    using System.Xml.Serialization;


    namespace WebServiceDemo

    {

        public class WebServiceHelper

        {

            /// <summary>

            /// 生成dll文件保存到本地

            /// </summary>

            /// <param name="url">WebService地址</param>

            /// <param name="className">类名</param>

            /// <param name="methodName">方法名</param>

            /// <param name="filePath">保存dll文件的路径</param>

            public static void CreateWebServiceDLL(string url,string className, string methodName,string filePath )

            {

                // 1. 使用 WebClient 下载 WSDL 信息。

                WebClient web = new WebClient();

                Stream stream = web.OpenRead(url   "?WSDL");

                // 2. 创建和格式化 WSDL 文档。

                ServiceDescription description = ServiceDescription.Read(stream);

                //如果不存在就创建file文件夹

                if (Directory.Exists(filePath) == false)

                {

                    Directory.CreateDirectory(filePath);

                }


                if (File.Exists(filePath   className   "_"   methodName   ".dll"))

                {

                    //判断缓存是否过期

                    var cachevalue = HttpRuntime.Cache.Get(className   "_"   methodName);

                    if (cachevalue == null)

                    {

                        //缓存过期删除dll

                        File.Delete(filePath   className   "_"   methodName   ".dll");

                    }

                    else

                    {

                        // 如果缓存没有过期直接返回

                        return;

                    }

                }


                // 3. 创建客户端代理代理类。

                ServiceDescriptionImporter importer = new ServiceDescriptionImporter();

                // 指定访问协议。

                importer.ProtocolName = "Soap";

                // 生成客户端代理。

                importer.Style = ServiceDescriptionImportStyle.Client; 

                importer.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync;

                // 添加 WSDL 文档。

                importer.AddServiceDescription(description, null, null);

                // 4. 使用 CodeDom 编译客户端代理类。

                // 为代理类添加命名空间,缺省为全局空间。

                CodeNamespace nmspace = new CodeNamespace();       

                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 = filePath   className   "_"   methodName   ".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");

                // 生成dll文件,并会把WebService信息写入到dll里面

                CompilerResults result = provider.CompileAssemblyFromDom(parameter, unit);

                if (result.Errors.HasErrors)

                {

                    // 显示编译错误信息

                    System.Text.StringBuilder sb = new StringBuilder();

                    foreach (CompilerError ce in result.Errors)

                    {

                        sb.Append(ce.ToString());

                        sb.Append(System.Environment.NewLine);

                    }

                    throw new Exception(sb.ToString());

                }

                //记录缓存

                var objCache = HttpRuntime.Cache;

                // 缓存信息写入dll文件

                objCache.Insert(className   "_"   methodName, "1", null, DateTime.Now.AddMinutes(5), TimeSpan.Zero, CacheItemPriority.High, null);

            }

        }

    }


    动态调用WebService代码:



    /// <summary>

    /// 动态调用WebService

    /// </summary>

    /// <param name="sender"></param>

    /// <param name="e"></param>

    private void btn_Dynamic_Click(object sender, EventArgs e)

    {

        // 读取配置文件,获取配置信息

        string url = ConfigurationManager.AppSettings["WebServiceAddress"];

        string className = ConfigurationManager.AppSettings["ClassName"];

        string methodName = ConfigurationManager.AppSettings["MethodName"];

        string filePath = ConfigurationManager.AppSettings["FilePath"];

        // 调用WebServiceHelper

        WebServiceHelper.CreateWebServiceDLL(url, className, methodName, filePath);

        // 读取dll内容

        byte[] filedata = File.ReadAllBytes(filePath   className   "_"   methodName   ".dll");

        // 加载程序集信息

        Assembly asm = Assembly.Load(filedata);

        Type t = asm.GetType(className);

        // 创建实例

        object o = Activator.CreateInstance(t);

        MethodInfo method = t.GetMethod(methodName);

        // 参数

        object[] args = {"动态调用WebService" };

        // 调用访问,获取方法返回值

        string value = method.Invoke(o, args).ToString();

        //输出返回值

        MessageBox.Show($"返回值:{value}");

    }


    如果说类名没有提供,可以根据url来自动获取类名:



    /// <summary>

    /// 根据WebService的url地址获取className

    /// </summary>

    /// <param name="wsUrl">WebService的url地址</param>

    /// <returns></returns>

    private  string GetWsClassName(string wsUrl)

    {

        string[] parts = wsUrl.Split('/');

        string[] pps = parts[parts.Length - 1].Split('.');

        return pps[0];

    }



    结束!!!1
    本文来源:https://www.cnblogs.com/dotnet261010/p/12461930.html