我在用.net实现Webservice的时候发现须要一个没有任何用处的.asmx文件,可是却无法删除,这两天我实现一个经过接口时想实现dll直接部署,不须要弄个.asmx文件.翻阅了不少,最后在Spring.net里面获得了启示.c#
我要实现的方式是直接在httpHandlers中配置框架
<httpHandlers>
<add verb="*" path="XXXservice.asmx" type="CampusWebService.DataService,CampusWebService"/>
</httpHandlers>函数
而后经过就能够直接部署,特别适合进行二次开发,嵌入式开始什么的.工具
具体的实现以下:this
先需须要经过继承反射实现一个c#的程序集封装的调用(很讨厌C#的程序集封装,讨嫌的要死) url
/// <summary> /// WebService处理类. /// </summary> [PermissionSet(SecurityAction.InheritanceDemand, Unrestricted = true)] internal class WebServiceHandlerFactory<T> : System.Web.Services.Protocols.WebServiceHandlerFactory, IHttpHandlerFactory where T : WebService { #region 成员变量,构造函数. /// <summary> /// 核心方法反射调用. /// </summary> private static readonly MethodInfo CoreGetHandler = typeof(System.Web.Services.Protocols.WebServiceHandlerFactory).GetMethod("CoreGetHandler", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(Type), typeof(HttpContext), typeof(HttpRequest), typeof(HttpResponse) }, null); private Type serviceType; /// <summary> /// 构造函数. /// </summary> /// <param name="serviceType"></param> public WebServiceHandlerFactory(T serviceType) { this.serviceType = serviceType.GetType(); } #endregion #region IHttpHandlerFactory 成员 /// <summary> /// /// </summary> /// <param name="context"></param> /// <param name="requestType"></param> /// <param name="url"></param> /// <param name="pathTranslated"></param> /// <returns></returns> IHttpHandler IHttpHandlerFactory.GetHandler(HttpContext context, string requestType, string url, string pathTranslated) { if (this.serviceType == null) { throw new ArgumentNullException("serviceType","服务类型为NULL!"); } new AspNetHostingPermission(AspNetHostingPermissionLevel.Minimal).Demand(); return (IHttpHandler)CoreGetHandler.Invoke(this, new object[] { this.serviceType, context, context.Request, context.Response }); } /// <summary> /// /// </summary> /// <param name="handler"></param> void IHttpHandlerFactory.ReleaseHandler(IHttpHandler handler) { base.ReleaseHandler(handler); } #endregion }
这个类能够成为一个工具类,这个类的是系统级的Web.config中全部.asmx文件的解析类,重载的目的就是把原来基于路径的访问变成对象访问,spa
.net框架的原版实现是这样的.net
1 public IHttpHandler GetHandler(HttpContext context, string verb, string url, string filePath) 2 { 3 TraceMethod caller = Tracing.On ? new TraceMethod(this, "GetHandler", new object[0]) : null; 4 if (Tracing.On) 5 { 6 Tracing.Enter("IHttpHandlerFactory.GetHandler", caller, Tracing.Details(context.Request)); 7 } 8 new AspNetHostingPermission(AspNetHostingPermissionLevel.Minimal).Demand(); 9 Type compiledType = WebServiceParser.GetCompiledType(url, context); 10 IHttpHandler handler = this.CoreGetHandler(compiledType, context, context.Request, context.Response); 11 if (Tracing.On) 12 { 13 Tracing.Exit("IHttpHandlerFactory.GetHandler", caller); 14 } 15 return handler; 16 }
这里的Url就是指向咱们经常使用的只有一句话的.asmx文件.rest
咱们发现CoreGetHandler是调用的目标WebService的type,可是这个函数是程序集可见,不能被咱们调用,只能用万能的反射来弄,code
最后咱们的WebService的实现为.
/// <summary> /// 数据服务接口. /// </summary> [WebService(Name="数字校园数据服务接口", Namespace="http://yaesoft.com", Description = "为第三方应用提供的基础数据服务接口")] [WebServiceBinding(ConformsTo=WsiProfiles.BasicProfile1_1)] public class DataService : WebService,IHttpHandler { #region 成员变量,构造函数./// <summary> /// 构造函数. /// </summary> public DataService() { } #endregion #region Web服务函数. /// <summary> /// 获取组织部门数据. /// </summary> /// <param name="type">部门类型.</param> /// <returns>部门信息集合.</returns> [WebMethod(Description = "获取组织部门数据.")] public List<Dept> Departments(EnumDeptType type) { ///TODO:
return null; } /// <summary> /// 获取教师用户数据. /// </summary> /// <param name="deptCode">部门代码</param> /// <returns>教师用户集合.</returns> [WebMethod(Description = "获取教师用户数据.")] public List<User> Teachers(string deptCode) {
///TODO: return null; }#endregion #region IHttpHandler 成员 /// <summary> /// /// </summary> public bool IsReusable { get { return false; } } /// <summary> /// /// </summary> /// <param name="context"></param> public void ProcessRequest(HttpContext context) { IHttpHandlerFactory factory = (IHttpHandlerFactory)new WebServiceHandlerFactory<DataService>(this); IHttpHandler handler = factory.GetHandler(context, null, null, null); handler.ProcessRequest(context); } #endregion }
因为咱们是WebService类,所以得继承WebService,
咱们须要在HttpHandlers中使用,因此至少要继承IHttpHandler接口,
而解析是在HTTPHandler接口中进行的因此咱们得在
public void ProcessRequest(HttpContext context) { IHttpHandlerFactory factory = (IHttpHandlerFactory)new WebServiceHandlerFactory<DataService>(this); IHttpHandler handler = factory.GetHandler(context, null, null, null); handler.ProcessRequest(context); }
这个方法的内容基本是不须要变化的,
咱们能够将这个类进行抽象,做为咱们全部的Webservice的基础类来使用,
而后只要在Web.config中进行HttpHandlers中进行配置便可发布WebService服务!