ASP.NET 动态加载WebService功能
在某些情况下,我们不能修改项目,重新引入一个WebService,然后再修改代码编译。所以最好解决办法是,通过一个小的dll,或者是cs文件,来实现动态加载webservice,这样现有项目,只需要在Web.config中加入一个webservice引用路径节点即可。参考别人做的例子,现在自己编码实现了一下,大体过程如下详述,主要代码,还是参考了论坛里别的朋友的帖子,不过是再次整理了下顺序,表示感谢,呵呵!
现在用VS2010编码,做个Demo实例。
1.服务器端WebService实例:
新建一个项目,提供两个方法,一个是返回一个ArrayList数组,一个是带参数方法,返回一个字符串。至于WebService支持的返回参数类型,不做详述。至少泛型是不支持的。
代码如下:
[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
转载于:https://www.cnblogs.com/tank-lizi/archive/2012/01/05/2313214.html
ASP.NET 动态加载WebService功能相关推荐
- Asp.net动态加载控件的一些问题
ASP.net 动态加载控件时一些问题的总结 1 .在使用LoadControl加载控件后,用户控件中的某些控件不再响应事件. 这个问题主要是由于将控件加载放在if (!Page.IsPostBack ...
- 关于ASP.NET动态加载Master页面
代码 //关于ASP.NET动态加载Master页面 //首先创建一母版页Master.master /* <%@ Master Language="C#" AutoEven ...
- ASP.NET动态加载CSS文件
方法一: 通过使页面动态加载不同CSS实现多界面 <%@page language="C#"%> <%@import namespace="System ...
- .NET ASP.NET 动态加载样式
引用的命名空间:using System.Web.UI.HtmlControls; protected void Page_Init(object sender, EventArgs e) {Html ...
- asp.net动态加载css
谁如果有更直接的方法,请不吝赐教.也不知道.net有什么方法可以直接更换css <%@ Page Language="C#" AutoEventWireup="tr ...
- ASp.net动态加载js和css文件
来自:原文:http://www.cnblogs.com/hyl8218/archive/2010/03/25/1690483.html protected void Page_Load(object ...
- 利用反射实现类的动态加载
为什么80%的码农都做不了架构师?>>> //首先定义一个接口来隔离类: public interface Operator { // public java.util.Lis ...
- Java动态加载类(对反射的基本理解)
目录 基本概念 演示 基本概念 这里演示下Java的动态加载类.因为在编译的时候,加载类是静态加载,运行时加载是动态加载. 在此我对反射有了如下的理解: 如果有一个class A,可以使用new A( ...
- Vue + Spring Boot 项目实战(十五):动态加载后台菜单
重要链接: 「系列文章目录」 「项目源码(GitHub)」 本篇目录 前言 一.后端实现 1.表设计 2.pojo 3.菜单查询接口(树结构查询) 二.前端实现 1.后台页面设计 2.数据处理 3.添 ...
最新文章
- react入门代码_如何在React中构建温度控制应用程序-包括提示和入门代码
- 快捷指令_苹果怎么关闭快捷指令通知提醒 取消ios14快捷指令设置方法
- Azure操作手册集合
- 机虚拟磁盘附加到计算机上,解决在NAS的共享文件夹下的VHDX虚拟磁盘无法附加到系统...
- java常用技术栈,HR的话扎心了
- 洛谷 - P1142 - 轰炸 - 计算几何
- ros开发增加clion常用模板及初始化配置(四)
- 软件工程导论--软件工程概述
- 如何彻底的删除hao123_hao123太流氓!怎么从电脑彻底清除?
- 微擎服务器数据迁移 ,微擎通过迁移数据方式搬家换服务器换站点换域名【图文教程】
- 曾国藩:一勤天下无难事(五勤)
- Java程序员编程学习之路资源合集
- MPC5748g基于源码实现ENET-PING实验(编译+调试)
- 评价页面html代码,HTML5 评论列表界面模板
- Android 进阶笔记,包含常用的技术框架、博客社区、书籍等。
- 求三角形面积 ← 海伦公式
- 拍案叫绝的算法(二)
- 如何写好测试用例以及go单元测试工具testify简单介绍
- 法规标准-ISO 22839标准解读(2013版)
- conda创建虚拟环境并添加到jupyter kernel(踩坑泪目)