• 二十、【.Net开源】EFW框架核心类库之WebService服务


    回《【开源】EFW框架系列文章索引》       

    EFW框架源代码下载V1.1:http://pan.baidu.com/s/1qWJjo3U

    EFW框架实例源代码下载:http://pan.baidu.com/s/1o6MAKCa

     

           EFW框架中的WebService服务开发方式与传统的net项目中开发不太一样,传统的开发方式虽然也挺简单但在后面的发布部署还是挺麻烦的,而在EFW框架中开发Webservice就跟编写普通的C#代码一样,并不需要单独建WebService服务项目,不需要Asmx文件;所以发布WebService只要把编译好的Dll拷贝到Web程序目录中就行了;

           另外我建议尽量少用WebService服务来开发业务功能,系统内部的功能实现用前三章的控制器方式就可以搞定,只有在需要与外部系统做接口时,可以用它来开发相关接口程序;

    本章主要内容通过解读框架源代码来学习WebService服务是怎么实现的,以及学习这种设计模式;

    本文要点:

    1.如何开发WebService系统接口

    2.WebService服务的设计思路

    3.WebService服务基类的AbstractService的实现

    4.通过服务名称解析WebService对象的WebServiceInvoker类的实现

    5.利用wsdl生成WebService生成代理类

    WebService服务源代码目录结构:

     

    EFW框架控制器设计图:

     

     

    1.如何开发WebService系统接口

     

    如上图,Books项目中实现了书籍实例的一些Webservice系统接口,bookWebService.cs文件是和逻辑层代码放在一起的,并不需要单独建一个Webservice服务项目,也不需要建到Web项目中;对比一下上图普通的WebService服务,不需要BookService.asmx文件;

     

    见上图,WebService服务接口的使用跟普通的Net 系统中的WebService是一样的,地址栏中输入WebService服务对象的名称就可以调用,但是注意名称一样但是必须用asmx为后缀名,因为服务器只解析这种后缀名称的文件映射到后台的WebService服务;上图开放了两个WebService服务方法SaveBook和SearchBook。

     

    2.WebService服务的设计思路

           当初设计这种开发模式的目的就是为了减少项目的个数,到现在整个框架的项目只有5个,而且只有5个项目却包括了Web、Winform和WCF三种系统的开发;这都是为了秉承框架中的核心思想“简洁”,结构的简单明了,代码的整洁干净;所以为了几个WebService接口而增加一个WebService项目觉得太划不来了,所以开始思考如何实现,后来在网上看到了一个帖子讲动态调用WebService服务的,具体哪个帖子现在找不到了,反正我就借鉴了过来融入到了框架中,终于解决了这个难题;WebServiceInvoker类就是动态解析WebService服务的实现代码;所有WebService服务对象都必须继承AbstractService基类,AbstractService基类封装了WebService服务公共的处理功能;

     

    3.WebService服务基类的AbstractService的实现

    AbstractService文件

     1   /// <summary>
     2     /// WebService基类
     3     /// </summary>
     4     public class AbstractService : WebService, INewObject, INewDao
     5     {
     6 
     7         private AbstractDatabase _oleDb = null;
     8         private IUnityContainer _container = null;
     9         public AbstractDatabase oleDb
    10         {
    11             get
    12             {
    13                 if (_oleDb == null)
    14                 {
    15                     _oleDb = FactoryDatabase.GetDatabase();
    16                     _container = AppGlobal.container;
    17                 }
    18                 return _oleDb;
    19             }
    20         }
    21 
    22         //声明Soap头实例
    23         public GlobalParam param = new GlobalParam();
    24 
    25         #region IBindDb 成员
    26 
    27         public void BindDb(AbstractDatabase Db, IUnityContainer container)
    28         {
    29             _oleDb = Db;
    30             _container = container;
    31         }
    32 
    33         public T BindDb<T>(T model)
    34         {
    35             (model as IbindDb).BindDb(_oleDb, _container);
    36             return model;
    37         }
    38 
    39         public List<T> ListBindDb<T>(List<T> list)
    40         {
    41             for (int i = 0; i < list.Count; i++)
    42             {
    43                 (list[i] as IbindDb).BindDb(_oleDb, _container);
    44             }
    45             return list;
    46         }
    47 
    48         public AbstractDatabase GetDb()
    49         {
    50             return _oleDb;
    51         }
    52 
    53         public IUnityContainer GetUnityContainer()
    54         {
    55             return _container;
    56         }
    57 
    58         #endregion
    59 
    60         #region INewObject 成员
    61         public T NewObject<T>()
    62         {
    63             T t = FactoryModel.GetObject<T>(_oleDb, _container, null);
    64             return t;
    65         }
    66 
    67         public T NewObject<T>(string unityname)
    68         {
    69             T t = FactoryModel.GetObject<T>(_oleDb, _container, unityname);
    70             return t;
    71         }
    72 
    73         #endregion
    74 
    75         #region INewDao 成员
    76 
    77         public T NewDao<T>()
    78         {
    79             T t = FactoryModel.GetObject<T>(_oleDb, _container, null);
    80             return t;
    81         }
    82 
    83         public T NewDao<T>(string unityname)
    84         {
    85             T t = FactoryModel.GetObject<T>(_oleDb, _container, unityname);
    86             return t;
    87         }
    88 
    89         #endregion
    90 
    91     }
    View Code

    AbstractService基类的功能封装包括:

    1)数据库操作对象oleDb,可以直接在WebService服务中编写SQL语句操作数据库

    2)实例化ObjectModel对象和Dao对象的方法,在WebService服务中实例化对象不能用new关键字,只能用NewObject()和NewDao()内置方法;

     

    4.通过服务名称解析WebService对象的WebServiceInvoker类的实现

    WebServiceInvoker文件

     1 /// <summary>
     2     /// WebService处理对象
     3     /// </summary>
     4     public class WebServiceInvoker : IHttpHandlerFactory
     5     {
     6         private Type GetWebService(HttpRequest request, string serviceName)
     7         {
     8             Type serviceType = null;
     9             //for (int i = 0; i < AppGlobal.BusinessDll.Count; i++)
    10             //{
    11             //    Assembly asmb = Assembly.LoadFrom(AppGlobal.AppRootPath + "bin\\" + AppGlobal.BusinessDll[i].Trim());
    12             //    if (asmb != null)
    13             //    {
    14             //        Type ts = asmb.GetType(serviceName);
    15             //        if (ts != null)
    16             //        {
    17             //            serviceType = ts;
    18             //            break;
    19             //        }
    20             //    }
    21             //}
    22 
    23             List<Type> cmd = (List<Type>)AppGlobal.cache.GetData("cmdWebService");
    24             serviceType = cmd.Find(x => x.Name == serviceName);
    25             return serviceType;
    26         }
    27 
    28         public void ReleaseHandler(IHttpHandler handler)
    29         {
    30             var wshf = new System.Web.Services.Protocols.WebServiceHandlerFactory();
    31             wshf.ReleaseHandler(handler);
    32         }
    33 
    34         public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
    35         {
    36             var webServiceType = GetWebService(context.Request, GetServiceName(url));
    37             var wshf = new System.Web.Services.Protocols.WebServiceHandlerFactory();
    38             var coreGetHandler = typeof(WebServiceHandlerFactory).GetMethod("CoreGetHandler", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
    39             var httpHandler = (IHttpHandler)coreGetHandler.Invoke(wshf, new object[] { webServiceType, context, context.Request, context.Response });
    40             return httpHandler;
    41         }
    42 
    43         public static string GetServiceName(string url)
    44         {
    45             int index = url.LastIndexOf("/");
    46             int index2 = url.Substring(index).IndexOf(".");
    47             return url.Substring(index + 1, index2 - 1);
    48         }
    49 
    50         public static void LoadWebService(List<string> BusinessDll, ICacheManager cache)
    51         {
    52             List<Type> webserviceList = new List<Type>();
    53 
    54             for (int k = 0; k < BusinessDll.Count; k++)
    55             {
    56                 System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom(EFWCoreLib.CoreFrame.Init.AppGlobal.AppRootPath + "bin/" + BusinessDll[k]);
    57                 Type[] types = assembly.GetTypes();
    58                 for (int i = 0; i < types.Length; i++)
    59                 {
    60                     WebServiceAttribute[] webS = ((WebServiceAttribute[])types[i].GetCustomAttributes(typeof(WebServiceAttribute), true));
    61                     if (webS.Length > 0)
    62                     {
    63                         webserviceList.Add(types[i]);
    64                     }
    65                 }
    66             }
    67 
    68             cache.Add("cmdWebService", webserviceList);
    69         }
    70     }
    View Code

    WebServiceInvoker对象继承IHttpHandlerFactory接口并实现接口方法GetHandler和ReleaseHandler,还要在Web.Config配置文件中进行配置;

     

    5.利用wsdl生成WebService生成代理类

    生成命令:wsdl /language:c# /out:c:\bookWebService.cs http://localhost:51796/bookWebService.asmx?WSDL

    操作步骤:

    1)打开Net命令工具

     

    2)复制上面的wsdl命令并执行,提示写入“c:\bookWebService.cs ”成功

     

    3)再把“c:\bookWebService.cs ”的文件拷贝到需要调用WebService接口的项目中使用就可以了;

    bookWebService文件

    //------------------------------------------------------------------------------
    // <auto-generated>
    //     此代码由工具生成。
    //     运行时版本:2.0.50727.5477
    //
    //     对此文件的更改可能会导致不正确的行为,并且如果
    //     重新生成代码,这些更改将会丢失。
    // </auto-generated>
    //------------------------------------------------------------------------------
    
    using System;
    using System.ComponentModel;
    using System.Data;
    using System.Diagnostics;
    using System.Web.Services;
    using System.Web.Services.Protocols;
    using System.Xml.Serialization;
    
    // 
    // 此源代码由 wsdl 自动生成, Version=2.0.50727.1432。
    // 
    
    
    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.1432")]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Web.Services.WebServiceBindingAttribute(Name="bookWebServiceSoap", Namespace="http://tempuri.org/")]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(MarshalByRefObject))]
    public partial class bookWebService : System.Web.Services.Protocols.SoapHttpClientProtocol {
        
        private System.Threading.SendOrPostCallback SaveBookOperationCompleted;
        
        private System.Threading.SendOrPostCallback SearchBookOperationCompleted;
        
        /// <remarks/>
        public bookWebService() {
            this.Url = "http://localhost:51796/bookWebService.asmx";
        }
        
        /// <remarks/>
        public event SaveBookCompletedEventHandler SaveBookCompleted;
        
        /// <remarks/>
        public event SearchBookCompletedEventHandler SearchBookCompleted;
        
        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/SaveBook", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
        public void SaveBook(Book book) {
            this.Invoke("SaveBook", new object[] {
                        book});
        }
        
        /// <remarks/>
        public System.IAsyncResult BeginSaveBook(Book book, System.AsyncCallback callback, object asyncState) {
            return this.BeginInvoke("SaveBook", new object[] {
                        book}, callback, asyncState);
        }
        
        /// <remarks/>
        public void EndSaveBook(System.IAsyncResult asyncResult) {
            this.EndInvoke(asyncResult);
        }
        
        /// <remarks/>
        public void SaveBookAsync(Book book) {
            this.SaveBookAsync(book, null);
        }
        
        /// <remarks/>
        public void SaveBookAsync(Book book, object userState) {
            if ((this.SaveBookOperationCompleted == null)) {
                this.SaveBookOperationCompleted = new System.Threading.SendOrPostCallback(this.OnSaveBookOperationCompleted);
            }
            this.InvokeAsync("SaveBook", new object[] {
                        book}, this.SaveBookOperationCompleted, userState);
        }
        
        private void OnSaveBookOperationCompleted(object arg) {
            if ((this.SaveBookCompleted != null)) {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.SaveBookCompleted(this, new System.ComponentModel.AsyncCompletedEventArgs(invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }
        
        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/SearchBook", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
        public System.Data.DataTable SearchBook(string schar, int flag) {
            object[] results = this.Invoke("SearchBook", new object[] {
                        schar,
                        flag});
            return ((System.Data.DataTable)(results[0]));
        }
        
        /// <remarks/>
        public System.IAsyncResult BeginSearchBook(string schar, int flag, System.AsyncCallback callback, object asyncState) {
            return this.BeginInvoke("SearchBook", new object[] {
                        schar,
                        flag}, callback, asyncState);
        }
        
        /// <remarks/>
        public System.Data.DataTable EndSearchBook(System.IAsyncResult asyncResult) {
            object[] results = this.EndInvoke(asyncResult);
            return ((System.Data.DataTable)(results[0]));
        }
        
        /// <remarks/>
        public void SearchBookAsync(string schar, int flag) {
            this.SearchBookAsync(schar, flag, null);
        }
        
        /// <remarks/>
        public void SearchBookAsync(string schar, int flag, object userState) {
            if ((this.SearchBookOperationCompleted == null)) {
                this.SearchBookOperationCompleted = new System.Threading.SendOrPostCallback(this.OnSearchBookOperationCompleted);
            }
            this.InvokeAsync("SearchBook", new object[] {
                        schar,
                        flag}, this.SearchBookOperationCompleted, userState);
        }
        
        private void OnSearchBookOperationCompleted(object arg) {
            if ((this.SearchBookCompleted != null)) {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.SearchBookCompleted(this, new SearchBookCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }
        
        /// <remarks/>
        public new void CancelAsync(object userState) {
            base.CancelAsync(userState);
        }
    }
    
    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.1432")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/")]
    public partial class Book : AbstractEntity {
        
        private int idField;
        
        private string bookNameField;
        
        private decimal buyPriceField;
        
        private System.DateTime buyDateField;
        
        private int flagField;
        
        /// <remarks/>
        public int Id {
            get {
                return this.idField;
            }
            set {
                this.idField = value;
            }
        }
        
        /// <remarks/>
        public string BookName {
            get {
                return this.bookNameField;
            }
            set {
                this.bookNameField = value;
            }
        }
        
        /// <remarks/>
        public decimal BuyPrice {
            get {
                return this.buyPriceField;
            }
            set {
                this.buyPriceField = value;
            }
        }
        
        /// <remarks/>
        public System.DateTime BuyDate {
            get {
                return this.buyDateField;
            }
            set {
                this.buyDateField = value;
            }
        }
        
        /// <remarks/>
        public int Flag {
            get {
                return this.flagField;
            }
            set {
                this.flagField = value;
            }
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(Book))]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.1432")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/")]
    public abstract partial class AbstractEntity : AbstractBusines {
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(AbstractEntity))]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(Book))]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.1432")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/")]
    public abstract partial class AbstractBusines : MarshalByRefObject {
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(AbstractBusines))]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(AbstractEntity))]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(Book))]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.1432")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/")]
    public abstract partial class MarshalByRefObject {
    }
    
    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.1432")]
    public delegate void SaveBookCompletedEventHandler(object sender, System.ComponentModel.AsyncCompletedEventArgs e);
    
    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.1432")]
    public delegate void SearchBookCompletedEventHandler(object sender, SearchBookCompletedEventArgs e);
    
    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.1432")]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    public partial class SearchBookCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs {
        
        private object[] results;
        
        internal SearchBookCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : 
                base(exception, cancelled, userState) {
            this.results = results;
        }
        
        /// <remarks/>
        public System.Data.DataTable Result {
            get {
                this.RaiseExceptionIfNecessary();
                return ((System.Data.DataTable)(this.results[0]));
            }
        }
    }
    View Code
  • 相关阅读:
    函数方法与面向对象
    seleniums私房菜系列一 ---- selenium简介
    MySQL图形化管理工具
    存储引擎
    mysql自定义函数
    加密函数
    mysql聚合函数
    mysql信息函数
    mysql日期时间函数(常用的)
    mysql比较运算符和函数
  • 原文地址:https://www.cnblogs.com/kakake/p/3984271.html
Copyright © 2020-2023  润新知