代码之家  ›  专栏  ›  技术社区  ›  user616076

如何从中的API访问数据。网芯

  •  0
  • user616076  · 技术社区  · 7 年前

    我没有和你一起工作过。Net核心之前,但对MVC和实体框架有很多经验。我的项目有四个不同的文件夹: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();
        }
    

    我被告知,如果调用这个GET方法,它将返回一个数据对象。如何从WEB文件夹中的HomeController调用API文件夹中的此方法?

    0 回复  |  直到 7 年前
        1
  •  2
  •   Chris Pratt    7 年前

    首先,在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);
    }
    

    这是这里快速而肮脏的代码。你应该考虑改进的事情:

    1. 为您的服务类使用一个接口,即。 IReferenceDataService .这将使测试更容易。在里面 配置服务 :

      services.AddHttpClient<IReferenceDataService, ReferenceDataService>(...);
      

      然后,注射 IReferenceDataService 相反

    2. 您可以而且应该将Polly扩展与 AddHttpClient 支持重试和异常处理策略。至少,你肯定想补充一点 AddTransientHttpErrorPolicy :

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

      这将处理暂时性错误,例如由于API重新启动或其他原因而暂时无法连接到API。您可以在 docs .

    3. 您应该使用单独的DTO类。为了简洁起见,我刚刚使用了(假定的)实体类 ReferenceData 。相反,您应该始终使用定制的DTO类,这些类只保存您需要通过API提供的数据片段。通过这种方式,您可以控制序列化以及自定义验证方案,而不会与实体类发生的情况发生冲突。此外,web项目只需要知道 ReferenceDataDTO (或其他什么),这意味着你可以在API和web项目之间与DTO共享一个库,并将DAL完全排除在web项目之外。