ASP.NET Core HttpClient使用http动词系列二

在这一节中我们介绍HTTP另外的几种请求方式:

  • POST

  • PUT

  • DELETE

  • PATCH

新增MVC项目命名为AspNetCore.HttpClientWithHttpVerb,在该项目中我们新建一个api作为服务器端,在当前项目的HomeController中使用HttpClient来请求该api

1.TodoItems api

我们使用EFCore作为ORM并将数据存储到内存中,在Model文件夹下新增TodoItems类和TodoContext类:

eb52168d87c645759a84ede070696e39.png

11cb1e015c09de67c0b720bc21f75b34.png

在Program类中新增EF Core相关服务:

93725a1c3b036f822bcd8aa7f5f15e1c.png

在Controllers文件夹下新增api命名为TodoItemsController并继承自ControllerBase

using AspNetCore.HttpClientWithHttpVerb.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Threading.Tasks;


namespace AspNetCore.HttpClientWithHttpVerb.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class TodoItemsController : ControllerBase
    {
        private readonly TodoContext _context;
        public TodoItemsController(TodoContext context)
        {
            _context = context;
        }
        public async Task<IEnumerable<TodoItem>> Get() =>
             await _context.TodoItems.AsNoTracking().ToListAsync();


        [HttpGet("{id}")]
        public async Task<ActionResult<TodoItem>> Get(long id)
        {
            var request = HttpContext.Request;
            var todoItem = await _context.TodoItems.FindAsync(id);
            if (todoItem == null)
            {
                return NotFound();
            }
            return todoItem;
        }
        [HttpPost]
        public async Task<IActionResult> Post(TodoItem todoItem)
        {
            var request = HttpContext.Request;
            _context.TodoItems.Add(todoItem);
            await _context.SaveChangesAsync();


            return RedirectToAction(nameof(Get), new { Id = todoItem.Id, todoItem });
        }
        [HttpPut("{id}")]
        public async Task<IActionResult> Put(long id, TodoItem todoItem)
        {
            var request = HttpContext.Request;
            if (todoItem.Id != id)
                return BadRequest();
            _context.Update(todoItem);
            await _context.SaveChangesAsync();
            return NoContent();
        }
        [HttpDelete("{id}")]
        public async Task<IActionResult> Delete(long id)
        {
            var request = HttpContext.Request;
            var todoItem = await _context.TodoItems.FindAsync(id);
            if (todoItem == null)
            {
                return NotFound();
            }
            _context.TodoItems.Remove(todoItem);
            await _context.SaveChangesAsync();
            return NoContent();
        }
    }
}

在这个类中我们定义常用的api包含增删改查

2.HttpClient客户端

我们使用类型化方式声明HttpClient,在启动类中配置HttpClient

f1012993483caa21c7ed1f5a2490279b.png

在Model文件夹下新增一个TodoClient类,在该类内部中使用构造函数中获取HttpClient,该类内部请求TodoItems api:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;


namespace AspNetCore.HttpClientWithHttpVerb.Models
{
    public class TodoClient
    {
        private static readonly JsonSerializerOptions _jsonSerializerOptions = new JsonSerializerOptions
        {
            IgnoreNullValues = true,
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase
        };
        private readonly HttpClient _httpClient;
        public TodoClient(HttpClient httpClient)
        {
            _httpClient = httpClient;
        }
        public async Task<IEnumerable<TodoItem>> GetItemsAsync()
        {
            using var httpReponse = await _httpClient.GetAsync("/api/TodoItems");
            httpReponse.EnsureSuccessStatusCode();
            var stream = await httpReponse.Content.ReadAsStreamAsync();
            return await JsonSerializer.DeserializeAsync<List<TodoItem>>(stream, _jsonSerializerOptions);
        }
        public async Task<TodoItem> GetItemAsync(long id)
        {
            using var httpResponse = await _httpClient.GetAsync($"/api/TodoItems/{id}");
            if (httpResponse.StatusCode == HttpStatusCode.NotFound)
                return null;
            httpResponse.EnsureSuccessStatusCode();
            var stream = await httpResponse.Content.ReadAsStreamAsync();
            return await JsonSerializer.DeserializeAsync<TodoItem>(stream, _jsonSerializerOptions);
        }
        public async Task CreateItemAsync(TodoItem todoItem)
        {
            var todoItemJson = new StringContent(
                JsonSerializer.Serialize(todoItem, _jsonSerializerOptions),
                System.Text.Encoding.UTF8,
                "application/json");
            using var httpResponse = await _httpClient.PostAsync("/api/TodoItems", todoItemJson);


            httpResponse.EnsureSuccessStatusCode();
        }
        public async Task SaveItemAsync(TodoItem todoItem)
        {
            var todoItemJson = new StringContent(
                JsonSerializer.Serialize(todoItem, _jsonSerializerOptions),
                System.Text.Encoding.UTF8,
                 "application/json"
            );
            using var httpResponse = await _httpClient.PutAsync($"/api/TodoItems/{todoItem.Id}", todoItemJson);
            httpResponse.EnsureSuccessStatusCode();
        }
        #region Delete Request
        public async Task DeleteItemAsync(long id)
        {
            using var httpResponse = await _httpClient.DeleteAsync($"/api/TodoItems/{id}");
            httpResponse.EnsureSuccessStatusCode();
        }
        #endregion
    }


}

在HomeController中通过调用HttpClient来请求api,并将请求的结果传给视图呈现:

feb786d0c33496da3f52b5963148503d.png

fa63f6e088bc5d699f59e45849a17034.png

源代码地址:

https://github.com/bingbing-gui/Asp.Net-Core-Skill/tree/master/Fundamentals/AspNetCore.HttpRequest/AspNetCore.HttpClientWithHttpVerb

参考文献

https://learn.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-8.0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值