【ASP.NET Web API教程】5.4 ASP.NET Web API批处理器

简介: 原文:【ASP.NET Web API教程】5.4 ASP.NET Web API批处理器注:本文是【ASP.NET Web API系列教程】的一部分,如果您是第一次看本系列教程,请先看前面的内容。 Batching Handler for ASP.
原文: 【ASP.NET Web API教程】5.4 ASP.NET Web API批处理器

注:本文是【ASP.NET Web API系列教程】的一部分,如果您是第一次看本系列教程,请先看前面的内容。

Batching Handler for ASP.NET Web API
5.4 ASP.NET Web API批处理器

本文引自:http://bradwilson.typepad.com/blog/2012/06/batching-handler-for-web-api.html

Brad Wilson | June 20, 2012
作者:Brad Wilson | 日期:2012-6-20

While there is no batching standard built into the HTTP protocol, there is a standard for MIME encoding HTTP request and response messages ("application/http" with "msgtype=request" and "msgtype=response", respectively). ASP.NET Web API has built-in support for both MIME multipart as well as encoded request and response messages, so we have all the building blocks we need to make a simple batch request handler.
当批处理标准尚未进入HTTP协议时,就已经有了对HTTP请求和响应消息进行编码的MIME标准(分别采用“msgtype=request”和“msgtype=response”的“application/http”)。ASP.NET Web API对MIME的multipart(多部分内容类型)、以及经过编码请求和响应消息都有内建的支持,因此,我们拥有了制作简单的请求批处理器的全部构建块。

All we need to make this work is an endpoint which can accept a multipart batch (an invention of our own), which then parses the requests, runs them sequentially, and returns the responses back in a multipart batch response.
我们所要做的全部工作只是一个端点(endpoint),它可以接收一个multipart batch(多部批,一个我们自己发明的内容类型),然后用它对请求进行解析,按顺序执行请求,并以一个multipart batch响应的形式返回一个响应。

Starting with a Web API project (built against the latest nightly build), I updated the Web API config to look like this:
从一个Web API项目(根据最新版建立的项目)开始,我修改了Web API的config,它看上去像这样:

var batchHandler = new BatchHandler(config);
config.Routes.MapHttpRoute("batch", "api/batch", null, null, batchHandler);
config.Routes.MapHttpRoute("default", "api/{controller}/{id}", new { id = RouteParameter.Optional });

I've inserted the handler for "api/batch" as our endpoint for batching requests, using the new "route-specific endpoint handler" feature in Web API. Note that since its URL is "api/batch", I made sure to add it before the default API route.
我已经为“api/batch”插入了处理器,以此作为对请求进行批处理的端点,这种做法利用了Web API中的“路由专用的端点处理器”特性。注,由于它的URL是“api/batch”,必须把它添加在默认的API路由之前

Using async & await in .NET 4.5 makes the implementation of BatchHandler fairly straight-forward. All we need is an in-memory HttpServer which uses our existing configuration, so that the batched requests hit the exact same endpoints as requests from the Internet:
利用.NET 4.5中的async和await可以很直接地构造BatchHandler实现。我们所需要的只是一个放在内存中的HttpServer,它使用当前配置,以便当请求来自Internet时,需要分批的请求会找到完全相同的端点:

public class BatchHandler : HttpMessageHandler
{
    HttpMessageInvoker _server; 
public BatchHandler(HttpConfiguration config) { _server = new HttpMessageInvoker(new HttpServer(config)); }
protected override async Task<HttpResponseMessage> SendAsync( HttpRequestMessage request, CancellationToken cancellationToken) { // Return 400 for the wrong MIME type // 对于错误的MIME类型,返回400 if ("multipart/batch" != request.Content.Headers.ContentType.MediaType) { return request.CreateResponse(HttpStatusCode.BadRequest); }
// Start a multipart response // 启动一个multipart响应 var outerContent = new MultipartContent("batch"); var outerResp = request.CreateResponse(); outerResp.Content = outerContent;
// Read the multipart request // 读取multipart请求 var multipart = await request.Content.ReadAsMultipartAsync(); foreach (var httpContent in multipart.Contents) { HttpResponseMessage innerResp = null; try { // Decode the request object // 解码请求对象 var innerReq = await httpContent.ReadAsHttpRequestMessageAsync();
// Send the request through the pipeline // 通过管线发送请求 innerResp = await _server.SendAsync( innerReq, cancellationToken ); } catch (Exception) { // If exceptions are thrown, send back generic 400 // 如果抛出异常,回发泛型的400 innerResp = new HttpResponseMessage( HttpStatusCode.BadRequest ); }
// Wrap the response in a message content and put it // into the multipart response // 在消息内容中封装响应,并把它放入multipart响应 outerContent.Add(new HttpMessageContent(innerResp)); }
return outerResp; } }

Now we have an endpoint that we can send multipart/batch requests to, which are assumed to be HTTP request objects (anything which isn't is going to yield a 400).
现在,我们拥有了一个端点,我们能够把multipart/batch请求发送给它,假设这些请求都是HTTP请求对象(任何不是HTTP请求的对象都会产生一个400状态码)。

On the client side, we make a multipart request and push requests into the multipart batch, one at a time:
在客户端,我们形成了一个multipart请求,并把请求推入multipart batch,每次压入一个请求:

var client = new HttpClient();
var batchRequest = new HttpRequestMessage(
    HttpMethod.Post,
    "http://localhost/api/batch"
); 
var batchContent = new MultipartContent("batch"); batchRequest.Content = batchContent;
batchContent.Add( new HttpMessageContent( new HttpRequestMessage( HttpMethod.Get, "http://localhost/api/values" ) ) );
batchContent.Add( new HttpMessageContent( new HttpRequestMessage( HttpMethod.Get, "http://localhost/foo/bar" ) ) );
batchContent.Add( new HttpMessageContent( new HttpRequestMessage( HttpMethod.Get, "http://localhost/api/values/1" ) ) );

In a console application, we can log both the request and response with code like this:
在一个控制台应用程序中,我们可以用以下代码对请求和响应时行日志:

using (Stream stdout = Console.OpenStandardOutput())
{
    Console.WriteLine("<<< REQUEST >>>");
    Console.WriteLine();
    Console.WriteLine(batchRequest);
    Console.WriteLine();
batchContent.CopyToAsync(stdout).Wait();
Console.WriteLine(); var batchResponse = client.SendAsync(batchRequest).Result; Console.WriteLine("<<< RESPONSE >>>"); Console.WriteLine(); Console.WriteLine(batchResponse); Console.WriteLine(); batchResponse.Content.CopyToAsync(stdout).Wait(); Console.WriteLine(); Console.WriteLine(); }

When I run this console application, I see output similar to this:
当运行这个控制台应用程序时,会看到输出类似于这样:

<<< REQUEST >>> 
Method: POST, RequestUri: 'http://localhost/api/batch', Version: 1.1, Content: System.Net.Http.MultipartContent, Headers: { Content-Type: multipart/batch; boundary="3bc5bd67-3517-4cd0-bcdd-9d23f3850402" }
--3bc5bd67-3517-4cd0-bcdd-9d23f3850402 Content-Type: application/http; msgtype=request
GET /api/values HTTP/1.1 Host: localhost
--3bc5bd67-3517-4cd0-bcdd-9d23f3850402 Content-Type: application/http; msgtype=request GET /foo/bar HTTP/1.1 Host: localhost
--3bc5bd67-3517-4cd0-bcdd-9d23f3850402 Content-Type: application/http; msgtype=request
GET /api/values/1 HTTP/1.1 Host: localhost
--3bc5bd67-3517-4cd0-bcdd-9d23f3850402-- <<< RESPONSE >>>
StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StreamContent, Headers: { Pragma: no-cache Cache-Control: no-cache Date: Thu, 21 Jun 2012 00:21:40 GMT Server: Microsoft-IIS/8.0 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Content-Length: 658 Content-Type: multipart/batch Expires: -1 }
--3d1ba137-ea6a-40d9-8e34-1b8812394baa Content-Type: application/http; msgtype=response
HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8
["Hello","world!"]
--3d1ba137-ea6a-40d9-8e34-1b8812394baa Content-Type: application/http; msgtype=response
HTTP/1.1 404 Not Found Content-Type: application/json; charset=utf-8
{"Message":"No HTTP resource was found that matches the request URI 'http://localhost/foo/bar'."}
--3d1ba137-ea6a-40d9-8e34-1b8812394baa Content-Type: application/http; msgtype=response
HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8
"world!" --3d1ba137-ea6a-40d9-8e34-1b8812394baa--

As you can see, our batch was successfully run, and the results show what we'd expected (the two real API calls returned back 200 with their data, and the bogus request we threw in the middle returns back a 404).
正如我们所看到的,批处理成功地运行了,并且显示了我们所期望的结果(两个真正的API调用返回了带有其数据的200状态码,而在中间压入的伪造请求返回了404状态码)。


看完此文如果觉得有所收获,请给个推荐

目录
相关文章
|
1月前
|
开发框架 前端开发 JavaScript
ASP.NET Web Pages - 教程
ASP.NET Web Pages 是一种用于创建动态网页的开发模式,采用HTML、CSS、JavaScript 和服务器脚本。本教程聚焦于Web Pages,介绍如何使用Razor语法结合服务器端代码与前端技术,以及利用WebMatrix工具进行开发。适合初学者入门ASP.NET。
|
3月前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
189 3
|
9天前
|
运维 前端开发 C#
一套以用户体验出发的.NET8 Web开源框架
一套以用户体验出发的.NET8 Web开源框架
一套以用户体验出发的.NET8 Web开源框架
|
1月前
|
开发框架 .NET PHP
ASP.NET Web Pages - 添加 Razor 代码
ASP.NET Web Pages 使用 Razor 标记添加服务器端代码,支持 C# 和 Visual Basic。Razor 语法简洁易学,类似于 ASP 和 PHP。例如,在网页中加入 `@DateTime.Now` 可以实时显示当前时间。
|
4月前
|
开发框架 监控 前端开发
在 ASP.NET Core Web API 中使用操作筛选器统一处理通用操作
【9月更文挑战第27天】操作筛选器是ASP.NET Core MVC和Web API中的一种过滤器,可在操作方法执行前后运行代码,适用于日志记录、性能监控和验证等场景。通过实现`IActionFilter`接口的`OnActionExecuting`和`OnActionExecuted`方法,可以统一处理日志、验证及异常。创建并注册自定义筛选器类,能提升代码的可维护性和复用性。
|
10天前
|
监控 前端开发 API
一款基于 .NET MVC 框架开发、功能全面的MES系统
一款基于 .NET MVC 框架开发、功能全面的MES系统
|
4月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
51 7
|
4月前
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
87 0
|
5月前
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
69 0
|
5月前
|
开发框架 前端开发 安全
ASP.NET MVC 如何使用 Form Authentication?
ASP.NET MVC 如何使用 Form Authentication?