首页 > 其他分享 >使用 ServiceStack 构建跨平台 Web 服务

使用 ServiceStack 构建跨平台 Web 服务

时间:2022-12-12 11:00:18浏览次数:75  
标签:Web set get ServiceStack 跨平台 WCF public

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》。

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

使用 ServiceStack 构建跨平台 Web 服务_Web



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

使用 ServiceStack 构建跨平台 Web 服务_WCF_02



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

使用 ServiceStack 构建跨平台 Web 服务_Web_03




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

使用 ServiceStack 构建跨平台 Web 服务_WCF_04


标签:Web,set,get,ServiceStack,跨平台,WCF,public
From: https://blog.51cto.com/shanyou/5929246

相关文章

  • 解决aspnetcore-browser-refresh.js:234 WebSocket connection to 'wss://localhost:6
    前言前段时间升级了VisualStudio到v17.1.1最新版本,然后今天来运行之前的一个.net5项目一直提示:aspnetcore-browser-refresh.js:234WebSocketconnectionto'wss://......
  • JavaWeb之利用Filter实现权限拦截小实战【过滤器】
    一.Filter实现权限拦截1.1重定向拦截1.新建类servletLogin,继承类Httpservlet,重写方法doGet和doPost。2.在web文件夹下新建文件jsp->login.jsp,作为权限测试登录页面。配......
  • JavaWeb对于Listener的运用详解【利用Session统计在线人数】
    一.监听器Listener1.1Listener的作用Listener是一个功能组件,在创建、销毁或添加、修改或删除应用程序、会话和请求对象的属性时自动执行代码。监听器是servlet的监听器,......
  • paozhu c++ web framework 框架原理
    paozhuc++webframework框架原理paozhuc++webframework使用asio网络库,如果用动态库方式还要boost库。paozhu框架使用两个线程池,一个是框架使用的解析协议,连接......
  • JavaWeb
    JavaWeb1、基本概念1.1、前言web开发:web,网页的意思,www.baidu.com静态webhtml,css提供给所有人看的数据始终不会发生变化!动态web淘宝,几乎所有的网站都是动态......
  • [BUUCTF][WEB][极客大挑战 2019]PHP 1
    打开靶机URL看到字面提示因为每次猫猫都在我键盘上乱跳,所以我有一个良好的备份网站的习惯不愧是我!!!说明该网站有备份,说不定放在了Http服务器的某个目录下那么这里我们......
  • [BUUCTF][WEB][极客大挑战 2019]BabySQL 1
    靶机打开url界面上显示,它做了更严格的过滤。看来后台是加了什么过滤逻辑老规矩先尝试时候有sql注入的可能,密码框输入123'爆出sql错误信息,说明有注入点构造万能密码注......
  • [BUUCtF][WEB][ACTF2020 新生赛]Upload 1
    打开靶机url,右键查看网页源代码其中有一段代码<divclass="light"><spanclass="glow"> <formenctype="multipart/form-data"method="post"onsubmit="returncheck......
  • [BUUCTF][WEB][极客大挑战 2019]Upload 1
    打开靶机url,看到一个页面可以上传文件上传一个图片试一下,发现上传的路径是http://a7661b03-4852-41de-9ea4-d48c47cb50f0.node4.buuoj.cn:81/upload_file.php试一下获......
  • Web应用开发必知的HTML 5编码实践方法
    本人作品,转载请注明出处HTML5现在的发展相当迅速,越来越多的浏览器开始支持HTML5的新特性,也涌现出越来越多的基于HTML5的App应用,毫无疑问,作为web开发者,必须了解和懂得HTML......