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]删除UI:Remove from Parent
同时要将保存UI的变量清空,以释放占用的系统内存
- OpenSips使用说明
OpenSips使用说明 安装MYSQL 安装及初始化 下载地址:http://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.17-linux-gli ...
- css定位(后盾网)
1.绝对定位:脱离了文档流,如果设置了left和top,位置相对浏览器来定位,如果不设值top和left,还是按照原来的文档流的位置站位,位置移走后,原来的空间位被其他元素占据 ***应用:一般来说我 ...
- ArcEngine 创建空间参考设置默认域
ISpatialReferenceFactory3 spatialReferenceFactory = new SpatialReferenceEnvironmentClass(); outSR = ...
- svn 红叉叉图标解决方法
这个图标表示当前文件夹下的某些文件或文件夹已经被计划从版本控制中 删除,或是该文件夹下某个受控的文件丢失了. 解决方法: 鼠标右键红叉小图标->->revert 更多SVN图标说明,请参考 ...
- spark streaming检查点使用
import org.apache.spark._ import org.apache.spark.streaming._ /** * Created by code-pc on 16/3/14. * ...
- Java动手及实验整理
1 枚举类型 在Java中,枚举类型本质上其实就是一个类,枚举中的常量都是该枚举类型的实例.枚举类型是引用类型!枚举不属于原始数据类型,它的每个具体值都引用一个特定的对象.相同的值则引用同一个对象 ...
- tkinter简单使用
第一个运行程序 # -*- coding: utf-8 -*- import tkinter as tk //引入 root = tk.Tk() // 实例化root T大写k小写 root.titl ...
- 错误为Lc.exe已退出,代码为-1
近来在做项目的时候,突然遇到 了 LC.exe 已退出,代码为-1 的提示,怎么也编译不了,在查了相关的资料后,终于明白了原因,其解决方案如下 : 1. 以管理员的身份来运行vs, 并把项目中“pro ...
- Spring Security数据库管理
要实现数据库管理用户角色及权限,需要自定义用户登录功能,Spring Security已经为我们提供了接口UserDetailService.需要以下表: 用户表 角色表 权限表 用户角色关系表 权限 ...