如何从.NETCore中的API访问数据

如何从.NETCore中的API访问数据,api,asp.net-core,visual-studio-2017,dbcontext,dto,Api,Asp.net Core,Visual Studio 2017,Dbcontext,Dto,我以前没有使用过.NETCore,但在MVC和EntityFramework方面有很多经验。我的项目有四个不同的文件夹:API、DTO、存储库和WEB。DTO文件夹有许多适合数据模型的模型文件。API文件夹有一个名为ReferenceDataController的控制器文件,如下所示 [Route("api/[controller]")] [ApiController] public class ReferenceDataController : ControllerBase { pri

我以前没有使用过.NETCore,但在MVC和EntityFramework方面有很多经验。我的项目有四个不同的文件夹:API、DTO、存储库和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();
    }
[路由(“api/[控制器]”)]
[ApiController]
公共类引用的数据控制器:ControllerBase
{
专用只读IReferenceDataRepository存储库;
公共引用数据控制器(iReferenceData存储库)
{
_存储库=存储库;
}
//获取api/值
[HttpGet]
公共操作结果GetReferenceData()
{
返回_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;
        }
    }
}
最后,将
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>(...);
    
    这将处理暂时性错误,例如由于API重新启动或其他原因而暂时无法连接到API。您可以在网站上找到更多信息和更高级的配置可能性

  • 您应该使用单独的DTO类。为简洁起见,我刚刚使用了您的(假定)实体类
    ReferenceData
    。相反,您应该始终使用自定义的DTO类,这些类只包含通过API需要提供的数据片段。这样,您可以控制序列化以及自定义验证方案等内容,而不会与实体类发生的情况相冲突。此外web项目只需要了解
    referencedatato
    (或任何内容),这意味着您可以在API和web项目之间与DTO共享一个库,并将DAL完全排除在web项目之外

  • services.AddHttpClient<IReferenceDataService, ReferenceDataService>(...);
    
    services.AddHttpClient<ReferenceDataService>(...)
        .AddTransientHttpErrorPolicy(builder => builder.WaitAndRetryAsync(new[]
        {
            TimeSpan.FromSeconds(1),
            TimeSpan.FromSeconds(5),
            TimeSpan.FromSeconds(10)
        }));