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 ...
随机推荐
- [UE4]Return Node节点好用法
蓝图自定义函数中,碰到“Return Node”也会推出当前的函数,跟高级语言的“return”是一样的用法
- KPPW2.5 漏洞利用--SQL注入
KPPW2.5 漏洞利用--SQL注入 SQL注入--布尔型盲注 环境搭建 1,集成环境简单方便,如wamp,phpstudy.... 2,KPPW v2.2源码一份(文末有分享)放到WWW目录下面 ...
- Mysql 之分库分表方案
Mysql分库分表方案 为什么要分表 当一张表的数据达到几千万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了.分表的目的就在于此,减小数据库的负担,缩短查询时间. mysq ...
- Linux内核学习笔记二——进程
Linux内核学习笔记二——进程 一 进程与线程 进程就是处于执行期的程序,包含了独立地址空间,多个执行线程等资源. 线程是进程中活动的对象,每个线程都拥有独立的程序计数器.进程栈和一组进程寄存器 ...
- C#存储过程中传入传出参数
作者:卞功鑫 ,转载请保留http://www.cnblogs.com/BinBinGo/p/6399847.html //1 连接字符串 string connectionString = &qu ...
- ZooKeeper系列(6):ZooKeeper机制架构
一.ZooKeeper权限管理机制 1.1 权限管理ACL(Access Control List) ZooKeeper 的权限管理亦即ACL 控制功能,使用ACL来对Znode进行访问控制.ACL的 ...
- PHP:导出数据到word(包含图片)
1.方法 public function word() { $xlsModel = M('api_aliucheng'); $Data = $xlsModel->Field('id,u_name ...
- @Autowired与@Resource 详细诠释和区别(附带例子)
@Autowired 与@Resource:1.@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上. 2.@Autowired默认按类型装配( ...
- url后面带斜杠与不带斜杠的区别
比如: https://www.baidu.com/test/ https://www.baidu.com/test 当Web服务器接收到对某个末尾不含斜杠的url请求时,例如https://www. ...
- eclipse聚合工程如何提交SVN,如何从SVN下载
提交: 比如聚合工程为taotao-manager,包含了taotao1,taotao2,taotao3等项目,在提交SVN只需 提交taotao-manager就可以了 1.右键taotao-man ...