(十三)RestShaarp

RestShaarp

1.简介

  • RestSharp 的主要目的是通过 HTTP 对远程资源进行同步和异步调用。
  • 顾名思义,RestSharp 的主要受众是使用 REST API 的开发人员。
  • 但是,RestSharp 可以通过 HTTP(但不是 HTTP/2)调用任何 API,只要您拥有符合 W3C HTTP 标准的资源 URI 和要发送的请求参数。
  • .NET 开发人员使用 HTTP API 的主要挑战之一是处理不同类型的请求和响应,并将它们转换为复杂的 C# 类型。
  • RestSharp 可以负责将请求正文序列化为 JSON 或 XML 并反序列化响应。
  • 它还可以根据不同的参数类型(路径、查询、表单或正文)形成有效的请求 URI。
    官网:https://restsharp.dev/intro.html#introduction

2.下载包

新版用法与106版本不同
其中postman里面可以通过接口生成C#restsharp的代码
image

服务层

1. 基本请求类

 public class BaseRequest
 {
     public Method Method { get; set; }
     public string? Route { get; set; }
     public string ContentType { get; set; } = "application/json";
     public object? Parameter { get; set; }//body当中
 }

2. 通用HTTP请求类

    public class HttpRestClient
    {
        private readonly string apiUrl;//基地址
       // private  RestClient client;

        public HttpRestClient(string apiUrl)
        {
            this.apiUrl = apiUrl;//请求地址
             // client = new RestClient();//创建请求的客户端
        }

        //异步请求
        public async Task<ApiResponse> ExecuteAsync(BaseRequest baseRequest)
        {
            var request = new RestRequest(string.Empty, baseRequest.Method);
            request.AddHeader("Content-Type", baseRequest.ContentType);

            if (baseRequest.Parameter != null)
            {//SerializeObject序列化
                request.AddParameter("param", JsonConvert.SerializeObject(baseRequest.Parameter), ParameterType.RequestBody);
            }
     
            var options = new RestClientOptions();
            options.BaseUrl = new Uri(apiUrl + baseRequest.Route);
            var client = new RestClient(options);
            var response = await client.ExecuteAsync(request);

            return JsonConvert.DeserializeObject<ApiResponse>(response.Content);//DeserializeObject反序列化
        }

        //带泛型的
        public async Task<ApiResponse<T>> ExecuteAsync<T>(BaseRequest baseRequest)
        {
            var request = new RestRequest(string.Empty, baseRequest.Method);
            request.AddHeader("Content-Type", baseRequest.ContentType);

            if (baseRequest.Parameter != null)
            {//SerializeObject序列化
                request.AddParameter("param", JsonConvert.SerializeObject(baseRequest.Parameter), ParameterType.RequestBody);
            }
            //client.Options.BaseUrl = new Uri(apiUrl + baseRequest.Route);
            //client.BaseUrl =new Uri(apiUrl+baseRequest.Route);

            var options=new RestClientOptions();
            options.BaseUrl= new Uri(apiUrl + baseRequest.Route);
            var client =new RestClient(options);     
            var response = await client.ExecuteAsync(request);

            return JsonConvert.DeserializeObject<ApiResponse<T>>(response.Content);//DeserializeObject反序列化
        }
    }

3.通用服务类

先写接口

 public interface IBaseService<TEntity> where TEntity : class
 {//通用接口层
     Task<ApiResponse<TEntity>> AddAsync(TEntity entity);
     Task<ApiResponse<TEntity>> UpdateAsync(TEntity entity);
     Task<ApiResponse> DeleteAsync(int id);
     Task<ApiResponse<TEntity>> GetFirstOfDefaultAsync(int id);
     Task<ApiResponse<PagedList<TEntity>>> GetAllAsync(QueryParameter parameter);//返回分页的数据
 }

通用服务层
CRUD里面是不同的request生成,客户端并不需要实现逻辑代码,具体的在接口api中实现

 public class BaseService<TEntity> : IBaseService<TEntity> where TEntity : class
 {//通用服务层
     private readonly HttpRestClient client;
     private readonly string serviceName;

     public BaseService(HttpRestClient client, string serviceName)
     {
         this.client = client;
         this.serviceName = serviceName;
     }
     public async Task<ApiResponse<TEntity>> AddAsync(TEntity entity)
     {
         BaseRequest request = new BaseRequest();
         request.Method = RestSharp.Method.Post;
         request.Route = $"api/{serviceName}/Add";
         request.Parameter = entity;
         return await client.ExecuteAsync<TEntity>(request);
     }

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

     public async Task<ApiResponse<PagedList<TEntity>>> GetAllAsync(QueryParameter parameter)
     {
         BaseRequest request = new BaseRequest();
         request.Method = RestSharp.Method.Get;
         request.Route = $"api/{serviceName}/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)
     {
         BaseRequest request = new BaseRequest();
         request.Method = RestSharp.Method.Get;
         request.Route = $"api/{serviceName}/Get?id={id}";
         return await client.ExecuteAsync<TEntity>(request);
     }

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

4. 具体的服务

待办服务和备忘录服务就创建接口,创建自己的服务类,继承通用服务类

public interface IToDoService : IBaseService<ToDoDto>
{
}

base调用基类构造函数

 public class ToDoService : BaseService<ToDoDto>, IToDoService
 {
     public ToDoService(HttpRestClient client) : base(client, "ToDo")
     {
     }
 }

5. 注册

 //服务器注册
 containerRegistry.GetContainer()
     .Register<HttpRestClient>(made: Parameters.Of.Type<string>(serviceKey: "webUrl"));
//给构造函数参数设置类型和名字 containerRegistry.GetContainer().RegisterInstance(@"http://localhost:5008/", serviceKey: "webUrl");
//apiurl就是这个基地址
 containerRegistry.Register<IToDoService, ToDoService>();

6.注入服务

在构造函数注入
image

7. 具体调用方法生成待办列表

在view model中

async void CreateToDoList()
{//先获取分页数据
    var todoResult = await service.GetAllAsync(new Shared.Parameters.QueryParameter()
    {
        PageIndex = 0,
        PageSize = 100,
    });
    if (todoResult.Status)//如果状态码对
    {
        ToDoDtos.Clear();
        foreach (var item in todoResult.Result.Items)
        {
            ToDoDtos.Add(item);
        }
    }
}

报错:反序列化的时候实体字段类型(api层实体对应dto层实体字段类型要一致)和返回对象(dto,数据库里面的)的字段类型对不上所以报错了

备忘录接口

主要看思路

  1. 创建接口继承通用服务接口
    image
  2. 创建服务类实现接口,并继承通用服务类
    image
  3. 注册
    image
  4. 注入服务并修改方法
    image
    image
posted @ 2023-10-10 11:07  huihui不会写代码  阅读(360)  评论(0)    收藏  举报