c#动态调用webservice接口(实时在线下载dll文件)

app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
    </configSections>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
    </startup>
    <system.serviceModel>
        <bindings />
        <client />
    </system.serviceModel>
	<appSettings>
		<!--webservice地址-->
		<add key="WebServiceAddress" value="http://具体ip地址:8081/WebService1.asmx"/>
		<!--webservice提供的类名-->
		<add key="ClassName" value="WebService1"/>
		<!--webservice方法名-->
		<add key="MethodName" value="CheckDataBeforeCheckIn"/>
		<add key="MethodName_2" value="AutoDispatch"/>
		<add key="MethodName_3" value="SpecialAutoDispatch"/>
		<!--存放dll文件的地址-->
		<!--<add key="FilePath" value="D:\GeEn"/>-->
		<!--批次请求类型-->
		<add key="CheckDataType" value="CheckDataBeforeCheckIn_Req"/>
		<add key="CheckInType" value="CheckIn_Req"/>
		<add key="CheckOutType" value="CheckOut_Req"/>
		<add key="SpecialInType" value="SpecialCheckIn_Req"/>
		<add key="SpecialOutType" value="SpecialCheckOut_Req"/>
	</appSettings>
</configuration>

WebServiceHelper.cs

using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Caching;
using System.Web.Services.Description;
using System.Xml.Serialization;

namespace WinFormsSlotMonitor
{
    public class WebServiceHelper
    {
        public static void CreateWebServiceDLL(string url, string className)
        {
            // 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(className + ".dll"))
            {
                //判断缓存是否过期
                var cachevalue = HttpRuntime.Cache.Get(className);

                if (cachevalue == null) {
                    //缓存过期删除dll
                    File.Delete(className + ".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 = 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里面
            //dll文件的存储路径为当前工程的/bin/debug目录下
            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, "1", null, DateTime.Now.AddMinutes(5), TimeSpan.Zero, CacheItemPriority.High, null);
        }
    }
}

form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Management;
using System.Net;
using System.Reflection;
using System.Security.Policy;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;
using ZCCommunication.Profinet.Melsec;

namespace WinFormsSlotMonitor
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            string url = ConfigurationManager.AppSettings["WebServiceAddress"];
            string className = ConfigurationManager.AppSettings["ClassName"];
            // 调用WebServiceHelper
            WebServiceHelper.CreateWebServiceDLL(url, className);

          //  string[] prodIdArr = { "G4P2208085", "HSP2281043", "G4P2207019" };
            string[] prodIdArr = { "G4P2208085" , "HSP2281043" };
            string opId = "01030831";
            string equipId = "1-CHB-2001";
            string direction = "in";
            //string direction = "out";
            //CheckDataBeforeCheckIn(className,prodIdArr,opId,equipId);
            AutoDispatch(direction,className,prodIdArr,equipId, opId);
          // SpecialAutoDispatch(direction,className,prodIdArr,opId, equipId);

        }

        /// <summary>
        /// 进站前校验数据
        /// </summary>
        /// <param name="className">类名</param>
        void CheckDataBeforeCheckIn(string className, string[] prodIdArr,string opId,string equipId)
        {
            string methodName = ConfigurationManager.AppSettings["MethodName"];
            string type = ConfigurationManager.AppSettings["CheckDataType"];
            //操作员工号、设备号可从plc的地址读取


            string soap_str = GenerateXmlDoc(methodName,type,opId,equipId,prodIdArr);
            //参数
            object[] args = { soap_str };
            string mes_return_info = ReflectInvoke(methodName,className,args);

        }

        /// <summary>
        /// 整批次进/出站
        /// </summary>
        /// <param name="direction">in进站,out出站</param>
        void AutoDispatch(string direction,string className, string[] prodIdArr, string equipId, string opId)
        {
            string methodName = ConfigurationManager.AppSettings["MethodName_2"];
            string type = string.Empty;
            //操作员工号、设备号可从plc的地址读取

            if ("in" == direction)
            {
                type = ConfigurationManager.AppSettings["CheckInType"];
            }
            else
            {
                type = ConfigurationManager.AppSettings["CheckOutType"];
            }
            string soap_str = GenerateXmlDoc(methodName, type, opId, equipId, prodIdArr);
            //参数
            object[] args = { soap_str };
            string mes_return_info = ReflectInvoke(methodName, className, args);

        }

        /// <summary>
        /// 组合批次进/出站
        /// </summary>
        /// <param name="direction">in进站,out出站</param>
        /// <param name="className">类名</param>
        void SpecialAutoDispatch(string direction,string className, string[] prodIdArr, string opId, string equipId)
        {
            string methodName = ConfigurationManager.AppSettings["MethodName_3"];
            string type = string.Empty;
            //操作员工号、设备号可从plc的地址读取

            if ("in" == direction)
            {
                type = ConfigurationManager.AppSettings["SpecialInType"];
            }
            else
            {
                type = ConfigurationManager.AppSettings["SpecialOutType"];
            }
            string soap_str = GenerateXmlDoc(methodName, type,opId,equipId, prodIdArr);
            object[] args = { soap_str };
            string mes_return_info = ReflectInvoke(methodName, className, args);
           
        }

        /// <summary>
        /// 生成xml格式的入参
        /// </summary>
        /// <param name="methodName">方法名</param>
        /// <param name="type">批次请求类型</param>
        /// <param name="opId">操作员工号</param>
        /// <param name="equipId">设备号</param>
        /// <returns></returns>
        string GenerateXmlDoc(string methodName,string type,string opId,string equipId, string[] prodIdArr)
        {
            string[] LD_LOT_ID = new string[20];
            //构造soap请求信息
            StringBuilder soap = new StringBuilder();
            soap.Append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
            soap.Append("<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">");
            soap.Append("<soap:Body>");
            soap.Append("<" + methodName + " " + "xmlns=\"http://tempuri.org/\">");
            soap.Append("<Message>");

            soap.Append("<Type>" + type + "</Type>");
            soap.Append("<ProdID_List>");

            //从plc中约定的地址循环读取批次号
            /*            for (int i = 0; i < 20; i++)
                        {

                            // PLCdata_read(22100 + i * 10, out LD_LOT_ID[i]);//LOT  22100
                            if (LD_LOT_ID[i] != null)
                            {
                                if (LD_LOT_ID[i].Length > 2)
                                {
                                    soap.Append("<ProdID>" + LD_LOT_ID[i] + "</ProdID>");
                                }
                            }
                        }*/

            for(int i = 0; i < prodIdArr.Length; i++)
            {
                soap.Append("<ProdID>" + prodIdArr[i] + "</ProdID>");
            }

            soap.Append("</ProdID_List>");
            soap.Append("<OpID>" + opId + "</OpID>");

            if (!string.IsNullOrEmpty(equipId))
            {
                soap.Append("<EquipID>" + equipId + "</EquipID>");
            }
            else
            {
                soap.Append("<EquipID></EquipID>");
            }
            soap.Append("</Message>");
            soap.Append("</" + methodName + ">");
            soap.Append("</soap:Body>");
            soap.Append("</soap:Envelope>");

            string soap_str = soap.ToString();
            return soap_str;
        }

        /// <summary>
        /// 以反射的方式调用WebService的方法
        /// </summary>
        /// <param name="methodName">方法名</param>
        /// <param name="className">类名</param>
        /// <param name="args">入参</param>
        /// <returns></returns>
        string ReflectInvoke(string methodName, string className, object[] args)
        {
            // 加载程序集信息,位置在当前工程的/bin/debug目录下
            Assembly asm = Assembly.LoadFrom(className + ".dll");
            Type t = asm.GetType("WebService1");
            // 创建实例
            object o = Activator.CreateInstance(t);
            MethodInfo method = t.GetMethod(methodName);
            // 调用访问,获取方法返回值
            string return_info = method.Invoke(o, args).ToString();
            this.responseTextBox.Text = return_info;
            return return_info;
        }
    }
}

注:仅供参考
参考文章链接:
https://blog.csdn.net/qq395537505/article/details/126034481?spm=1001.2014.3001.5506
https://blog.csdn.net/weixin_44012111/article/details/126406375?spm=1001.2014.3001.5506

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值