ASP.NET 动态加载WebService功能

 2023-09-13 阅读 25 评论 0

摘要:在某些情况下,我们不能修改项目,重新引入一个WebService,然后再修改代码编译。所以最好解决办法是,通过一个小的dll,或者是cs文件,来实现动态加载webservice,这样现有项目,只需要在Web.config中加入一个webservice引

        在某些情况下,我们不能修改项目,重新引入一个WebService,然后再修改代码编译。所以最好解决办法是,通过一个小的dll,或者是cs文件,来实现动态加载webservice,这样现有项目,只需要在Web.config中加入一个webservice引用路径节点即可。参考别人做的例子,现在自己编码实现了一下,大体过程如下详述,主要代码,还是参考了论坛里别的朋友的帖子,不过是再次整理了下顺序,表示感谢,呵呵!

现在用VS2010编码,做个Demo实例。

静态加载和动态加载,1.服务器端WebService实例:

    新建一个项目,提供两个方法,一个是返回一个ArrayList数组,一个是带参数方法,返回一个字符串。至于WebService支持的返回参数类型,不做详述。至少泛型是不支持的。

    代码如下:

qq简洁模式动态页功能管理、[WebMethod(Description = "返回数组列表方法")]
public ArrayList GetALString()
{
return GetArrayListString();
}

[WebMethod(Description = "带有参数方法")]
public string GetMsgFromService(object[] arges)
{
return GetHelloWord((string)arges[0], (string)arges[1]);
}
/// <summary>
/// 返回Arraylist数组
/// </summary>
/// <returns></returns>
private ArrayList GetArrayListString()
{
ArrayList reList = new ArrayList();
reList.Add("Dynamic");
reList.Add("WebService");
reList.Add("True");
return reList;
}
/// <summary>
/// 根据传入参数,返回一个组合字符串
/// </summary>
/// <param name="sName"></param>
/// <param name="sWrod"></param>
/// <returns></returns>
private string GetHelloWord(string sName, string sWrod)
{
return "This Message From Service【"+ sName + ": "+ sWrod +"】";
}

2.客户端调用WebService类代码如下:

using System;
using System.Collections.Generic;
using System;
using System.IO;
using System.Net;
using System.CodeDom;
using System.Configuration;
using System.Reflection;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.Web.Services.Description;namespace WebDemo
{class ServiceClass{public static SortedList<string, Type> _typeList = new SortedList<string, Type>();#region InvokeWebServiceprivate static string m_ServiceIP = ConfigurationManager.AppSettings["WebServiceIP"];private static string m_ServiceNamespace = ConfigurationManager.AppSettings["WebServiceNamespace"];private static string sClassName = GetWsClassName(m_ServiceIP);private static string GetCacheKey(){return m_ServiceIP + "_ServiceData_" + sClassName;}private static Type GetTypeFromCache(){string key = GetCacheKey();foreach (KeyValuePair<string, Type> pair in _typeList){if (key == pair.Key){return pair.Value;}}return null;}private static Type GetTypeFromWebService(){string @namespace = m_ServiceNamespace;//获取WSDLWebClient wc = new WebClient();Stream stream = wc.OpenRead(m_ServiceIP + "?WSDL");ServiceDescription sd = ServiceDescription.Read(stream);ServiceDescriptionImporter sdi = new ServiceDescriptionImporter();sdi.AddServiceDescription(sd, "", "");CodeNamespace cn = new CodeNamespace(@namespace);//生成客户端代理类代码CodeCompileUnit ccu = new CodeCompileUnit();ccu.Namespaces.Add(cn);sdi.Import(cn, ccu);CSharpCodeProvider csc = new CSharpCodeProvider();ICodeCompiler icc = csc.CreateCompiler();//设定编译参数CompilerParameters cplist = new CompilerParameters();cplist.GenerateExecutable = false;cplist.GenerateInMemory = true;// cplist.OutputAssembly = "CheckWebServer.dll";//输出程序集的名称cplist.ReferencedAssemblies.Add("System.dll");cplist.ReferencedAssemblies.Add("System.XML.dll");cplist.ReferencedAssemblies.Add("System.Web.Services.dll");cplist.ReferencedAssemblies.Add("System.Data.dll");//编译代理类CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu);if (true == cr.Errors.HasErrors){System.Text.StringBuilder sb = new System.Text.StringBuilder();foreach (System.CodeDom.Compiler.CompilerError ce in cr.Errors){sb.Append(ce.ToString());sb.Append(System.Environment.NewLine);}throw new Exception(sb.ToString());}// Assembly asm = Assembly.LoadFrom("CheckWebServer.dll");//加载前面生成的程序集//生成代理实例,并调用方法Assembly assembly = cr.CompiledAssembly;Type t = assembly.GetType(@namespace + "." + sClassName, true, true);return t;}//动态调用web服务public static object InvokeWebService(string methodName, object[] args){try{Type t = GetTypeFromCache();if (t == null){t = GetTypeFromWebService();//添加到缓冲中string key = GetCacheKey();if (!_typeList.ContainsKey(key))_typeList.Add(key, t);}object obj = Activator.CreateInstance(t);MethodInfo mi = t.GetMethod(methodName);if (args == null || args.Length < 0){return mi.Invoke(obj, null);}else{return mi.Invoke(obj, new object[] { args });}}catch (Exception ex){throw new Exception(ex.InnerException.Message);}}/// <summary>/// 默认类名为URL中.asmx类名/// </summary>/// <param name="wsUrl"></param>/// <returns></returns>private static string GetWsClassName(string wsUrl){string[] parts = wsUrl.Split('/');string[] pps = parts[parts.Length - 1].Split('.');return pps[0];}#endregion}
}
 
3.页面访问调用方法如下:
        protected void BTN_Array_Click(object sender, EventArgs e){object result = ServiceClass.InvokeWebService("GetALString", null);Array list = (Array)result;StringBuilder reText = new StringBuilder();foreach (string str in list){reText.Append(str);}LB_Text.Text = reText.ToString();}protected void BTN_String_Click(object sender, EventArgs e){object[] args = new object[2];args[0] = "Tank";args[1] = "From WebClient";object result = ServiceClass.InvokeWebService("GetMsgFromService", args);LB_Text.Text = (string)result;}
Ok,小结:
1)的了解WebService调用方法,可返回类型,比如开始返回了个Hashtabale,泛型,这些都是不支持的,反编译,问题又不好查找。
2)动态添加,开始没注意缓存是否已经存在,导致容易出现问题,最好进行缓存插入时,先判断是否已经存在_typeList.ContainsKey(key),不存在再插入。
3)传递参数必须为object类型,且webservice也是同类型,否则调用会因为类型无法转换而失败。
 
附上自做代码小例子。提供给大家下载扩充交流。http://files.cnblogs.com/tank-lizi/DynamicWebService.rar 

qq动态里的功能怎么开启,转载于:https://www.cnblogs.com/tank-lizi/archive/2012/01/05/2313214.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/1/52947.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息