zoukankan      html  css  js  c++  java
  • C#下丢掉.asmx文件的WebService的实现

    我在用.net实现Webservice的时候发现需要一个没有任何用处的.asmx文件,但是却没法删除,这两天我实现一个通过接口时想实现dll直接部署,不需要弄个.asmx文件.翻阅了很多,最后在Spring.net里面得到了启示.

    我要实现的方式是直接在httpHandlers中配置

        <httpHandlers>
                <add verb="*" path="XXXservice.asmx" type="CampusWebService.DataService,CampusWebService"/>
        </httpHandlers>

    然后通过就可以直接部署,特别适合进行二次开发,嵌入式开始什么的.

    具体的实现如下:

    先需需要通过继承反射实现一个c#的程序集封装的调用(很讨厌C#的程序集封装,讨嫌的要死)

     /// <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文件的解析类,重载的目的就是把原来基于路径的访问变成对象访问,

    .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文件.

    我们发现CoreGetHandler调用的目标WebService的type,但是这个函数是程序集可见,不能被我们调用,只能用万能的反射来弄,

    最后我们的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服务!

    
    
    
    
    

    己所不欲,勿施于人。

  • 相关阅读:
    centos7系统中忘记了root管理员账号密码的解决方式
    【python之路48】生成器表达式、推导式
    小米集团信息化中台战略
    分时函数
    函数节流
    JS浮点计算问题
    要转型做前端开发了
    优秀的开发人员和测试人员应有的态度
    C#数组的笔记
    LINQ不包含列表
  • 原文地址:https://www.cnblogs.com/jeason1914/p/3190912.html
Copyright © 2011-2022 走看看