使用 ServiceStack 构建跨平台 Web 服务(转)

出处:http://www.cnblogs.com/shanyou/p/3348347.html

本文主要来自MSDN杂志《Building Cross-Platform Web Services with ServiceStack》,Windows Communication Foundation (WCF) 是一个相当优秀的服务框架,当我们讨论跨平台的服务的时候,虽然WCF对WebService的支持还行,在面对一些高级应用的不太好,微软重新发展了ASP.NET WebAPI框架,关于这两个框架的讨论可以看我另外一篇文章《WCF和ASP.NET Web API在应用上的选择》 。在讨论跨平台的Web服务上,ASP.NET Web API是一个重要选项,在本文中,我将展示如何利用 ServiceStack (开放源代码.NET 和Mono REST 服务框架) 来完成这一任务,不用离开 Visual Studio 或 Microsoft.NET/Mono,除了 ServiceStack 之外还有个Nancy的框架,具体可以看《.NET的微型Web框架 Nancy》。

一个典型的 Web 服务结构如下:

Print

  • 服务层是您定义您的Web 服务接口的地方。 这也是,客户端和你的 Web 服务进行交互的一层。
  • 业务层通常是业务逻辑
  • 数据层是为了封装数据访问和操纵在业务层提供抽象的数据模型。
  • Web服务通常有远程过程调用(RPC)和RESTful (HTTP)两类,现在占据主导地位的Web服务是RESTful (HTTP),具体内容可以参看文章《REST在企业中获得成功了么?》,贴一张文章里的图片:

REST&SOAP1

2年前REST就已经成为Web API部署方式的主流了,而且一直保持这种发展势头,现在基本上都是REST服务,SOAP在企业内网还存在。

远程过程调用 (RPC) ,每个请求旨在类似于函数调用:

public interface IService

{

      string DoSomething(int input);

}

RPC 方法对服务的修改非常不友好。 例如前面的代码段,如果要求从客户端来执行更高版本的 Web 服务的 DoSomething 方法的两个输入参数 — 或需要返回字符串值之外的另一个字段 —— 给老客户重大更改是不可避免的。 当然,您始终可以创建平行的 DoSomething_v2 方法,要带两个输入的参数,但久而久之会搞乱您的 Web 服务接口和消费者,服务变得越来越丑,用WCF实现的Web服务就是属于这种情况,下面我们介绍ServiceStack。

ServiceStack是.Net和Mono的开源框架,相对WCF,MVC及Web API而言它是开发Web服务与Web应用的有力替代品,它越来越普及。 用 ServiceStack 生成的 web 服务可以运行在 Windows 环境中,.NET 代码或Mono支持 Linux 环境中。 Mono支持的操作系统包括:

  • Linux
  • Mac OS X, iOS
  • Sun Solaris
  • BSD
  • Microsoft Windows
  • Nintendo Wii
  • Sony PlayStation 3

ServiceStack是一系列事物的综合体:

  • 包含高性能Razor Engine的Web应用框架
  • 支持例如HTML,XML,JSON,SOAP等多种格式的基于消息的Web服务框架
  • 包含内建IOC的容器
  • 若干内建库文件,诸如:Text serializer,Redis Client,ORM以及caching providers
  • 除了ASP.NET Hosting和Mono Hosting之外,还包含self-hosting选项

ServiceStack 强制远程 Web 服务最佳实践、 基于公约 DTO 标准为其 Web 服务接口,ServiceStack 还提供预置的响应状态对象,可用于撰写 DTO,鼓励更加直接和简单的错误处理方案,显然和WCF是明显不同的路线。

本文假定您有一些熟悉 WCF 和.NET 框架。 为了更好地展示WCF 概念可以如何转化为 ServiceStack 的概念,首先会在WCF中实现服务层。我会告诉你如何通过将WCF Web 服务移植到等效的使用 ServiceStack 转换为跨平台的 Web 服务。

WCF 使用数据合同建立的客户端和服务器之间的通信手段。 ServiceStack和WCF相同。 WCF 需要何数据对象和数据成员打上标记; 否则,WCF 简单地忽略它们。 这是 ServiceStack 和 WCF 与的不同的地方。 ServiceStack 支持所有POCO 的对象作为契约:

WCF的契约:

   [DataContract] 
    public class Ticket 
    { 
        [DataMember] 
        public int TicketId { get; set; } 
        [DataMember] 
        public int TableNumber { get; set; } 
        [DataMember] 
        public int ServerId { get; set; } 
        [DataMember] 
        public List<Order> Orders { get; set; } 
        [DataMember] 
        public DateTime Timestamp { get; set; } 
    } 
    [ServiceContract] 
    public interface ITicketService 
    { 
        /// <summary> 
        /// 检索当前队列中的所有门票的完整清单 
        /// </summary> 
        /// <returns></returns> 
        [OperationContract] 
        List<Ticket> GetAllTicketsInQueue();

        /// <summary> 
        /// 新增新门票 
        /// </summary> 
        /// <param name="ticket"></param> 
        [OperationContract] 
        void QueueTicket(Ticket ticket);

        /// <summary> 
        /// 从队列拉出一张票 
        /// </summary> 
        /// <returns></returns> 
        [OperationContract] 
        Ticket PullTicket(); 
    } 
}

把它转换为ServiceStack的契约:

public class Ticket 

       public int TicketId { get; set; } 
        public int TableNumber { get; set; } 
        public int ServerId { get; set; } 
        public List<Order> Orders { get; set; } 
        public DateTime Timestamp { get; set; }

}

public class GetAllTicketsInQueueRequest 

}

public class QueueTicketRequest 

    public Ticket Ticket { get; set; } 
}

public class PullTicketRequest 

}

public interface ISCTicketService 

    List<Ticket> Any(GetAllTicketsInQueueRequest request);

    void Any(QueueTicketRequest request);

    Ticket Any(PullTicketRequest request); 
}

ServiceStack 规定每个唯一的请求是对象所标识唯一的请求,这意味着你不能重用 DTO 跨多个服务实现与 ServiceStack 的请求。ServiceStack 支持不同的操作,如有 Get 和 Post。 您的选择在这里仅影响的 HTTP 请求。 指定任何 Web 服务请求是指可以通过 HTTP GET 和 HTTP POST 调用操作。 这种强制措施,简化了 rest 风格的 Web 服务实现。要将您的 ServiceStack Web 服务变成 rest 风格的 Web 服务,只需添加 URL [Route(...)]向您的 Web 服务请求声明属性。

    //Request DTO 
    public class Hello 
    { 
        public string Name { get; set; } 
    }

    //Response DTO 
    public class HelloResponse 
    { 
        public string Result { get; set; } 
        public ResponseStatus ResponseStatus { get; set; } //Where Exceptions get auto-serialized 
    }

    //Can be called via any endpoint or format, see: http://servicestack.net/ServiceStack.Hello/ 
    public class HelloService : Service 
    { 
        public object Any(Hello request) 
        { 
            return new HelloResponse { Result = "Hello, " + request.Name }; 
        } 
    }

    //REST Resource DTO 
    [Route("/todos")] 
    [Route("/todos/{Ids}")] 
    public class Todos : IReturn<List<Todo>> 
    { 
        public long[] Ids { get; set; } 
        public Todos(params long[] ids) 
        { 
            this.Ids = ids; 
        } 
    }

    [Route("/todos", "POST")] 
    [Route("/todos/{Id}", "PUT")] 
    public class Todo : IReturn<Todo> 
    { 
        public long Id { get; set; } 
        public string Content { get; set; } 
        public int Order { get; set; } 
        public bool Done { get; set; } 
    }

    public class TodosService : Service 
    { 
        public TodoRepository Repository { get; set; }  //Injected by IOC

        public object Get(Todos request) 
        { 
            return request.Ids.IsEmpty() 
                ? Repository.GetAll() 
                : Repository.GetByIds(request.Ids); 
        }

        public object Post(Todo todo) 
        { 
            return Repository.Store(todo); 
        }

        public object Put(Todo todo) 
        { 
            return Repository.Store(todo); 
        }

        public void Delete(Todos request) 
        { 
            Repository.DeleteByIds(request.Ids); 
        } 
    }   

以ASP.NET Hosting承载ServiceStack,创建一个空的ASP.NET应用,使用 NuGet 包管理器控制台将 ServiceStack 引用添加到 ServiceStack.Host.AspNet中所示

image

Web.config 会增加下面的配置

<configuration> 
  <system.web> 
    <compilation debug="true" targetFramework="4.0" /> 
    <httpHandlers> 
      <add path="*" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*" /> 
    </httpHandlers> 
  </system.web> 
  <system.webServer> 
    <modules runAllManagedModulesForAllRequests="true" /> 
    <validation validateIntegratedModeConfiguration="false" /> 
    <handlers> 
      <add path="*" name="ServiceStack.Factory" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*" preCondition="integratedMode" resourceType="Unspecified" allowPathInfo="true" /> 
    </handlers> 
  </system.webServer> 
</configuration>

你需要从 ServiceStack.WebHost.End 继承­实现端点。

public class AppHost  : AppHostBase 
    {        
        public AppHost() //Tell ServiceStack the name and where to find your web services 
            : base("StarterTemplate ASP.NET Host", typeof(HelloService).Assembly) { }

        public override void Configure(Funq.Container container) 
        { 
            //Set JSON web services to return idiomatic JSON camelCase properties 
            ServiceStack.Text.JsConfig.EmitCamelCaseNames = true; 
        
            //Configure User Defined REST Paths 
            Routes 
              .Add<Hello>("/hello") 
              .Add<Hello>("/hello/{Name*}");

            //Uncomment to change the default ServiceStack configuration 
            //SetConfig(new EndpointHostConfig { 
            //});

            //Enable Authentication 
            //ConfigureAuth(container);

            //Register all your dependencies 
            container.Register(new TodoRepository());            
        }

        /* Uncomment to enable ServiceStack Authentication and CustomUserSession 
        private void ConfigureAuth(Funq.Container container) 
        { 
            var appSettings = new AppSettings();

            //Default route: /auth/{provider} 
            Plugins.Add(new AuthFeature(() => new CustomUserSession(), 
                new IAuthProvider[] { 
                    new CredentialsAuthProvider(appSettings), 
                    new FacebookAuthProvider(appSettings), 
                    new TwitterAuthProvider(appSettings), 
                    new BasicAuthProvider(appSettings), 
                }));

            //Default route: /register 
            Plugins.Add(new RegistrationFeature());

            //Requires ConnectionString configured in Web.Config 
            var connectionString = ConfigurationManager.ConnectionStrings["AppDb"].ConnectionString; 
            container.Register<IDbConnectionFactory>(c => 
                new OrmLiteConnectionFactory(connectionString, SqlServerDialect.Provider));

            container.Register<IUserAuthRepository>(c => 
                new OrmLiteAuthRepository(c.Resolve<IDbConnectionFactory>()));

            var authRepo = (OrmLiteAuthRepository)container.Resolve<IUserAuthRepository>(); 
            authRepo.CreateMissingTables(); 
        } 
        */

        public static void Start() 
        { 
            new AppHost().Init(); 
        } 
    }

ServiceStack Web 应用程序启动时,您的服务合同列出作为元数据操作,如图所示:

image

相关文章:

SignalR, Filters and ServiceStack

采访ServiceStack的项目领导Demis Bellot——第1部分

采访ServiceStack的项目领导Demis Bellot——第2部分            

转载于:https://www.cnblogs.com/smileberry/p/4518849.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/419897.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

框架详解_详解:python Web框架flask表单实现(建议收藏)

今天为大家带来的内容是&#xff1a;python框架flask表单实现详解文章内容主要介绍了python框架flask表单实现详解,文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下&#xff01;&#xff01;&#xff01;表单表单…

共享内存中使用指针_详解c++中字符指针数组的使用

之前有写过一篇叫c中动态数组的使用&#xff0c;今来看看c中的字符指针数组的使用。涛哥&#xff1a;c中的动态数组使用​zhuanlan.zhihu.com指针数组&#xff0c;就指向指针的指针&#xff0c;很早以前在说指针的时候说过&#xff0c;但后来发现很多人还是比较难以理解&#x…

软件测试用例项目写作,通用测试用例写作方法

测试用例工作过程软件测试用例设计和软件测试用例写作软件测试用例设计&#xff1a;从设计层面考虑(功能性、可用性、安全性等方面)&#xff1b;软件测试用例写作&#xff1a;指的是软件测试用例的写作规范(格式、标识的命名规范等)软件测试用例设计设计出用例的内容&#xff0…

二叉树学习笔记--先序遍历

首先数据二叉树中数据存储如图&#xff0c;n代表节点为空 &#xff0c;此时退出当前函数。 分解各个步骤如图&#xff0c;为了简化&#xff0c;将节点中的数据代表节点&#xff0c;先left执行&#xff0c;left执行前先输出数据&#xff0c;left执行时&#xff0c;right等待。此…

apache cgi 模块安装

apache安装,请参照:http://httpd.apache.org/docs/2.4/ 安装系统: Fedora release 21 (Twenty One) (x64) 版本:Server version: Apache/2.4.12 (Unix) 安装方式: 源码安装, 源文件目录: /home/web/docs/soft/httpd-2.4.12 安装目录: /usr/local/apache2 在安装apache 之后,…

eslint 无法格式化ts_vscode保存代码,自动按照eslint规范格式化代码设置

vscode保存代码&#xff0c;自动按照eslint规范格式化代码设置编辑器代码风格一致&#xff0c;是前端代码规范的一部分。我们现在前端绝大部分都在使用eslint&#xff0c;或者将要把代码改为eslint&#xff0c;那么此时我们怎么方便使用这个规范呢&#xff0c;下面我来介绍一下…

8个球放入3个盒子方式_8种土豆做法,好吃到根本停不下来!

石锅土豆鸡块鸡腿3&#xff0c;土豆1&#xff0c;青椒2洋葱一半&#xff0c;辣椒10g&#xff0c;肉桂5g八角2&#xff0c;生姜10克&#xff0c;大蒜15g1。将鸡腿洗净切成大块&#xff0c;切成薄片&#xff0c;切青椒&#xff0c;切洋葱片&#xff0c;姜片和蒜片去皮。2、在锅里…

计算机d盘被拒绝访问了怎么办,如果硬盘分区被拒绝访问或无法访问该怎么办?...

拒绝访问硬盘分区的原因可能是硬盘分区表已损坏&#xff0c;导致系统无法正确读取硬盘的分区信息&#xff0c;或者可能是某些软件(例如加密软件)已使用&#xff0c;并且磁盘权限已修改.Bit提供了几种解决方案&#xff0c;请参见下面的具体操作方法:修复方法一&#xff0c;使用硬…

c++电费管理系统_能耗管理系统

园区能源管理系统是专注于园区能耗在线监测以及能耗评估的综合能源管理系统。一、应用背景存在问题&#xff1a;园区建筑功能构成较为复杂&#xff0c;用能设备多&#xff0c;耗能量大&#xff0c;监管难度高。安全、舒适是首要考虑因素&#xff0c;维持这一效果需要消耗更多的…

泰拉瑞亚服务器怎么让玩家注册,上线10年,《泰拉瑞亚》为何变成了一款交友游戏?...

《泰拉瑞亚》这款游戏,最初于2011年5月16日在PC上发行,之后也陆续登录安卓和苹果手机端,如今已走过了十个年头。也许对于《泰拉瑞亚》部分人并不是很熟悉,但提起《我的世界》,相信大部分游戏爱好者都会有共同话题。而《泰拉瑞亚》就是被玩家戏称为横版的Minecraft,因为游戏给玩…

【链表+启发式合并】Bzoj1483 [HNOI2009] 梦幻布丁

Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. Input 第一行给出N,M表示布丁的个数和好友的操作次数. 第二行N个数A1,A2...An表示第i个布丁的颜色从第三行…

小程序秒杀活动服务器,微信小程序官方上线张大仙周年活动,人数太多把服务器弄崩溃了...

原标题&#xff1a;微信小程序官方上线张大仙周年活动&#xff0c;人数太多把服务器弄崩溃了说起如今人气最旺的《王者荣耀》主播&#xff0c;莫过于就是靠着一手“素质直播”走遍天下的张大仙了。之前由于一些合同上面的问题&#xff0c;张大仙被迫停播了一段时间&#xff0c;…

curl 怎么在xp下使用_Http Post 快速使用

点击上方蓝字可直接关注&#xff01;方便下次阅读。如果对你有帮助&#xff0c;麻烦点个在看或点个赞&#xff0c;感谢~一直对http很陌生&#xff0c;这次借助libcurl分享一个快速使用http post的案例。平台&#xff1a;ubuntu16.04一、libcurl的安装1. Git上下载 master最新代…

ajax 高并发请求,理解node.js处理高并发请求原理

很少分享技术文章&#xff0c;写的不好的地方请大家多多指教&#xff0c;本文是自己对于node.js的一些见解&#xff0c;如有纰漏请在评论区交流。高并发策略通常高并发的解决方案就是提供多线程模型&#xff0c;服务器为每个客户端请求分配一个线程&#xff0c;使用同步 I/O&am…

abaqus生成adams柔性体_基于ADAMS 的大型反铲挖泥机加装破碎锤 结构动力学分析

刘 斌 徐沪萍 王 磊武汉理工大学物流工程学院 武汉 430063摘 要&#xff1a;以配备液压破碎锤的反铲挖泥船反铲挖泥机为研究对象&#xff0c;简单介绍加装液压破碎锤方案&#xff0c;然后运用动力学理论和相关的动态仿真软件&#xff0c;通过建立反铲挖泥机的刚柔耦合模型&…

rust加载不进去服务器eac_基于腾讯云的 Rust 和 WebAssembly 函数即服务

腾讯云云函数 (SCF) 已经支持十多种编程语言和运行时框架。腾讯云最近发布的 SCF custom runtime&#xff08;自定义运行时&#xff09;更进一步 —— SCF 现在可以支持用任何编程语言编写的函数。本文将介绍如何在云函数 SCF 中运行用 Rust 编写的 WebAssembly 函数。我们先介…