ASP.NET Core HttpClient使用http动词系列二
内容提要
本节介绍了HTTP的POST、PUT、DELETE和PATCH请求方式。在AspNetCore.HttpClientWithHttpVerb项目中,使用HttpClient来请求api。新增了TodoItems api和TodoItemsController类,包含了常用的增删改查操作。使用类型化方式声明HttpClient,并在启动类中配置。在TodoClient类中使用HttpClient发送请求,包括获取所有项、获取单个项、创建项和更新项。在HomeController中调用HttpClient来请求api,并将结果传给视图呈现。
延伸解读
类型化HttpClient的依赖注入配置
文章采用类型化方式声明HttpClient,并在启动类中配置。这意味着TodoClient通过构造函数接收HttpClient实例,由依赖注入容器管理其生命周期。这种模式避免了手动创建HttpClient可能导致的套接字耗尽问题,同时使客户端配置(如基地址、超时)集中管理,便于测试和维护。
API控制器中的HTTP动词映射
TodoItemsController继承自ControllerBase,使用[HttpPost]、[HttpPut]、[HttpDelete]等特性将方法映射到对应的HTTP动词。POST用于创建资源并返回RedirectToAction指向新资源;PUT用于全量更新,要求URL中的id与实体id一致,否则返回BadRequest;DELETE用于删除,资源不存在时返回NotFound。这些状态码有助于客户端判断操作结果。
客户端序列化与错误处理策略
TodoClient使用System.Text.Json进行序列化,配置了IgnoreNullValues和CamelCase命名策略,以匹配API的JSON格式。每个请求后调用EnsureSuccessStatusCode,确保非成功状态码抛出异常。对于GetItemAsync,单独处理了NotFound状态码并返回null,使调用方能够区分资源不存在与其他错误。
内存数据库的适用场景与局限
示例使用EF Core将数据存储到内存中,这简化了演示环境,无需配置外部数据库。但内存数据库的数据在应用程序重启后会丢失,且不支持事务和并发控制等高级特性。因此,它仅适用于学习、测试或原型开发,生产环境应替换为持久化数据库。
Q&A
在ASP.NET Core中,如何使用HttpClient发送POST请求创建资源?
在TodoClient类中,使用HttpClient的PostAsync方法发送POST请求。首先将TodoItem对象序列化为JSON字符串,并创建StringContent,指定内容类型为application/json。然后调用PostAsync方法,传入请求URI和StringContent。最后调用EnsureSuccessStatusCode确保请求成功。
ASP.NET Core中如何配置类型化HttpClient?
在启动类(Program类)中,使用AddHttpClient方法注册类型化客户端。例如,services.AddHttpClient<TodoClient>(),这样TodoClient就可以通过构造函数注入HttpClient实例。
TodoItemsController中实现了哪些HTTP动词对应的操作?
TodoItemsController实现了GET(获取所有项和单个项)、POST(创建项)、PUT(更新项)和DELETE(删除项)操作,分别对应HttpClient的GetAsync、PostAsync、PutAsync和DeleteAsync方法。
在ASP.NET Core中,使用HttpClient发送PUT请求时需要注意什么?
发送PUT请求时,需要将更新后的对象序列化为JSON,并创建StringContent,指定内容类型为application/json。然后调用PutAsync方法,请求URI应包含要更新资源的ID(如/api/TodoItems/{id})。最后调用EnsureSuccessStatusCode确保请求成功。
如何在ASP.NET Core中处理HttpClient请求返回的404 NotFound响应?
在TodoClient的GetItemAsync方法中,首先检查httpResponse.StatusCode是否等于HttpStatusCode.NotFound,如果是则返回null;否则调用EnsureSuccessStatusCode确保请求成功,然后反序列化响应内容。
TodoClient类中如何反序列化JSON响应?
TodoClient使用System.Text.Json进行反序列化。首先从响应内容中读取流(ReadAsStreamAsync),然后使用JsonSerializer.DeserializeAsync方法,传入流和JsonSerializerOptions(配置了IgnoreNullValues和CamelCase命名策略)来反序列化为TodoItem或List<TodoItem>。