ReactiveX 学习笔记(15)使用 Rx.NET + Json.NET 调用 REST API
JSON : Placeholder
JSON : Placeholder (https://jsonplaceholder.typicode.com/) 是一个用于测试的 REST API 网站。
以下使用 Task API/Rx.NET + Json.NET 调用该网站的 REST API,获取字符串以及 JSON 数据。
- GET /posts/1
- GET /posts
- POST /posts
- PUT /posts/1
- DELETE /posts/1
所有 GET API 都返回JSON数据,格式(JSON-Schema)如下:
{
"type":"object",
"properties": {
"userId": {"type" : "integer"},
"id": {"type" : "integer"},
"title": {"type" : "string"},
"body": {"type" : "string"}
}
}
Post 对象
public class Post
{
[JsonProperty("userId")]
public int UserId { get; set; }
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("body")]
public string Body { get; set; }
public override string ToString() =>
$"Post {{userId = {UserId}, id = {Id}, title = \"{Title}\", body = \"{Body.Replace("\n", "\\n")}\"}}";
}
Post 对象负责 .NET 对象和 JSON 数据的相互转换。
Post 类使用了 Json.NET 所提供的 attributes。
Task API
public class PostDataStoreByTask
{
protected HttpClient client = new HttpClient
{
BaseAddress = new Uri("https://jsonplaceholder.typicode.com/")
};
public async Task<string> GetPostAsString(int id) =>
!CrossConnectivity.Current.IsConnected ? null : await client.GetStringAsync($"posts/{id}");
public async Task<Post> GetPostAsJson(int id)
{
if (!CrossConnectivity.Current.IsConnected) return null;
var json = await client.GetStringAsync($"posts/{id}");
var item = await Task.Run(() => JsonConvert.DeserializeObject<Post>(json));
return item;
}
public async Task<IEnumerable<Post>> GetPosts(int n)
{
IEnumerable<Post> items = new List<Post>();
if (CrossConnectivity.Current.IsConnected)
{
var json = await client.GetStringAsync("posts");
items = await Task.Run(() => JsonConvert.DeserializeObject<IEnumerable<Post>>(json));
}
return items.Take(n);
}
private StringContent GetStringContent(Post item) =>
new StringContent(JsonConvert.SerializeObject(item), Encoding.UTF8, "application/json");
public async Task<Post> CreatePost(Post item)
{
if (item == null || !CrossConnectivity.Current.IsConnected) return null;
var response = await client.PostAsync("posts", GetStringContent(item));
if (!response.IsSuccessStatusCode) return null;
var json = await response.Content.ReadAsStringAsync();
var item2 = await Task.Run(() => JsonConvert.DeserializeObject<Post>(json));
return item2;
}
public async Task<Post> UpdatePost(Post item)
{
if (item == null || !CrossConnectivity.Current.IsConnected) return null;
var response = await client.PutAsync($"posts/{item.Id}", GetStringContent(item));
if (!response.IsSuccessStatusCode) return null;
var json = await response.Content.ReadAsStringAsync();
var item2 = await Task.Run(() => JsonConvert.DeserializeObject<Post>(json));
return item2;
}
public async Task<string> DeletePost(int id)
{
if (!CrossConnectivity.Current.IsConnected) return null;
var response = await client.DeleteAsync($"posts/{id}");
if (!response.IsSuccessStatusCode) return null;
var json = await response.Content.ReadAsStringAsync();
return json;
}
}
- getPostAsString 方法取出第1个Post,返回字符串
- getPostAsJson 方法取出第1个Post,返回Post对象
- getPosts 方法取出前n个Post,返回n个Post对象
- createPost 方法创建1个Post,返回所创建的Post对象
- updatePost 方法更新第1个Post,返回所更新的Post对象
- deletePost 方法删除第1个Post,返回字符串
Rx.NET
public class PostDataStoreByRx
{
protected HttpClient client = new HttpClient
{
BaseAddress = new Uri("https://jsonplaceholder.typicode.com/")
};
public IObservable<string> GetPostAsString(int id) =>
!CrossConnectivity.Current.IsConnected ? Observable.Empty<string>() :
client.GetStringAsync($"posts/{id}").ToObservable();
public IObservable<Post> GetPostAsJson(int id) =>
!CrossConnectivity.Current.IsConnected? Observable.Empty<Post>() :
client.GetStringAsync($"posts/{id}").ToObservable()
.Select(json => JsonConvert.DeserializeObject<Post>(json));
public IObservable<Post> GetPosts(int n) =>
!CrossConnectivity.Current.IsConnected ? Observable.Empty<Post>() :
client.GetStringAsync("posts").ToObservable()
.SelectMany(json => JsonConvert.DeserializeObject<IEnumerable<Post>>(json))
.Take(n);
private StringContent GetStringContent(Post item) =>
new StringContent(JsonConvert.SerializeObject(item), Encoding.UTF8, "application/json");
public IObservable<Post> CreatePost(Post item) =>
item == null || !CrossConnectivity.Current.IsConnected ? Observable.Empty<Post>() :
client.PostAsync("posts", GetStringContent(item)).ToObservable()
.SelectMany(response => !response.IsSuccessStatusCode ? Observable.Empty<Post>() :
response.Content.ReadAsStringAsync().ToObservable()
.Select(json => JsonConvert.DeserializeObject<Post>(json)));
public IObservable<Post> UpdatePost(Post item) =>
item == null || !CrossConnectivity.Current.IsConnected? Observable.Empty<Post>() :
client.PutAsync($"posts/{item.Id}", GetStringContent(item)).ToObservable()
.SelectMany(response => !response.IsSuccessStatusCode? Observable.Empty<Post>() :
response.Content.ReadAsStringAsync().ToObservable()
.Select(json => JsonConvert.DeserializeObject<Post>(json)));
public IObservable<string> DeletePost(int id) =>
!CrossConnectivity.Current.IsConnected ? Observable.Empty<string>() :
client.DeleteAsync($"posts/{id}").ToObservable()
.SelectMany(response => !response.IsSuccessStatusCode ? Observable.Empty<string>() :
response.Content.ReadAsStringAsync().ToObservable());
}
相比较 Task API,Rx.NET 代码简练但是比较难理解。
Main 方法
public static void Main(string[] args)
{
{
var dataStore = new PostDataStoreByTask();
Console.WriteLine(dataStore.GetPostAsString(1).Result);
Console.WriteLine(dataStore.GetPostAsJson(1).Result);
dataStore.GetPosts(2).Result.ToList().ForEach(Console.WriteLine);
Console.WriteLine(dataStore.CreatePost(new Post
{
UserId = 101,
Id = 0,
Title = "test title",
Body = "test body"
}).Result);
Console.WriteLine(dataStore.UpdatePost(new Post
{
UserId = 101,
Id = 1,
Title = "test title",
Body = "test body"
}).Result);
Console.WriteLine(dataStore.DeletePost(1).Result);
}
{
var dataStore = new PostDataStoreByRx();
dataStore.GetPostAsString(1).Subscribe(Console.WriteLine);
dataStore.GetPostAsJson(1).Subscribe(Console.WriteLine);
dataStore.GetPosts(2).Do(Console.WriteLine).Subscribe();
dataStore.CreatePost(new Post
{
UserId = 101,
Id = 0,
Title = "test title",
Body = "test body"
}).Subscribe(Console.WriteLine);
dataStore.UpdatePost(new Post
{
UserId = 101,
Id = 1,
Title = "test title",
Body = "test body"
}).Subscribe(Console.WriteLine);
dataStore.DeletePost(1).Subscribe(Console.WriteLine);
Console.ReadKey();
}
}
输出结果
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
Post {userId = 1, id = 1, title = "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", body = "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"}
Post {userId = 1, id = 1, title = "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", body = "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"}
Post {userId = 1, id = 2, title = "qui est esse", body = "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"}
Post {userId = 101, id = 101, title = "test title", body = "test body"}
Post {userId = 101, id = 1, title = "test title", body = "test body"}
{}
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
Post {userId = 1, id = 1, title = "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", body = "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"}
Post {userId = 1, id = 1, title = "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", body = "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"}
Post {userId = 1, id = 2, title = "qui est esse", body = "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"}
Post {userId = 101, id = 1, title = "test title", body = "test body"}
Post {userId = 101, id = 101, title = "test title", body = "test body"}
{}
ReactiveX 学习笔记(15)使用 Rx.NET + Json.NET 调用 REST API的更多相关文章
- ReactiveX 学习笔记(14)使用 RxJava2 + Retrofit2 调用 REST API
JSON : Placeholder JSON : Placeholder (https://jsonplaceholder.typicode.com/) 是一个用于测试的 REST API 网站. ...
- ReactiveX 学习笔记(17)使用 RxSwift + Alamofire 调用 REST API
JSON : Placeholder JSON : Placeholder (https://jsonplaceholder.typicode.com/) 是一个用于测试的 REST API 网站. ...
- ReactiveX 学习笔记(18)使用 RxJS + Angular 调用 REST API
JSON : Placeholder JSON : Placeholder (https://jsonplaceholder.typicode.com/) 是一个用于测试的 REST API 网站. ...
- ReactiveX 学习笔记(0)学习资源
ReactiveX 学习笔记 ReactiveX 学习笔记(1) ReactiveX 学习笔记(2)创建数据流 ReactiveX 学习笔记(3)转换数据流 ReactiveX 学习笔记(4)过滤数据 ...
- Ext.Net学习笔记15:Ext.Net GridPanel 汇总(Summary)用法
Ext.Net学习笔记15:Ext.Net GridPanel 汇总(Summary)用法 Summary的用法和Group一样简单,分为两步: 启用Summary功能 在Feature标签内,添加如 ...
- SQL反模式学习笔记15 分组
目标:查询得到每组的max(或者min等其他聚合函数)值,并且得到这个行的其他字段 反模式:引用非分组列 单值规则:跟在Select之后的选择列表中的每一列,对于每个分组来说都必须返回且仅返回一直值. ...
- ReactiveX 学习笔记(24)使用 RxCpp + C++ REST SDK 调用 REST API
JSON : Placeholder JSON : Placeholder (https://jsonplaceholder.typicode.com/) 是一个用于测试的 REST API 网站. ...
- 【Spring学习笔记-MVC-4】SpringMVC返回Json数据-方式2
<Spring学习笔记-MVC>系列文章,讲解返回json数据的文章共有3篇,分别为: [Spring学习笔记-MVC-3]SpringMVC返回Json数据-方式1:http://www ...
- 【Spring学习笔记-MVC-3】SpringMVC返回Json数据-方式1
<Spring学习笔记-MVC>系列文章,讲解返回json数据的文章共有3篇,分别为: [Spring学习笔记-MVC-3]SpringMVC返回Json数据-方式1:http://www ...
随机推荐
- SQL-sqlHelper001
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.D ...
- Mybatis 系列8-结合源码解析select、resultMap的用法
[Mybatis 系列10-结合源码解析mybatis 执行流程] [Mybatis 系列9-强大的动态sql 语句] [Mybatis 系列8-结合源码解析select.resultMap的用法] ...
- Mysql 之闪回技术 binlog2sql
1.下载 https://github.com/danfengcao/binlog2sql http://rpmfind.net Search: python-pip pip 是一个Python包管理 ...
- 提高modem的core dump级别
zhangze@zhangze-OptiPlex-7040:~/e2_8939-E2-2104026-CTA/device/qcom/common$ git showcommit be2b5cb33a ...
- 【Unix网络编程】chapter3套接字编程简介
chapter3套接字编程简介3.1 概述 地址转换函数在地址的文本表达和他们存放在套接字地址结构中的二进制值之间进行转换.多数现存的IPv4代码使用inet_addr和inet_ntoa这两个函数, ...
- SSH2 No Session found for current thread原因
Hibernate4 与 spring3 集成之后, 如果在取得session 的地方使用了getCurrentSession, 可能会报一个错:“No Session found for curre ...
- gulp 使用案例
1.gulp 配置: // 引入 gulp var gulp = require('gulp'); var watch = require('gulp-watch'), //导入所有gulp需要的模块 ...
- 07 grep命令与正则表达式
grep命令 首先我们知道grep命令是用来做文件内容过滤的!如果你要在文件中查找一些对应的内容,我们如何来过滤找到其中我们需要符合条件的内容呢?grep命令结合正则表达式就可以实现: grep.eg ...
- CF235C Cyclical Quest(SAM)
/* 统计串的出现次数显然可以在自动机上匹配出来即可 但是每次都挨个匹配的话会时间爆炸 那么考虑我们把串复制一份, 然后一起在后缀自动机上跑, 当我们匹配长度大于该串长度的时候强行失配即可 可能会有旋 ...
- Android2.2+opencv3.1配置实现
来实习什么都要自己干,不仅仅要写算法,还要再Android上面跑起来.... 弄了三天才搞好,就因为一点点失误!!! 第一步:安装Android Studio2.2 安装opencv3.1 下载 ...