本文主要来自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 服务结构如下:

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

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中所示

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 应用程序启动时,您的服务合同列出作为元数据操作,如图所示:

相关文章:

SignalR, Filters and ServiceStack

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

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

转载于:https://www.cnblogs.com/shanyou/p/3348347.html

使用 ServiceStack 构建跨平台 Web 服务相关推荐

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

    出处:http://www.cnblogs.com/shanyou/p/3348347.html 本文主要来自MSDN杂志<Building Cross-Platform Web Service ...

  2. flask url构建_如何为生产构建构建Flask-RESTPlus Web服务

    flask url构建 by Greg Obinna 由格雷格·奥比纳(Greg Obinna) 如何为生产构建构建Flask-RESTPlus Web服务 (How to structure a F ...

  3. 构建 RESTful Web 服务

    from: https://www.ibm.com/developerworks/cn/education/java/j-rest/j-rest.html 开始之前 关于本教程 REST 是一种思维方 ...

  4. 使用 Jersey 和 Apache Tomcat 构建 RESTful Web 服务

    http://www.ibm.com/developerworks/cn/web/wa-aj-tomcat/ 使用 Jersey 和 Apache Tomcat 构建 RESTful Web 服务 Y ...

  5. 使用Spring Boot构建REST Web服务

    本教程提供了有关如何使用Spring Boot构建Restfull Web服务的分步指南. 先决条件: Eclipse IDE(最新版本) Maven的4 Java 1.8 1.创建Maven Web ...

  6. Guzzle – 构建 RESTful Web 服务的 PHP HTTP 框架

    Guzzle 减轻了发送 HTTP 请求和创建 Web 服务客户端的痛苦.它包含建立一个强大的网络服务客户端的工具,包括:服务描述定义的输入和输出的 API,资源迭代器遍历分页资源,尽可能有效地发送大 ...

  7. Spring Boot 构建RESTful Web服务

    Spring Boot 构建RESTful Web服务 本指南将引导您完成使用Spring 创建" Hello World" RESTful Web服务的过程. 你会建立什么 您将 ...

  8. 使用 Spring 3 MVC HttpMessageConverter 功能构建 RESTful web 服务

    Spring,构建 Java™ 平台和 Enterprise Edition (Java EE) 应用程序的著名框架,现在在其模型-视图-控制器(Model-View-Controller ,MVC) ...

  9. jersey tomcat MySQL_基于jersey和Apache Tomcat构建Restful Web服务(一)

    基于jersey和Apache Tomcat构建Restful Web服务(一) 现如今,RESTful架构已然成为了最流行的一种互联网软件架构,它结构清晰.符合标准.易于理解.扩展方便,所以得到越来 ...

最新文章

  1. [转]CentOS 5.5下FTP安装及配置
  2. 从视觉系统的原理入手 破解VR眩晕症
  3. HR最常用的Excel技巧,职场必备,值得收藏转发!
  4. 回顾2019年5个重大宕机事件
  5. oracle timestamp比较大小_ORACLE包和过程依赖关系测试
  6. 如何使用Maven scope
  7. linux 进程 释放内存,Linux 释放内存方法和原理
  8. __bridge,__bridge_retained,__bridge_transfer
  9. $(document).ready()与window.onload的区别
  10. android db加载后无法读取任何内容_android性能优化(二)之卡顿优化
  11. iOS开发常用的RGB色值
  12. 【转】【CN五一装机版】GhostXP_SP3电脑公司通用版v19.2装机版NTFS
  13. android 微信浮窗实现_Android仿微信文章悬浮窗效果的实现代码
  14. 浅析大数据与传统经济学
  15. linux上的离线地图,离线地图接入指南
  16. 夺命雷公狗ThinkPHP项目之----企业网站25之网站前台面包屑导航URL的完善
  17. python循环读取excel存入列表_python3 循环读取excel文件并写入json操作
  18. HDMI接口简介---分辨率 时钟频率 lane速率计算
  19. 广告图片自动轮播控件
  20. golang的运维开发

热门文章

  1. 使用DNS 轻松获取主机信息
  2. Django的视图层
  3. Linux学习134 Unit 8
  4. 《C和C++代码精粹》——1.7 类型安全I/O
  5. [转载]SYSCALL_DEFINE宏定义
  6. Linux 关闭服务后 鼠标 键盘用不了
  7. [javascript|基本概念|Number]学习笔记
  8. reboot重启失败的解决方法
  9. 学成在线--13.RabbitMQ工作模式
  10. ride上点击用例不能显示edit信息_接口测试平台代码实现61: 多接口用例1