api - 如何从 .Net Core 中的 API 访问数据
问题描述
我以前没有使用过 .Net Core,但在 MVC 和 Entity Framework 方面有很多经验。我的项目有四个不同的文件夹,API、DTO、Repository 和 WEB。DTO 文件夹有许多适合数据模型的模型文件。API 文件夹有一个名为 ReferenceDataController 的控制器文件,如下所示
[Route("api/[controller]")]
[ApiController]
public class ReferenceDataController : ControllerBase
{
private readonly IReferenceDataRepository _repository;
public ReferenceDataController(IReferenceDataRepository repository)
{
_repository = repository;
}
// GET api/values
[HttpGet]
public ActionResult<ReferenceData> GetReferenceData()
{
return _repository.GetReferenceData();
}
有人告诉我,如果我调用这个 GET 方法,它将返回一个数据对象。如何从我的 WEB 文件夹中的 HomeController 中的 API 文件夹中调用此方法?
解决方案
首先,在您的 Web 项目中,您需要进行一些设置。添加如下类:
public class ReferenceDataService
{
private readonly HttpClient _httpClient;
public ReferenceDataService(HttpClient httpClient)
{
_httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
}
public async Task<List<ReferenceData>> GetReferenceDataAsync(CancellationToken cancellationToken = default)
{
using (var response = await _httpClient.GetAsync("/api/referencedata", cancellationToken))
{
if (response.IsSuccessStatusCode())
{
return await response.Content.ReadAsAsync<List<ReferenceData>>();
}
return null;
}
}
}
然后,在ConfigureServices
中Startup.cs
:
services.AddHttpClient<ReferenceDataService>(c =>
{
c.BaseAddress = new Uri("https://api.example.com");
// Use the actual URL for your API here. You also probably want to get this
// from `Configuration` rather than hard-coding it.
});
最后,注入ReferenceDataService
你的HomeController
:
public class HomeController : Controller
{
private readonly ReferenceDataService _referenceDataService;
public HomeController(ReferenceDataService referenceDataService)
{
_referenceDataService = referenceDataService ?? throw new ArgumentNullException(nameof(referenceDataService));
}
// In your action(s):
// var data = await _referenceDataService.GetReferenceDataAsync(HttpContext.RequestAborted);
}
这是这里快速而肮脏的代码。您应该考虑改进的事项:
为您的服务类使用接口,即
IReferenceDataService
. 这将使测试更容易。在ConfigureServices
:services.AddHttpClient<IReferenceDataService, ReferenceDataService>(...);
IReferenceDataService
然后,改为注入。您可以并且应该使用 Polly 扩展
AddHttpClient
来支持重试和异常处理策略。至少,您肯定要添加AddTransientHttpErrorPolicy
:services.AddHttpClient<ReferenceDataService>(...) .AddTransientHttpErrorPolicy(builder => builder.WaitAndRetryAsync(new[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(10) }));
这将处理暂时性错误,例如由于重新启动或其他原因而暂时无法连接到 API。您可以在文档中找到更多信息和更高级的配置可能性。
您应该使用单独的 DTO 类。为简洁起见,我只是使用了您的(假定的)实体类
ReferenceData
。相反,您应该始终使用定制的 DTO 类,这些类只包含您需要通过 API 获得的数据片段。这样,您可以控制诸如序列化以及自定义验证方案之类的事情,而不会与您的实体类发生的事情发生冲突。此外,Web 项目只需要了解ReferenceDataDTO
(或其他),这意味着您可以在 API 和 Web 项目之间与您的 DTO 共享一个库,并将您的 DAL 完全排除在您的 Web 项目之外。
推荐阅读
- python - Python更快的方法来取N维数组的对数
- javascript - 转义文本的效果。如何扭转它?
- node.js - Angular CanActivate Guard 错误
- javascript - Vuejs TypeError:无法读取未定义的属性“占位符”
- google-cloud-platform - 在 GCP 中更新 globalForwardingRules
- python - python BaseHTTPRequestHandler 和用于打开文件的本地 http 服务器目录
- oracle - Oracle 11g 子查询中缺少表达式
- php - HTML 和 Php 表单未将数据插入或更新到 MySQL
- c - 检查答案是否正确到小数点后 7 位
- python - 如何擦除在 PIL/Pillow 上创建的图像?