出处: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 服务结构如下:

  • 服务层是您定义您的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是一系列事物的综合体:

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部分

使用 ServiceStack 构建跨平台 Web 服务(转)的更多相关文章

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

    本文主要来自MSDN杂志<Building Cross-Platform Web Services with ServiceStack>,Windows Communication Fou ...

  2. 使用RpcLite构建SOA/Web服务

    使用RpcLite构建SOA/Web服务 SOA框架系列 1. 使用RpcLite构建SOA/Web服务 提到Web服务最先想到的就是WebService此外常用的还有WCF.ServiceStack ...

  3. 基于IIS构建Pyathon Web服务

    本文简单叙述了在Windows下,如何利用IIS构建Python Web服务. 其主要步骤如下: 1.在IIS下构建一个站点,如图: 2.配置Python文件的处理程序,如图: 3.最后,在对应站点根 ...

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

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

  5. WCF:为 SharePoint 2010 Business Connectivity Services 构建 WCF Web 服务(第 1 部分,共 4 部分)

    转:http://msdn.microsoft.com/zh-cn/library/gg318615.aspx 摘要:通过此系列文章(共四部分)了解如何在 Microsoft SharePoint F ...

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

    原文地址:http://www.ibm.com/developerworks/cn/web/wa-restful/ 简介: Spring,构建 Java™ 平台和 Enterprise Edition ...

  7. 如何快速搭建一个基于ServiceStack框架的web服务

    ServiceStack是一个高性能的.NET Web Service 平台,能够简化开发高性能的REST (支持JSON,XML,JSV,HTML,MsgPack,ProtoBuf,CSV等消息格式 ...

  8. SpringBoot实战(十)之使用Spring Boot Actuator构建RESTful Web服务

    一.导入依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http ...

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

    基于jersey和Apache Tomcat构建Restful Web服务(二) 上篇博客介绍了REST以及Jersey并使用其搭建了一个简单的“Hello World”,那么本次呢,再来点有趣的东西 ...

随机推荐

  1. pagination实现分页功能

    pagination.js: /** * pagination分页插件 */ ;(function($,window,document,undefined){ //配置参数 var defaults ...

  2. Java-Runoob-高级课程:Java 集合框架

    ylbtech-Java-Runoob-高级课程:Java 集合框架 1.返回顶部 1. Java 集合框架 早在 Java 2 中之前,Java 就提供了特设类.比如:Dictionary, Vec ...

  3. Required String parameter 'id' is not present

    问题详情:       简单的说,我就是通过ajax发起了一个post请求到后台,但是后台没有收到请求发过去的参数,并且还报了这样的错误.       错误描述告诉我们,请求参数里面并没有存在id.我 ...

  4. Linux中常用的查找文件的命令

    我们经常在linux要查找某个文件,但不知道放在哪里了,可以使用下面的一些命令来搜索.这些是从网上找到的资料(参考资料1),因为有时很长时间不会用到,当要用的时候经常弄混了,所以放到这里方便使用. w ...

  5. python复习之路-Day01

    数据类型初识 1.数字 2 是一个整数的例子.长整数 不过是大一些的整数.3.23和52.3E-4是浮点数的例子.E标记表示10的幂.在这里,52.3E-4表示52.3 * 10-4.(-5+4j)和 ...

  6. ftp之心脏病

    FTP基础 FTP只通过TCP连接,没有用于FTP的UDP组件.FTP不同于其他服务的是它使用了两个端口, 一个数据端口和一个命令端口(或称为控制端口).通常21端口是命令端口,20端口是数据端口.当 ...

  7. 记一次 Docker swarm - overlay network access error

    背景 之前使用Docker swam 在不同的服务器 (docker host) 上面创建了service,他们之间的container通过overlay的网络通信. 昨天由于公司网络维护,其中一台服 ...

  8. node制作代理服务器

    下面代码实现的功能是这样的: 首先创建一个HTTP服务器,当服务器接收到客户端的请求后,向"www.taobao.com"网站请求数据,当从该网站接受到的响应数据后,将响应数据发送 ...

  9. json data 解析demo

    json data: demo: JsonObject jsonObject= JsonHandle.getAsJsonObject(city_dataInfo).get("data&quo ...

  10. Vcf文件格式

    Vcf文件格式是GATK钟爱的表示遗传变异的一种文件格式. 就拿GATK给出的vcf例子说明吧,下面这个文件只表示了一个完整vcf文件的前几个SNP. 看上去确实有点复杂,那就把它分为两部分看吧,第一 ...