在某些情况下,我们不能修改项目,重新引入一个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功能相关推荐

  1. Asp.net动态加载控件的一些问题

    ASP.net 动态加载控件时一些问题的总结 1 .在使用LoadControl加载控件后,用户控件中的某些控件不再响应事件. 这个问题主要是由于将控件加载放在if (!Page.IsPostBack ...

  2. 关于ASP.NET动态加载Master页面

    代码 //关于ASP.NET动态加载Master页面 //首先创建一母版页Master.master /* <%@ Master Language="C#" AutoEven ...

  3. ASP.NET动态加载CSS文件

    方法一: 通过使页面动态加载不同CSS实现多界面 <%@page language="C#"%> <%@import namespace="System ...

  4. .NET ASP.NET 动态加载样式

    引用的命名空间:using System.Web.UI.HtmlControls; protected void Page_Init(object sender, EventArgs e) {Html ...

  5. asp.net动态加载css

    谁如果有更直接的方法,请不吝赐教.也不知道.net有什么方法可以直接更换css <%@ Page Language="C#" AutoEventWireup="tr ...

  6. ASp.net动态加载js和css文件

    来自:原文:http://www.cnblogs.com/hyl8218/archive/2010/03/25/1690483.html protected void Page_Load(object ...

  7. 利用反射实现类的动态加载

    为什么80%的码农都做不了架构师?>>>    //首先定义一个接口来隔离类: public interface Operator { // public java.util.Lis ...

  8. Java动态加载类(对反射的基本理解)

    目录 基本概念 演示 基本概念 这里演示下Java的动态加载类.因为在编译的时候,加载类是静态加载,运行时加载是动态加载. 在此我对反射有了如下的理解: 如果有一个class A,可以使用new A( ...

  9. Vue + Spring Boot 项目实战(十五):动态加载后台菜单

    重要链接: 「系列文章目录」 「项目源码(GitHub)」 本篇目录 前言 一.后端实现 1.表设计 2.pojo 3.菜单查询接口(树结构查询) 二.前端实现 1.后台页面设计 2.数据处理 3.添 ...

最新文章

  1. react入门代码_如何在React中构建温度控制应用程序-包括提示和入门代码
  2. 快捷指令_苹果怎么关闭快捷指令通知提醒 取消ios14快捷指令设置方法
  3. Azure操作手册集合
  4. 机虚拟磁盘附加到计算机上,解决在NAS的共享文件夹下的VHDX虚拟磁盘无法附加到系统...
  5. java常用技术栈,HR的话扎心了
  6. 洛谷 - P1142 - 轰炸 - 计算几何
  7. ros开发增加clion常用模板及初始化配置(四)
  8. 软件工程导论--软件工程概述
  9. 如何彻底的删除hao123_hao123太流氓!怎么从电脑彻底清除?
  10. 微擎服务器数据迁移 ,微擎通过迁移数据方式搬家换服务器换站点换域名【图文教程】
  11. 曾国藩:一勤天下无难事(五勤)
  12. Java程序员编程学习之路资源合集
  13. MPC5748g基于源码实现ENET-PING实验(编译+调试)
  14. 评价页面html代码,HTML5 评论列表界面模板
  15. Android 进阶笔记,包含常用的技术框架、博客社区、书籍等。
  16. 求三角形面积 ← 海伦公式
  17. 拍案叫绝的算法(二)
  18. 如何写好测试用例以及go单元测试工具testify简单介绍
  19. 法规标准-ISO 22839标准解读(2013版)
  20. conda创建虚拟环境并添加到jupyter kernel(踩坑泪目)

热门文章

  1. 华为笔试题--最长公共子串
  2. html5上传使用FileReader,Promise图片预览
  3. MapReduce案例一:天气温度
  4. 第一阶段冲刺 第八天
  5. windows 程序设计及API
  6. 好吧,如果一定要RESTFUL的DJANGO
  7. 代码意识流——花朵数问题(七)
  8. 诗与远方:无题(三十二)- 曾经写给妹子的一首诗
  9. Spring自学日志01
  10. Intellij Idea插件利器推荐大全