二十、【.Net开源】EFW框架核心类库之WebService服务
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文件
- /// <summary>
- /// WebService基类
- /// </summary>
- public class AbstractService : WebService, INewObject, INewDao
- {
- private AbstractDatabase _oleDb = null;
- private IUnityContainer _container = null;
- public AbstractDatabase oleDb
- {
- get
- {
- if (_oleDb == null)
- {
- _oleDb = FactoryDatabase.GetDatabase();
- _container = AppGlobal.container;
- }
- return _oleDb;
- }
- }
- //声明Soap头实例
- public GlobalParam param = new GlobalParam();
- #region IBindDb 成员
- public void BindDb(AbstractDatabase Db, IUnityContainer container)
- {
- _oleDb = Db;
- _container = container;
- }
- public T BindDb<T>(T model)
- {
- (model as IbindDb).BindDb(_oleDb, _container);
- return model;
- }
- public List<T> ListBindDb<T>(List<T> list)
- {
- for (int i = ; i < list.Count; i++)
- {
- (list[i] as IbindDb).BindDb(_oleDb, _container);
- }
- return list;
- }
- public AbstractDatabase GetDb()
- {
- return _oleDb;
- }
- public IUnityContainer GetUnityContainer()
- {
- return _container;
- }
- #endregion
- #region INewObject 成员
- public T NewObject<T>()
- {
- T t = FactoryModel.GetObject<T>(_oleDb, _container, null);
- return t;
- }
- public T NewObject<T>(string unityname)
- {
- T t = FactoryModel.GetObject<T>(_oleDb, _container, unityname);
- return t;
- }
- #endregion
- #region INewDao 成员
- public T NewDao<T>()
- {
- T t = FactoryModel.GetObject<T>(_oleDb, _container, null);
- return t;
- }
- public T NewDao<T>(string unityname)
- {
- T t = FactoryModel.GetObject<T>(_oleDb, _container, unityname);
- return t;
- }
- #endregion
- }
AbstractService基类的功能封装包括:
1)数据库操作对象oleDb,可以直接在WebService服务中编写SQL语句操作数据库
2)实例化ObjectModel对象和Dao对象的方法,在WebService服务中实例化对象不能用new关键字,只能用NewObject()和NewDao()内置方法;
4.通过服务名称解析WebService对象的WebServiceInvoker类的实现
WebServiceInvoker文件
- /// <summary>
- /// WebService处理对象
- /// </summary>
- public class WebServiceInvoker : IHttpHandlerFactory
- {
- private Type GetWebService(HttpRequest request, string serviceName)
- {
- Type serviceType = null;
- //for (int i = 0; i < AppGlobal.BusinessDll.Count; i++)
- //{
- // Assembly asmb = Assembly.LoadFrom(AppGlobal.AppRootPath + "bin\\" + AppGlobal.BusinessDll[i].Trim());
- // if (asmb != null)
- // {
- // Type ts = asmb.GetType(serviceName);
- // if (ts != null)
- // {
- // serviceType = ts;
- // break;
- // }
- // }
- //}
- List<Type> cmd = (List<Type>)AppGlobal.cache.GetData("cmdWebService");
- serviceType = cmd.Find(x => x.Name == serviceName);
- return serviceType;
- }
- public void ReleaseHandler(IHttpHandler handler)
- {
- var wshf = new System.Web.Services.Protocols.WebServiceHandlerFactory();
- wshf.ReleaseHandler(handler);
- }
- public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
- {
- var webServiceType = GetWebService(context.Request, GetServiceName(url));
- var wshf = new System.Web.Services.Protocols.WebServiceHandlerFactory();
- var coreGetHandler = typeof(WebServiceHandlerFactory).GetMethod("CoreGetHandler", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
- var httpHandler = (IHttpHandler)coreGetHandler.Invoke(wshf, new object[] { webServiceType, context, context.Request, context.Response });
- return httpHandler;
- }
- public static string GetServiceName(string url)
- {
- int index = url.LastIndexOf("/");
- int index2 = url.Substring(index).IndexOf(".");
- return url.Substring(index + , index2 - );
- }
- public static void LoadWebService(List<string> BusinessDll, ICacheManager cache)
- {
- List<Type> webserviceList = new List<Type>();
- for (int k = ; k < BusinessDll.Count; k++)
- {
- System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom(EFWCoreLib.CoreFrame.Init.AppGlobal.AppRootPath + "bin/" + BusinessDll[k]);
- Type[] types = assembly.GetTypes();
- for (int i = ; i < types.Length; i++)
- {
- WebServiceAttribute[] webS = ((WebServiceAttribute[])types[i].GetCustomAttributes(typeof(WebServiceAttribute), true));
- if (webS.Length > )
- {
- webserviceList.Add(types[i]);
- }
- }
- }
- cache.Add("cmdWebService", webserviceList);
- }
- }
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[]));
- }
- /// <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[]));
- }
- /// <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[]));
- }
- }
- }
二十、【.Net开源】EFW框架核心类库之WebService服务的更多相关文章
- 十九、【.Net开源】EFW框架核心类库之WCF控制器
回<[开源]EFW框架系列文章索引> EFW框架源代码下载V1.1:http://pan.baidu.com/s/1qWJjo3U EFW框架实例源代码下载:http://pan.baid ...
- 二十九、EFW框架开发的系统支持SaaS模式和实现思路
回<[开源]EFW框架系列文章索引> EFW框架源代码下载V1.3:http://pan.baidu.com/s/1c0dADO0 EFW框架实例源代码下载:http://p ...
- 十五、EnterpriseFrameWork框架核心类库之系统启动入口与初始化
本章内容是讲三种开发模式,web模式.Winform模式和Wcf模式的系统启动入口有什么区别,以及启动后系统初始化的内容:为什么要把这些单独提出来讲一章,因为我觉得本章非常重要,我们都知道程序中的ma ...
- 十四、EnterpriseFrameWork框架核心类库之简易ORM
在写本章前先去网上找了一下关于ORM的相关资料,以为本章做准备,发现很多东西今天才了解,所以在这里也对ORM做不了太深入的分析,但还是浅谈一下EFW框架中的设计的简易ORM:文中有一点讲得很有道理,D ...
- 【开源EFW框架】框架中自定义控件GridBoxCard使用实例说明
回<[开源]EFW框架系列文章索引> EFW框架源代码下载V1.3:http://pan.baidu.com/s/1c0dADO0 EFW框架实例源代码下载:http://p ...
- 第三百二十节,Django框架,生成二维码
第三百二十节,Django框架,生成二维码 用Python来生成二维码,需要qrcode模块,qrcode模块依赖Image 模块,所以首先安装这两个模块 生成二维码保存图片在本地 import qr ...
- 十八、【开源】EnterpriseFrameWork框架核心类库之Winform控制器
回<[开源]EnterpriseFrameWork框架系列文章索引> EFW框架源代码下载:http://pan.baidu.com/s/1qWJjo3U EFW框架中的WinContro ...
- 十六、【适合中小企业的.Net轻量级开源框架】EnterpriseFrameWork框架核心类库之单点登录SSO
回<[开源]EnterpriseFrameWork框架系列文章索引> EFW框架源代码下载:http://pan.baidu.com/s/1qWJjo3U 单点登录(Single Sign ...
- 十二、EnterpriseFrameWork框架核心类库之与EntLib结合
从本章开始对框架的讲叙开始进入核心类库的讲解,前面都是对框架外在功能讲解,让人有个整体的概念,知道包含哪些功能与对系统开发有什么帮助.以后多章都是讲解核心类库的,讲解的方式基本按照代码的目录结构,这样 ...
随机推荐
- 使用Lucene.NET实现数据检索功能
引言 在软件系统中查询数据是再平常不过的事情了,那当数据量非常大,数据存储的媒介不是数据库,或者检索方式要求更为灵活的时候,我们该如何实现数据的检索呢?为数据建立索引吧,利用索引技术可以更灵活 ...
- Mac OS X 系统下自带的文本文件格式转换工具iconv
1. utf-8 转 GBK的方法 在mac bash 中直接运行 iconv -f UTF-8 -t GBK test_utf8.txt > test_gbk.txt 举例:创建测试文件 ec ...
- 套路!从Ruby 到 Cocoapods的发布
前言: 现在的社会讲究的是套路,作为一名iOS工程师, 一言不合我要发套路了! 一.Ruby(ruby环境已经安装了的朋友可以跳过这一点) 准备: Mac OSX 安装xcode,它会帮你安装好 Un ...
- ftp如何预览图片 解决方案
下载使用 server-U ,开启 HTTP 服务,输入 http://ip:端口 后,登录ftp账号密码,可选使用 基于java的应用 web client 或 FTP Voyager JV,来预览 ...
- pip 豆瓣镜像使用
pip install -i https://pypi.douban.com/simple/ flask 要用https的 https://pip.pypa.io/en/latest/user_gui ...
- ECShop出现Strict Standards: Only variables should be passed by reference in的解决方法
今天安装ecshop的时候最上面出现了一个错误提示:Strict Standards: Only variables should be passed by reference in F:\www.x ...
- 集群: 如何在spring 任务中 获得集群中的一个web 容器的端口号?
系统是两台机器, 跑四个 web 容器, 每台机器两个容器 . nginx+memcached+quartz集群,web容器为 tomcat . web 应用中 用到spring 跑多个任务,任务只能 ...
- S7-200系列PLC与WINCC以太网通信CP243i的实例
S7-200系列PLC与WINCC以太网通信CP243i的实例 ----选用大连德嘉国际电子www.dl-winbest.cn的CP243i作为连接S7-200的PPI口转以太网RJ45的接口转换器. ...
- 原创:goldengate从11.2升级到12.1.2
goldengate从11.2升级到12.1.2 1.停止抽取进程 GGSCI (001.oracle.drs.dc.com) 286> stop EXTSJ01 2. 停止投递和复制进程 等待 ...
- LCLFramework框架之IOC
我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑. 借助于"第三方"实现具有依赖关系的对象之间的解 ...