Wpf 使用 Prism 实战开发Day16

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


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

  1. RestSharp 
  2. Newtonsoft.Json 

Wpf 使用 Prism 实战开发Day16_第1张图片

Wpf 使用 Prism 实战开发Day16_第2张图片


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

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

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

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

Wpf 使用 Prism 实战开发Day16_第3张图片

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 客户端项目,右键,启动一个新实例

Wpf 使用 Prism 实战开发Day16_第4张图片

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

Wpf 使用 Prism 实战开发Day16_第5张图片


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

Wpf 使用 Prism 实战开发Day16_第6张图片

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


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

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

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

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

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

        /// 
        /// 结果
        /// 
        public object Result { get; set; }
    }

    public class ApiResponse
    {
        /// 
        /// 返回消息
        /// 
        public string Message { get; set; }

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

        /// 
        /// 结果
        /// 
        public T Result { get; set; }
    }

Wpf 使用 Prism 实战开发Day16_第7张图片

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

Wpf 使用 Prism 实战开发Day16_第8张图片

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

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

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

        /// 
        /// 请求参数
        /// 
        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 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(response.Content);
    }

    //通用带泛型请求
    public async Task> 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>(response.Content);
    }
}

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

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

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

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

 public class BaseService : IBaseService 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> AddAsync(TEntity entity)
     {
         var request = new BaseRequest() {
             Method = Method.Post,
             Route=$"api/{serverName}/Add",
             Paramenter=entity
         };
         return await client.ExecuteAsync(request);
     }

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

     public async Task>> 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> (request);
     }

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

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

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

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

    public interface IToDoService:IBaseService
    {
    }

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

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

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

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

            containerRegistry.RegisterForNavigation();
            containerRegistry.RegisterForNavigation();
            containerRegistry.RegisterForNavigation();
            containerRegistry.RegisterForNavigation();
            containerRegistry.RegisterForNavigation();
            containerRegistry.RegisterForNavigation();
        }
    }

Wpf 使用 Prism 实战开发Day16_第9张图片


4.最后,在ViewModels 中,去使用 待办事项接口服务(IToDoService )

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


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

     /// 
     /// 创建数据的动态集合
     /// 
     public ObservableCollection 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="测试数据..."
         //    });
         //}
     }
     /// 
     /// 添加待办
     /// 
     /// 
     private void Add()
     {
         IsRightDrawerOpen=true;
     }

 }

 四.代码结构

Wpf 使用 Prism 实战开发Day16_第10张图片

你可能感兴趣的:(WPF入门,wpf,c#,数据库)