C#下丟掉.asmx文件的WebService的實現

我在用.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服務!

相關文章
相關標籤/搜索