zoukankan      html  css  js  c++  java
  • 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")}"}}";
    }
    

    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
    suscipit recusandae consequuntur expedita et cum
    reprehenderit molestiae ut ut quas totam
    nostrum 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
    suscipit recusandae consequuntur expedita et cum
    reprehenderit molestiae ut ut quas totam
    nostrum 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
    suscipit recusandae consequuntur expedita et cum
    reprehenderit molestiae ut ut quas totam
    nostrum rerum est autem sunt rem eveniet architecto"}
    Post {userId = 1, id = 2, title = "qui est esse", body = "est rerum tempore vitae
    sequi sint nihil reprehenderit dolor beatae ea dolores neque
    fugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis
    qui 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
    suscipit recusandae consequuntur expedita et cum
    reprehenderit molestiae ut ut quas totam
    nostrum 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
    suscipit recusandae consequuntur expedita et cum
    reprehenderit molestiae ut ut quas totam
    nostrum 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
    suscipit recusandae consequuntur expedita et cum
    reprehenderit molestiae ut ut quas totam
    nostrum rerum est autem sunt rem eveniet architecto"}
    Post {userId = 1, id = 2, title = "qui est esse", body = "est rerum tempore vitae
    sequi sint nihil reprehenderit dolor beatae ea dolores neque
    fugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis
    qui 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"}
    {}
    
  • 相关阅读:
    ubuntu删除django和安装django
    linux shell 统计文件单词出现次数
    linux shell $$、$!特殊符号
    linux安装zabbix需要php两个模块php-bcmach与php-mbstring
    linux 源码编译与卸载
    Job for dhcpd.service failed because the control process exited with error code. See "systemctl status dhcpd.service" and "journalctl -xe" for details.问题
    Linux中部署DNS分离解析技术
    NFS网络文件系统服务搭建
    Samba服务搭建
    Linux RAID磁盘阵列技术
  • 原文地址:https://www.cnblogs.com/zwvista/p/9500975.html
Copyright © 2011-2022 走看看