Wpf 使用 Prism 实战开发Day16

news2024/11/15 21:25:31

客户端使用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 中,去使用 待办事项接口服务(IToDoService )

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;
     }

 }

 四.代码结构

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端开发基于Qunee绘制网络拓扑图总结-02

1、渲染连线颜色 *关键函数一定要调用&#xff1a;graph.invalidate()* graph.forEach(function(element) {if (element instanceof Q.Edge) {let arr [#549BF1, #AA8A6E, #8F54F1,#5A70BC,#BCBF5C, #BC5A76, #67B4D4,#B4C9EF, #676AD4, #A86EAA,#5CBF7F, #EFB4B4];let inde…

CapCut - 剪映国际版11.0.0

【应用名称】&#xff1a;CapCut - 剪映国际版 【适用平台】&#xff1a;#Android 【软件标签】&#xff1a;#CapCut #剪映国际版 【应用版本】&#xff1a;11.0.0 【应用大小】&#xff1a;231MB 【软件说明】&#xff1a;软件升级更新。目前大家广泛使用的最令人惊叹、最专业…

负载均衡下的webshell上传+nginx解析漏洞

负载均衡下的webshell上传 一&#xff0c;负载均衡下webshell上传的四大难点 难点一&#xff1a;需要在每一台节点的相同位置上传相同内容的webshell 我们需要在每一台节点的相同位置都上传相同内容的 WebShell一旦有一台机器上没有&#xff0c;那么在请求轮到这台机器上的时…

C++ hash—unordered_mapset

目录 一. unordered系列关联式容器 1、文档说明 2、接口说明 1. 构造 2. 容量 3. 迭代器 4. 元素访问 5. 查询 6. 修改 7. 桶操作 8. 测试 二、unordered_set 1、​​​​​​​文档说明 2、接口说明 1. 构造 2. 容量 3. 迭代器 4. 元素访问 5. 插入和删除…

AI赋能编程 | 自动化工具助力高效办公

前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;https://www.captainbed.cn/z ChatGPT体验地址 文章目录 前言泡泡AI工具卡片思维导图Markdown编辑器 其他工具文件免费处理工具结语 合集…

SpringBoot 使用WebSocket功能

实现步骤&#xff1a; 1.导入WebSocket坐标。 在pom.xml中增加依赖项&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dependency>2.编写WebSocket配…

查看 npm的一些命令,以及npm config set registry x x x 不生效 解决方案

在 Mac 上查看自己的 npm 源&#xff0c;可以使用以下命令&#xff1a; 打开终端应用程序&#xff08;Terminal&#xff09;。 运行以下命令来查看当前的 npm 配置&#xff1a; npm config list这会显示 npm 的配置信息&#xff0c;包括当前使用的源&#xff08;registry&am…

FCIS 2023:洞悉网络安全新前沿,引领未来安全创新狂潮

在数字化浪潮席卷全球的今天&#xff0c;网络安全问题愈发凸显其重要性。 FCIS 2023网络安全创新大会作为业界瞩目的盛会&#xff0c;不仅汇聚了国际顶尖的网络安全专家&#xff0c;更展示了最前沿的安全技术与研究成果。那么&#xff0c;参与这场大会&#xff0c;我们究竟能学…

MySQL-DQL(Data Query Language)数据查询语言

文章目录 1. DQL定义2. 基础查询3. 条件查询&#xff08;WHERE&#xff09;4. 分组查询&#xff08;GROUP BY&#xff09;5. 过滤分组&#xff08;HAVING&#xff09;6. 排序&#xff08;ORDER BY&#xff09;7. 限制查询结果的条数&#xff08;LIMIT&#xff09;8. 多表查询8.…

OG Trade在ZKX揭幕:一家基于Starknet的游戏化永续合约交易所

ZKX的 OG Trade通过内置游戏化和30分钟交易竞赛&#xff0c;为所有交易者创造机会&#xff0c;革新了永续合约交易模式。 2024年1月30日 — ZKX宣布推出OG Trade&#xff0c;这是一家基于Starknet的游戏化永续合约交易所&#xff0c;旨在满足短期交易者、高水平交易者和波段交易…

数据可视化工具之选,三选一?

在数据可视化的世界中&#xff0c;选择一款合适的工具对于提升工作效率和洞察力至关重要。本文将对三款主流数据可视化工具进行详细比较&#xff0c;包括山海鲸可视化、Echarts和D3.js&#xff0c;以帮助您做出明智的选择。 山海鲸可视化 山海鲸可视化是一款免费且功能强大的…

全面掌握Django的web框架Django Rest_Framework(一)

文章目录 Django Rest_Framework1. DRF介绍2.DRF特点3.环境安装与配置&#xff08;1&#xff09;DRF需要以下依赖&#xff08;2&#xff09;创建django项目 4.序列化器的使用&#xff08;1&#xff09;创建序列化器 5. 反序列化器使用 Django Rest_Framework 1. DRF介绍 Djan…

phar反序列化漏洞

基础&#xff1a; Phar是一种PHP文件归档格式&#xff0c;它类似于ZIP或JAR文件格式&#xff0c;可以将多个PHP文件打包成一个单独的文件&#xff08;即Phar文件&#xff09;。 打包后的Phar文件可以像普通的PHP文件一样执行&#xff0c;可以包含PHP代码、文本文件、图像等各…

Web中的转发与重定向

转发与重定向 一、转发和重定向的概念1.转发2.重定向 二、JavaWeb 中的转发和重定向三、SpringMVC 中的转发和重定向1.转发(1) 默认的方式(2) 完整的方式 2.重定向 四、总结 一、转发和重定向的概念 在 Web 应用中&#xff0c;转发和重定向都是用于将请求从一个页面传递到另一…

asp.net吃了么销售系统

asp.net吃了么销售系统 用户功能有首页购买商品 购物车 我的订单 后台管理员可以进行用户管理 菜品管理 订单管理 销售统计 asp.net吃了么销售系统是一个功能完善的在线购物平台&#xff0c;用户可以在首页浏览并购买各类商品。通过购物车功能&#xff0c;用户可以方便地管理…

ElasticSearch 应用实践 笔记

概述 介绍 ES 是一个开源的高扩展的分布式全文搜索引擎&#xff0c;是整个Elastic Stack技术栈的核心。它可以近乎实时的存储&#xff0c;检索数据&#xff1b;本身扩展性很好&#xff0c;可以扩展到上百台服务器&#xff0c;处理PB级别的数据。ElasticSearch的底层是开源库Lu…

什么样的评论更容易得到别人的关注

要发表吸引人的评论&#xff0c;可以注意这些个方面&#xff1a; 合适的软件&#xff1a;用DT浏览器的笔记本写文本&#xff0c;保存为图片&#xff0c;用图片的方式评论更容易得到别人的关注。 特别的观点&#xff1a;发表与众不同的观点&#xff0c;或者从不同的角度看待问…

上岸国考有多难?

国考笔试成绩已于2024年1月13日公布&#xff0c;听说宇宙的尽头是编制&#xff0c;今天用一份2024国考的数据帮大家探探路。数据来自和鲸平台&#xff0c;数据主要包括招考省市和部门、专业和学历要求、招考和报考人数。 经过一番探索&#xff0c;我发现一个上岸密码&#xff1…

成功解决AttributeError: ‘str‘ object has no attribute ‘keys‘

成功解决AttributeError: ‘str’ object has no attribute ‘keys’。 &#x1f335;文章目录&#x1f335; &#x1f333;引言&#x1f333;&#x1f333;报错分析及解决方案&#x1f333;&#x1f333;字典对象的keys方法&#x1f333;&#x1f333;结尾&#x1f333; &…

01、全文检索 ------ 反向索引库 与 Lucene 的介绍

目录 全文检索 ------ 反向索引库 与 LuceneSQL模糊查询的问题反向索引库反向索引库的查询 Lucene&#xff08;全文检索技术&#xff09;Lucene能做什么Lucene存在的问题Solr 和 Elasticsearch 与 Lucene 的关系 全文检索 ------ 反向索引库 与 Lucene MySQL一些索引词汇解释 …