《ASP.NET Core跨平台開發從入門到實戰》樣章節 Web API自定義格式化protobuf。
樣章
Protocol Buffers 是一種輕便高效的結構化數據存儲格式,可以用於結構化數據串行化,或者說序列化。
它很適合做數據存儲或 RPC 數據交換格式。可用於通訊協議、數據存儲等領域的語言無關、平台無關、可擴展的序列化結構數據格式。
以下將實現一個格式化程序返回protobuf 格式。
首先新建一個ASP.NET Core Web Application應用程序名為 ProtobufFormat,選擇Web API模板。
添加protobuf-net 引用。使用NuGet 命令行或者NuGet包管理器安裝。
NuGet 命令行:Install-Package protobuf-net。
添加一個ProtobufFormatter 類
public class ProtobufFormatter : OutputFormatter
{
public string ContentType { get; private set; }
public ProtobufFormatter()
{
ContentType = "application/proto";
SupportedMediaTypes.Add(Microsoft.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/proto"));
}
public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var response = context.HttpContext.Response;
Serializer.Serialize(response.Body, context.Object);
return Task.FromResult(0);
}
}
繼承OutputFormatter ,然后實現WriteResponseBodyAsync 方法,初始化時賦值ContentType 以及添加支持MediaType。
在WriteResponseBodyAsync 方法中獲取Response,調用protobuf-net的Serialize方法將Object序列化至輸出內容。protobuf 在序列化時必須指定順序,不然會序列化失敗。
下面添加一個User類,來實現protobuf 實體。
[ProtoContract]
public class User
{
[ProtoMember(1)]
public int Id { get; set; }
[ProtoMember(2)]
public string Name { get; set; }
[ProtoMember(3)]
public int Age { get; set; }
}
類上需要加上ProtoContract 特性,然后字段需加上ProtoMember特性,並指定順序。這樣的一個類才能被序列化為protobuf 格式。
然后更改ValuesController控制器里的操作,使之輸出protobuf。
[Route("api/[controller]")]
public class ValuesController : Controller
{
private IEnumerable<User> Users;
public ValuesController()
{
Users= new User[] {
new User() { Id=1,Name="book",Age=1},
new User() { Id=2,Name="asp.net core",Age=10},
};
}
// GET api/values
[HttpGet]
[Produces("application/proto")]
public IEnumerable<User> Get()
{
return Users;
}
// GET api/values/5
[HttpGet("{id}")]
[Produces("application/proto")]
public User Get(int id)
{
return Users.FirstOrDefault(r => r.Id == id);
}
}
在每個操作上加上Produces特性,里面值為application/proto,也就是剛剛設置的 ContentType。然后直接返回對應的對象結果即可。
如果現在運行應用程序,訪問api/values 會發現沒有返回結果,因為還需要在AddMvc中添加對應的格式化。
打開Startup 類中的ConfigureServices方法,將services.AddMvc() 更改為如下:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(option=> {
option.OutputFormatters.Add(new ProtobufFormatter());
});
}
添加輸出格式化程序ProtobufFormatter。
現在再運行應用程序,訪問api/values 會返回一個二進制文件,里面也就包含序列化之后的數據。
可以新建測試程序來模擬調用Web API來檢查序列化是否正確。
新建一個.NET Core控制台應用程序,在Program.cs 中將Main方法更改為如下代碼:
public static void Main(string[] args)
{
HttpClient client = new HttpClient();
var stream=client.GetStreamAsync("http://localhost:5000/api/values").Result;
var users=Serializer.Deserialize<List<User>>(stream);
foreach (var item in users)
{
Console.WriteLine($"ID:{item.Id}-Name:{item.Name}-Age:{item.Age}");
}
Console.ReadKey();
}
並將User類復制到該項目。
代碼為訪問http://localhost:5000/api/values獲得結果,然后將其反序列化為實體對象。遍歷對象,並展示出來。
首先運行Web API 應用程序,然后運行測試控制台應用程序。控制台應用程序會顯示如下:
ID:1-Name:book-Age:1
ID:2-Name:asp.net core-Age:10
表示成功訪問並得到結果反序列化實體對象成功。如此,自定義格式化程序ProtobufFormatter,也就成功實現。同理還可以實現其他所需要的格式化程序。
感悟
《ASP.NET Core跨平台開發從入門到實戰》 成功出版,經歷時間還是蠻長的。本書是基於.NET Core 1.0所著。
.NET Core發展快速,現在新的VS2017也發布了,導致書中部分內容可能不大適用。但是理論部分及代碼還是未過時。
本書的定位為 入門書籍 ,想系統了解ASP.NET Core 及學習ASP.NET Core 有所幫助。
可以點擊文章底部或左邊的購買鏈接查看詳細的目錄和購買。
活動
贈書活動,本次贈送6本《ASP.NET Core跨平台開發從入門到實戰》。
活動規則:
在下方評論或轉發至微博並在下方評論留言。
中獎樓層規則:
截止 4月21日 12:00 樓層數-(樓層數/6-1) 遞減下去。 如:最終50層 50-(50/6-1)=43 43-7=36 36-7=29 29-7=22 22-7=15 15-7=8
每人最多評論三次,超過屬於刷屏,順延至下一位。
4月21日 13:00 公布 公布中獎以后,大家將地址和聯系方式私信於我。
4月21日 12:30 更新
152-(152/6-1)=128 @sigmud
128-24=104 @IT胡小帥
104-24=80 順延至下一位 81 @張君度
80-24=56 @麥梗上的代碼
56-24=32 @wlf921
32-24=8 @。流年。
恭喜以上博友獲得 《ASP.NET Core跨平台開發從入門到實戰》一本。
感謝大家的熱情支持,以上朋友請將地址和聯系方式盡快私信於我,我會在這周末發出。
如果你覺得本文對你有幫助,請點擊“推薦”,謝謝。

