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的更多相关文章

  1. ReactiveX 学习笔记(14)使用 RxJava2 + Retrofit2 调用 REST API

    JSON : Placeholder JSON : Placeholder (https://jsonplaceholder.typicode.com/) 是一个用于测试的 REST API 网站. ...

  2. ReactiveX 学习笔记(17)使用 RxSwift + Alamofire 调用 REST API

    JSON : Placeholder JSON : Placeholder (https://jsonplaceholder.typicode.com/) 是一个用于测试的 REST API 网站. ...

  3. ReactiveX 学习笔记(18)使用 RxJS + Angular 调用 REST API

    JSON : Placeholder JSON : Placeholder (https://jsonplaceholder.typicode.com/) 是一个用于测试的 REST API 网站. ...

  4. ReactiveX 学习笔记(0)学习资源

    ReactiveX 学习笔记 ReactiveX 学习笔记(1) ReactiveX 学习笔记(2)创建数据流 ReactiveX 学习笔记(3)转换数据流 ReactiveX 学习笔记(4)过滤数据 ...

  5. Ext.Net学习笔记15:Ext.Net GridPanel 汇总(Summary)用法

    Ext.Net学习笔记15:Ext.Net GridPanel 汇总(Summary)用法 Summary的用法和Group一样简单,分为两步: 启用Summary功能 在Feature标签内,添加如 ...

  6. SQL反模式学习笔记15 分组

    目标:查询得到每组的max(或者min等其他聚合函数)值,并且得到这个行的其他字段 反模式:引用非分组列 单值规则:跟在Select之后的选择列表中的每一列,对于每个分组来说都必须返回且仅返回一直值. ...

  7. ReactiveX 学习笔记(24)使用 RxCpp + C++ REST SDK 调用 REST API

    JSON : Placeholder JSON : Placeholder (https://jsonplaceholder.typicode.com/) 是一个用于测试的 REST API 网站. ...

  8. 【Spring学习笔记-MVC-4】SpringMVC返回Json数据-方式2

    <Spring学习笔记-MVC>系列文章,讲解返回json数据的文章共有3篇,分别为: [Spring学习笔记-MVC-3]SpringMVC返回Json数据-方式1:http://www ...

  9. 【Spring学习笔记-MVC-3】SpringMVC返回Json数据-方式1

    <Spring学习笔记-MVC>系列文章,讲解返回json数据的文章共有3篇,分别为: [Spring学习笔记-MVC-3]SpringMVC返回Json数据-方式1:http://www ...

随机推荐

  1. [UE4]Return Node节点好用法

    蓝图自定义函数中,碰到“Return Node”也会推出当前的函数,跟高级语言的“return”是一样的用法

  2. KPPW2.5 漏洞利用--SQL注入

    KPPW2.5 漏洞利用--SQL注入 SQL注入--布尔型盲注 环境搭建 1,集成环境简单方便,如wamp,phpstudy.... 2,KPPW v2.2源码一份(文末有分享)放到WWW目录下面 ...

  3. Mysql 之分库分表方案

    Mysql分库分表方案 为什么要分表 当一张表的数据达到几千万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了.分表的目的就在于此,减小数据库的负担,缩短查询时间. mysq ...

  4. Linux内核学习笔记二——进程

    Linux内核学习笔记二——进程   一 进程与线程 进程就是处于执行期的程序,包含了独立地址空间,多个执行线程等资源. 线程是进程中活动的对象,每个线程都拥有独立的程序计数器.进程栈和一组进程寄存器 ...

  5. C#存储过程中传入传出参数

    作者:卞功鑫  ,转载请保留http://www.cnblogs.com/BinBinGo/p/6399847.html //1 连接字符串 string connectionString = &qu ...

  6. ZooKeeper系列(6):ZooKeeper机制架构

    一.ZooKeeper权限管理机制 1.1 权限管理ACL(Access Control List) ZooKeeper 的权限管理亦即ACL 控制功能,使用ACL来对Znode进行访问控制.ACL的 ...

  7. PHP:导出数据到word(包含图片)

    1.方法 public function word() { $xlsModel = M('api_aliucheng'); $Data = $xlsModel->Field('id,u_name ...

  8. @Autowired与@Resource 详细诠释和区别(附带例子)

    @Autowired 与@Resource:1.@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上. 2.@Autowired默认按类型装配( ...

  9. url后面带斜杠与不带斜杠的区别

    比如: https://www.baidu.com/test/ https://www.baidu.com/test 当Web服务器接收到对某个末尾不含斜杠的url请求时,例如https://www. ...

  10. eclipse聚合工程如何提交SVN,如何从SVN下载

    提交: 比如聚合工程为taotao-manager,包含了taotao1,taotao2,taotao3等项目,在提交SVN只需 提交taotao-manager就可以了 1.右键taotao-man ...