【超细完整版】C# WebService 通过URL生成WSDL文件和DLL文件 【生成篇】

目的

支持通过web url (自适应“?wsdl”的有无) 生成.wsdl文件 和 .dll文件

实现

将通过一个类的三部分来实现这些功能

  • 获取url中的ClassName (GetClassNameFromUrl)
  • 转换为WSDL文件 (UrlToWsdlFile)
  • 转换为DLL文件 (UrlToDllFile)

创建一个新类

类名为 WebServiceHelper.cs

    /// <summary>
    /// 动态调用WebService(支持SaopHeader)
    /// </summary>
    public class WebServiceHelper
    {
    
    }

并在该类实现下述方法

获取url中的ClassName

#region 获取url中的ClassName
/// <summary>   
/// 获取WebService的类名   
/// </summary>   
/// <param name="wsUrl">WebService地址</param>   
/// <returns>返回WebService的类名</returns>   
public static string GetClassNameFromUrl(string wsUrl)
{
    string result = string.Empty;
    if (!wsUrl.EndsWith("?wsdl", StringComparison.CurrentCultureIgnoreCase))
    {
        wsUrl = wsUrl + "?wsdl";
    }
    XmlDocument doc = new XmlDocument();
    doc.Load(wsUrl);
    try
    {
        result = doc.GetElementsByTagName("wsdl:service")[0].Attributes[0].Value;
    }
    catch (Exception err)
    {
        return string.Empty;
    }
    return result;
}
#endregion

转换为WSDL文件

 #region 生成WSDL
 public static void UrlToWsdlFile(string url, string savePath, string outName = "")
 {
     string className = string.Empty;
     string FullFileName = string.Empty;
     className = GetClassNameFromUrl(url);
     if (outName == "")
     {
         outName = className + ".wsdl";
     }
     else
     {
         if (!outName.EndsWith(".wsdl", StringComparison.CurrentCultureIgnoreCase))
         {
             outName = outName + ".wsdl";
         }
     }
     if (!url.EndsWith("?wsdl", StringComparison.CurrentCultureIgnoreCase))
     {
         url = url + "?wsdl";
     }
     FullFileName = savePath + "\\" + outName;
     WebClient wc = new WebClient();
     if (!System.IO.Directory.Exists(savePath))
     {
         System.IO.Directory.CreateDirectory(savePath);//不存在就创建文件夹
     }
     wc.DownloadFile(url, FullFileName);
 }
 #endregion

转换为DLL文件

#region 生成DLL

public static CompilerResults UrlToDllFile(string url, string @namespace = "")
{
    string className = string.Empty;
    className = GetClassNameFromUrl(url);
    if (!url.EndsWith("?wsdl", StringComparison.CurrentCultureIgnoreCase))
    {
        url = url + "?wsdl";
    }
    WebClient web = new WebClient();
    Stream stream = web.OpenRead(url);
    //创建和格式化 WSDL 文档。       
    ServiceDescription description = ServiceDescription.Read(stream);
    CompilerResults compiler = CreatDll(className, description, @namespace);
    return compiler;
}

private static CompilerResults CreatDll(string className, ServiceDescription description, string @namespace = "")
{
    try
    {
        // 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();
        nmspace.Name = @namespace;
        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.GenerateInMemory = true;//在内存中生成输出
        // 可以指定你所需的任何文件名。
        parameter.OutputAssembly = AppDomain.CurrentDomain.BaseDirectory + "dll\\" + className + ".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 System.Text.StringBuilder();
            foreach (System.CodeDom.Compiler.CompilerError ce in result.Errors)
            {
                sb.Append(ce.ToString());
                sb.Append(System.Environment.NewLine);
            }
            throw new Exception(sb.ToString());
        }
        return result;
    }
    catch (Exception err)
    {
        MessageBox.Show(err.Message, "Error");
        return null;
    }
}
#endregion

应用

个人示例,实际根据自己需求调整 ; 以下为窗体按钮事件

private void bt_generate_dll_Click(object sender, EventArgs e)
{
    try
    {
        WebServiceHelper.UrlToDllFile(tb_webLink.Text);

        if (MessageBox.Show("The dll is generated successfully. Do you want to open the file path?", "notice", MessageBoxButtons.YesNo) == DialogResult.Yes)
            openPath("dll");
    }
    catch (Exception err)
    {
        MessageBox.Show(err.Message, "Error");
    }
}
private void openPath(string type)
{
    if (string.IsNullOrEmpty(type)) return;
    string key = string.Empty;
    key = type.Equals(defaultKey) ? wsdlPathKey : dllPathKey;
    //get Configuration object
    Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
    //get value by key
    string path = config.AppSettings.Settings[key].Value;
    System.Diagnostics.Process.Start("explorer.exe", path);
}

老规矩,点赞关注走一波 😄

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-19 12:58:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-19 12:58:03       101 阅读
  3. 在Django里面运行非项目文件

    2024-03-19 12:58:03       82 阅读
  4. Python语言-面向对象

    2024-03-19 12:58:03       91 阅读

热门阅读

  1. Linux 查看防火墙相关命令

    2024-03-19 12:58:03       40 阅读
  2. word的第六课笔记

    2024-03-19 12:58:03       42 阅读
  3. 每日一题 第十一期 洛谷 进制转换

    2024-03-19 12:58:03       39 阅读
  4. PyTorch的向量化思维,以及Tensor、nn接口

    2024-03-19 12:58:03       43 阅读
  5. C++ day6

    C++ day6

    2024-03-19 12:58:03      41 阅读
  6. 面试题(补充)

    2024-03-19 12:58:03       46 阅读
  7. openxml对worksheet数值化

    2024-03-19 12:58:03       37 阅读