Wpf 使用 Prism 实战开发Day16

客户端使用RestSharp库调用WebApi 动态加载数据


在MyDoTo客户端中,使用NuGet 安装两个库

  1. RestSharp 
  2. Newtonsoft.Json 


一. RestSharp 简单的使用测试例子

当前章节主要目的是:对RestSharp 库,根据项目需求再次进行封装。下面先做个简单的使用测试例子。

1.首先运行WebApi 项目,获取Memo 单条数据

请求成功后,可以看到请求的URL和返回的Response body(响应内容)

2.在MyToDo客户端的 MemoViewModel中 ,CreateMemoList 方法加载数据时进行以下修改测试

var client = new RestSharp.RestClient("http://localhost:5143");
var requestGet = new RestRequest("api/Memo/Get",Method.Get);
requestGet.AddParameter("id","2");
var response= client.Execute(requestGet);
var con= response.Content;

 如果需要解析拿到的具体对象数据,需对结果进行 JsonConvert.DeserializeObject 反序列化。具体的解析步骤就是:

  • 拿到对象数据,把JSON 生成C# 实体类。进行反序列化的时候把当前数据实体类传进去就OK了。

 3.把WebApi项目已经启动后,选择 MyToDo 客户端项目,右键,启动一个新实例

或者右键解决方案==》属性,配置多个启动项目


4.最后在MyToDo客户端打断点调试。运行起来后,命中断点,可以看到请求的接口有数据返回了

 基本的简单使用就是这样。在RestSharp 官网 有各种使用实例,复杂的涉到Token 身份认证等都有。


二.对 RestSharp 进行封装使用,集成到客户端中

新建一个服务层文件夹(Service),用于存放封装对WebApi 接口的访问等处理逻辑

1. 首先把 ApiResponse 共用类,移到MyToDo.Shared 中,并且再添加请求结果泛型的ApiResponse 类

    public class ApiResponse
    {
        /// <summary>
        /// 失败
        /// </summary>
        /// <param name="message"></param>
        /// <param name="status"></param>
        public ApiResponse(string message, bool status = false)
        { 
            this.Message = message;
            this.Status = status;
        }
        /// <summary>
        /// 成功
        /// </summary>
        /// <param name="status"></param>
        /// <param name="result"></param>
        public ApiResponse(bool status,object result) 
        {
          this.Status = status;
          this.Result = result;
        }
        /// <summary>
        /// 返回消息
        /// </summary>
        public string Message { get; set; }

        /// <summary>
        /// 返回状态
        /// </summary>
        public bool Status { get; set; }

        /// <summary>
        /// 结果
        /// </summary>
        public object Result { get; set; }
    }

    public class ApiResponse<T>
    {
        /// <summary>
        /// 返回消息
        /// </summary>
        public string Message { get; set; }

        /// <summary>
        /// 返回状态
        /// </summary>
        public bool Status { get; set; }

        /// <summary>
        /// 结果
        /// </summary>
        public T Result { get; set; }
    }

且MyToDo 客户端要引用MyToDo.Shared 项目。

2. 在 MyToDo 项目Service 文件夹中,封装一个通用的请求类型类(BaseRequest)主要用于构造请求接口的时候,传递的参数。

    public class BaseRequest
    {
        /// <summary>
        /// 请求类型
        /// </summary>
        public Method Method { get; set; }
        /// <summary>
        /// 路由,也就是Url
        /// </summary>
        public string Route { get; set; }

        /// <summary>
        /// 数据类型描述
        /// </summary>
        public string ContentType { get; set; } = "application/json";

        /// <summary>
        /// 请求参数
        /// </summary>
        public object Paramenter { get; set; }
    }

 3.同样,接着再封装一个访问WebApi 的共用类(HttpRestClient)

public class HttpRestClient
{
    private readonly string apiUrl;
    protected readonly RestClient clinet;

    public HttpRestClient(string apiUrl) 
    {
        this.apiUrl = apiUrl;
        clinet = new RestClient(apiUrl);
    }

    //通用请求
    public async Task<ApiResponse> ExecuteAsync(BaseRequest baseRequest)
    {
        
        var request = new RestRequest(baseRequest.Route, baseRequest.Method);
        //添加请求头
        request.AddHeader("Content-Type", baseRequest.ContentType);
        //添加请求参数
        if (baseRequest.Paramenter != null)
        {
            //把请求参数进行序列化后,添加进来。并且设置序列化的类型
            request.AddParameter("param",JsonConvert.SerializeObject(baseRequest.Paramenter),ParameterType.RequestBody);
        }
         var response=await clinet.ExecuteAsync(request);
        //把结果进行反序列化后,返回出去
        return JsonConvert.DeserializeObject<ApiResponse>(response.Content);
    }

    //通用带泛型请求
    public async Task<ApiResponse<T>> ExecuteAsync<T>(BaseRequest baseRequest)
    {

        var request = new RestRequest(baseRequest.Route, baseRequest.Method);
        //添加请求头
        request.AddHeader("Content-Type", baseRequest.ContentType);
        //添加请求参数
        if (baseRequest.Paramenter != null)
        {
            //把请求参数进行序列化后,添加进来。并且设置序列化的类型
            request.AddParameter("param", JsonConvert.SerializeObject(baseRequest.Paramenter), ParameterType.RequestBody);
        }
        var response = await clinet.ExecuteAsync(request);
        //把结果进行反序列化后,返回出去
        return JsonConvert.DeserializeObject<ApiResponse<T>>(response.Content);
    }
}

4.创建通用的请求服务类(IBaseService)

    public interface IBaseService<TEntity> where TEntity : class
    {
        //添加
        Task<ApiResponse<TEntity>> AddAsync(TEntity entity);
        //更新
        Task<ApiResponse<TEntity>> UpdateAsync(TEntity entity);
        //删除
        Task<ApiResponse> DeleteAsync(int id);
        //根据id,取第一条数据
        Task<ApiResponse<TEntity>> GetFirstOfDefaultAsync(int id);

        //获取所有数据
        Task<ApiResponse<PagedList<TEntity>>> GetAllAsync(QueryParameter parameter);
    }

5. 实现(BaseService)通用服务类。继承 IBaseService

 public class BaseService<TEntity> : IBaseService<TEntity> where TEntity : class
 {
     private readonly HttpRestClient client;
     private readonly string serverName;

     public BaseService(HttpRestClient client,string serverName)
     {
         this.client = client;
         this.serverName = serverName;
     }



     public async Task<ApiResponse<TEntity>> AddAsync(TEntity entity)
     {
         var request = new BaseRequest() {
             Method = Method.Post,
             Route=$"api/{serverName}/Add",
             Paramenter=entity
         };
         return await client.ExecuteAsync<TEntity>(request);
     }

     public async Task<ApiResponse> DeleteAsync(int id)
     {
         var request = new BaseRequest()
         {
             Method = Method.Delete,
             Route = $"api/{serverName}/Delete?id={id}"
         };
         return await client.ExecuteAsync(request);
     }

     public async Task<ApiResponse<PagedList<TEntity>>> GetAllAsync(QueryParameter parameter)
     {
         var request = new BaseRequest()
         {
             Method = Method.Get,
             Route = $"api/{serverName}/GetAll?pageIndex={parameter.PageIndex}&pageSize={parameter.PageSize}&Search={parameter.Search}"
         };
         return await client.ExecuteAsync<PagedList<TEntity>> (request);
     }

     public async Task<ApiResponse<TEntity>> GetFirstOfDefaultAsync(int id)
     {
         var request = new BaseRequest()
         {
             Method = Method.Delete,
             Route = $"api/{serverName}/Get?id={id}"
         };
         return await client.ExecuteAsync<TEntity>(request);
     }

     public async Task<ApiResponse<TEntity>> UpdateAsync(TEntity entity)
     {
         var request = new BaseRequest()
         {
             Method = Method.Post,
             Route = $"api/{serverName}/Update",
             Paramenter = entity
         };
         return await client.ExecuteAsync<TEntity>(request);
     }
 }

三.待办事项调用WebApi服务接口获取数据

1.首先创建(待办事项服务接口类) IToDoService ,继承IBaseService 基类

    public interface IToDoService:IBaseService<ToDoDto>
    {
    }

2.接着,要实现(待办事项服务接口类)ToDoService。继承BaseService和IToDoService 

    public class ToDoService : BaseService<ToDoDto>, IToDoService
    {
        /// <summary>
        /// 构造中,直接传控制器名称进去。因为在Web Api项目中,待办事项控制器的名称,就是叫ToDo
        /// </summary>
        /// <param name="client"></param>
        /// <param name="serverName"></param>
        public ToDoService(HttpRestClient client, string serverName= "ToDo") : base(client, serverName)
        {
        }
    }

3.最后,需要在 App.xaml.cs 中,进行依赖注入

    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : PrismApplication
    {
        /// <summary>
        /// 创建启动页面
        /// </summary>
        /// <returns></returns>
        protected override Window CreateShell()
        {
           return Container.Resolve<MainView>();
        }
        /// <summary>
        /// 依懒注入的方法
        /// </summary>
        /// <param name="containerRegistry"></param>
        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            //对封装的http请求类,进行注入。并且设置一个默认参数
            containerRegistry.GetContainer().Register<HttpRestClient>(made:Parameters.Of.Type<string>(serviceKey:"webUrl"));
            //注册默认的服务地址
            containerRegistry.GetContainer().RegisterInstance(@"http://localhost:5143/",serviceKey: "webUrl");
            //注册服务
            containerRegistry.Register<IToDoService, ToDoService>();

            containerRegistry.RegisterForNavigation<AboutView>();
            containerRegistry.RegisterForNavigation<SkinView, SkinViewModel>();
            containerRegistry.RegisterForNavigation<IndexView, IndexViewModel>();
            containerRegistry.RegisterForNavigation<MemoView, MemoViewModel>();
            containerRegistry.RegisterForNavigation<ToDoView, ToDoViewModel>();
            containerRegistry.RegisterForNavigation<SettingsView, SettingsViewModel>();
        }
    }


4.最后,在ViewModels 中,去使用 待办事项服务

public class ToDoViewModel:BindableBase
 {
     public ToDoViewModel(IToDoService toDoService)
     {
         ToDoDtos = new ObservableCollection<ToDoDto>();
         AddCommand = new DelegateCommand(Add);
         this.toDoService = toDoService;
         CreateTodoList();
     }
     private bool isRightDrawerOpen;
     /// <summary>
     /// 右侧编辑窗口是否展开
     /// </summary>
     public bool IsRightDrawerOpen
     {
         get { return isRightDrawerOpen; }
         set { isRightDrawerOpen = value; RaisePropertyChanged(); }
     }


     public DelegateCommand AddCommand{ get; private set; }
     private ObservableCollection<ToDoDto> toDoDtos;
     private readonly IToDoService toDoService;

     /// <summary>
     /// 创建数据的动态集合
     /// </summary>
     public ObservableCollection<ToDoDto> ToDoDtos
     {
         get { return toDoDtos; }
         set { toDoDtos = value;RaisePropertyChanged(); }
     }
     async void CreateTodoList()
     {
         //添加查询条件
        var todoResult=await toDoService.GetAllAsync(new Shared.Parameters.QueryParameter()
         {
             PageIndex = 0,
             PageSize = 100,
         });
         if (todoResult.Status)
         {
             toDoDtos.Clear();
             foreach (var item in todoResult.Result.Items)
             {
                 toDoDtos.Add(item);
             }
         }
         //for (int i = 0; i < 20; i++)
         //{
         //    toDoDtos.Add(new ToDoDto()
         //    {
         //        Title="标题"+i,
         //        Content="测试数据..."
         //    });
         //}
     }
     /// <summary>
     /// 添加待办
     /// </summary>
     /// <exception cref="NotImplementedException"></exception>
     private void Add()
     {
         IsRightDrawerOpen=true;
     }

 }

 四.代码结构

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/353221.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

优雅的python(二)

&#x1f308;个人主页&#xff1a;小田爱学编程 &#x1f525; 系列专栏&#xff1a;c语言从基础到进阶 &#x1f3c6;&#x1f3c6;关注博主&#xff0c;随时获取更多关于c语言的优质内容&#xff01;&#x1f3c6;&#x1f3c6; &#x1f600;欢迎来到小田代码世界~ &#x…

【Go 快速入门】数组 | 切片 | 映射 | 函数 | 结构体 | 方法和接收者

文章目录 数组切片append 函数copy 函数删除元素 映射delete 函数 函数init 特殊的函数defer 语句panic / recover 错误处理 类型结构体内存对齐JSON 序列化与反序列化方法和接收者 项目代码地址&#xff1a;03-ArraySliceMapFuncStruct 数组 基本格式&#xff1a;var 数组变…

C#,最小生成树(MST)普里姆(Prim)算法的源代码

Vojtěch Jarnk 一、Prim算法简史 Prim算法&#xff08;普里姆算法&#xff09;&#xff0c;是1930年捷克数学家算法沃伊捷赫亚尔尼克&#xff08;Vojtěch Jarnk&#xff09;最早设计&#xff1b; 1957年&#xff0c;由美国计算机科学家罗伯特普里姆独立实现&#xff1b; 19…

智慧交通的“大脑”与“神经”:物联网与车联网双轮驱动,智慧交通加速驶入未来

目录 一、物联网&#xff1a;智慧交通的“大脑” 二、车联网&#xff1a;智慧交通的“神经” 三、物联网与车联网的协同发展 四、智慧交通的未来展望 五、物联网与车联网在智慧交通中的应用案例 六、智慧交通面临的挑战与解决方案 七、政策与法规在智慧交通发展中的作用…

35、WEB攻防——通用漏洞XSS跨站反射存储DOM盲打劫持

文章目录 XSS产生于前端的漏洞&#xff0c;常产生于&#xff1a; XSS分类&#xff1a; 反射型&#xff08;非持久型&#xff09; 存储型&#xff08;持久型&#xff09;&#xff0c;攻击代码被写入数据库中。常见于&#xff1a;写日志、留言、评论的地方 DOM型 DOM型XSS与…

【深度学习】【AutoDL】【SSH】通过VSCode和SSH使用AutoDL服务器训练模型

身边没有显卡资源或不足以训练模型时&#xff0c;可以租赁服务器的显卡。 1、注册AutoDL并配置环境 首先打开AutoDL官网&#xff0c;注册账号并租赁自己期望的显卡资源 点击“租赁”之后&#xff0c;我们要继续选择基础环境。此处&#xff0c;我们让其自动配置好基础的pytor…

抖去推短视频矩阵系统+实景无人直播系统技术源头开发

抖去推爆款视频生成器&#xff0c;通过短视频矩阵、无人直播&#xff0c;文案引流等&#xff0c;打造实体商家员工矩阵、用户矩阵、直播矩阵&#xff0c;辅助商家品牌曝光&#xff0c;团购转化等多功能赋能商家拓客引流。 短视频矩阵通俗来讲就是批量剪辑视频和批量发布视频&a…

Kotlin Multiplatform项目推荐 | 太空人分布图

Kotlin Multiplatform项目推荐 | 太空人分布图 项目简介 Kotlin Multiplatform项目是一种跨平台开发技术&#xff0c;它可以同时使用SwiftUI、Jetpack Compose、Compose for Wear OS、Compose for Desktop、Compose for Web、Kotlin/JS React等客户端框架&#xff0c;并且使…

MCU启动文件小解一下

GD32启动文件分析 启动文件的一些指令.s启动文件分析栈空间分配堆空间管理中断向量表定义堆空间定义Reset_Handler复位程序HardFault_Handler_main文件分析用户堆栈初始化 GD32启动文件主要做了以下工作&#xff1a; 初始化SP_initial_sp , PCReset_Handler指针&#xff0c;设置…

Linux下安装openresty

Linux下安装openresty 十一、Linux下安装openresty11.1.概述11.2.下载OpenResty并安装相关依赖&#xff1a;11.3.使用wget下载:11.4.解压缩:11.5.进入OpenResty目录:11.6.编译和安装11.7.进入OpenResty的目录&#xff0c;找到nginx&#xff1a;11.8.在conf目录下的nginx.conf添…

React一学就会(3): 强化练习一

前言 兄弟们点个关注点点赞&#xff0c;有什么建议在评论里留言说一下&#xff0c;一定要和我多多互动啊&#xff0c;这样我才有动力创作出更有品质的文章。 这节课我们用前两节课的知识做一个实践&#xff0c;在实战中巩固我们所学。本来我想借用官方的示例翻译一下&#xf…

Redis3-秒杀活动

秒杀 准备工作 我是参照下面这位大佬的i骄傲成下载的 csdn友情链接 Jmeter模拟多线程的压力测试工具 秒杀代码&#xff1a; package com.aaa.controller;import io.netty.util.internal.StringUtil; import org.apache.commons.lang.StringUtils; import org.springfram…

HarmonyOS鸿蒙ArkTS,封装http网络请求

HarmonyOS鸿蒙ArkTS&#xff0c;封装http网络请求 前提&#xff1a; 要想使用http请求&#xff0c;系统必须要具备ohos.permission.INTERNET权限&#xff0c;在model.json5文件中的module模块下添加如下请求权限&#xff1a; 在module.json5文件中 配置 "requestPermi…

1949-2022年交通运输设备行业数据

1949-2022年交通运输设备行业数据 1、时间1949-2021年 2、指标&#xff1a;民用驳船保有量(艘)_AmoCivBar、民用机动船保有量(艘)_AmoCivMotBoat、民用运输机保有量(架)_AmoPlaTra、民用其他汽车保有量(万辆)_AmoOthAutCiv、私人其他汽车保有量(万辆)_AmoOthAutPri、新注册民…

k8s 进阶实战笔记 | Scheduler 调度策略总结

文章目录 Scheduler 调度策略总结调度原理和过程调度策略nodeSelect亲和性和反亲和性NodeAffinify亲和验证PodAffinity 亲和验证PodAntiAffinity 反亲和验证污点与容忍跳过 Scheduler 调度策略 调度策略场景总结 Scheduler 调度策略总结 调度原理和过程 Scheduler 一直监听着…

Linux使用二进制包安装MySQL

目录 一、软件包下载 二、上传软件包到Linux根目录 1、使用xftp将软件包上传到根目录 2、解压缩 三、准备工作 四、初始化软件 五、设置MySQL的配置文件 六、配置启动脚本 一、软件包下载 官网下载&#xff1a;MySQL :: Download MySQL Community Server 二、上传软件…

【leetcode题解C++】144. 94. 145.二叉树前序、中序、后序遍历 and 102.二叉树的层序遍历

144. 二叉树前序遍历 给出一个根节点&#xff0c;返回前中后序遍历的结果的。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,2,3]示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[]示例 3&#xff1a; 输入&#xff1a;root…

vue项目如何打包,java项目如何打包

目录 vue项目如何打包 java项目如何打jar包 使用Maven打包为JAR&#xff08;方式一&#xff09;视图&#xff1a; 先双击clean再双击package即可打包 使用Maven打包为JAR&#xff08;方式二&#xff09;命令&#xff1a; 1、确保你已经安装了Maven&#xff0c;并且配置了相应…

关机恶搞小程序

1. system("shutdown")的介绍 当system函数的参数是"shutdown"时&#xff0c;它将会执行系统的关机命令。 具体来说&#xff0c;system("shutdown")的功能是向操作系统发送一个关机信号&#xff0c;请求关闭计算机。这将触发操作系统执行一系列…

uniapp实现页面左滑右滑切换内容

uniapp uview&#xff1a;使用uniapp的swiper和uview的tabs标签组合实现 Tabs 标签 | uview-plus 3.0 - 全面兼容nvue的uni-app生态框架 - uni-app UI框架 vue <template> <view class"main"> <view class""> …