【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状态码)。


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

目录
相关文章
|
23天前
|
人工智能 搜索推荐 IDE
突破网页数据集获取难题:Web Unlocker API 助力 AI 训练与微调数据集全方位解决方案
本文介绍了Web Unlocker API、Web-Scraper和SERP API三大工具,助力解决AI训练与微调数据集获取难题。Web Unlocker API通过智能代理和CAPTCHA绕过技术,高效解锁高防护网站数据;Web-Scraper支持动态内容加载,精准抓取复杂网页信息;SERP API专注搜索引擎结果页数据抓取,适用于SEO分析与市场研究。这些工具大幅降低数据获取成本,提供合规保障,特别适合中小企业使用。粉丝专属体验入口提供2刀额度,助您轻松上手!
59 2
|
2月前
|
XML JSON API
Understanding RESTful API and Web Services: Key Differences and Use Cases
在现代软件开发中,RESTful API和Web服务均用于实现系统间通信,但各有特点。RESTful API遵循REST原则,主要使用HTTP/HTTPS协议,数据格式多为JSON或XML,适用于无状态通信;而Web服务包括SOAP和REST,常用于基于网络的API,采用标准化方法如WSDL或OpenAPI。理解两者区别有助于选择适合应用需求的解决方案,构建高效、可扩展的应用程序。
|
7月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
111 4
|
4月前
|
人工智能 前端开发 API
Gemini Coder:基于 Google Gemini API 的开源 Web 应用生成工具,支持实时编辑和预览
Gemini Coder 是一款基于 Google Gemini API 的 AI 应用生成工具,支持通过文本描述快速生成代码,并提供实时代码编辑和预览功能,简化开发流程。
239 38
Gemini Coder:基于 Google Gemini API 的开源 Web 应用生成工具,支持实时编辑和预览
|
2月前
|
机器学习/深度学习 开发框架 API
Python 高级编程与实战:深入理解 Web 开发与 API 设计
在前几篇文章中,我们探讨了 Python 的基础语法、面向对象编程、函数式编程、元编程、性能优化、调试技巧以及数据科学和机器学习。本文将深入探讨 Python 在 Web 开发和 API 设计中的应用,并通过实战项目帮助你掌握这些技术。
|
5月前
|
Kubernetes 安全 Devops
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
156 10
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
|
6月前
|
开发框架 .NET 程序员
驾驭Autofac,ASP.NET WebApi实现依赖注入详细步骤总结
Autofac 是一个轻量级的依赖注入框架,专门为 .NET 应用程序量身定做,它就像是你代码中的 "魔法师",用它来管理对象的生命周期,让你的代码更加模块化、易于测试和维护
167 4
驾驭Autofac,ASP.NET WebApi实现依赖注入详细步骤总结
|
6月前
|
前端开发 API 开发者
Python Web开发者必看!AJAX、Fetch API实战技巧,让前后端交互如丝般顺滑!
在Web开发中,前后端的高效交互是提升用户体验的关键。本文通过一个基于Flask框架的博客系统实战案例,详细介绍了如何使用AJAX和Fetch API实现不刷新页面查看评论的功能。从后端路由设置到前端请求处理,全面展示了这两种技术的应用技巧,帮助Python Web开发者提升项目质量和开发效率。
126 1
|
6月前
|
JSON API 数据格式
如何使用Python和Flask构建一个简单的RESTful API。Flask是一个轻量级的Web框架
本文介绍了如何使用Python和Flask构建一个简单的RESTful API。Flask是一个轻量级的Web框架,适合小型项目和微服务。文章从环境准备、创建基本Flask应用、定义资源和路由、请求和响应处理、错误处理等方面进行了详细说明,并提供了示例代码。通过这些步骤,读者可以快速上手构建自己的RESTful API。
410 2
|
7月前
|
监控 负载均衡 API
Web、RESTful API 在微服务中有哪些作用?
在微服务架构中,Web 和 RESTful API 扮演着至关重要的角色。它们帮助实现服务之间的通信、数据交换和系统的可扩展性。
118 2