【问题标题】:Best way to handle HttpClient inside Model class in C#在 C# 中的 Model 类中处理 HttpClient 的最佳方法
【发布时间】:2020-09-12 18:03:49
【问题描述】:

我有一个模型。它有一个名为country 的属性。我需要通过 3rd 方服务验证此属性,即国家/地区是否有效

我可以这么想:

  1. 我应该在模型构造函数中注入 HttpClient 并在模型本身中调用 3rd 方服务吗?
  2. 我是否应该创建另一个服务来调用第 3 方服务并将另一个服务注入我的模型中?
  3. 有没有更好的方法来做到这一点?

【问题讨论】:

  • 将外部服务 URL 存储在配置中,并使用 DI 将 IConfiguration 传递给模型类。然后使用 HttpClient 与服务交互并执行验证。由于外部服务提供的数据属于查找类,所以我使用 IMemCache 来缓存数据,这样可以避免对外部服务的多次调用。更好的解决方案是将这种外部服务交互移动到代理类并将代理类注入模型,从而保持逻辑分离和可重用。
  • 您确定要对模型进行自我验证吗?我建议使用像FluentValidation 这样的库来执行验证,然后有单独的验证类。至于HttpClient:使用HttpClientFactory,将IHttpMessageHandlerFactory注入你的验证器并从中构造Httpclient
  • 验证是为了确认哪些国家目前可以与第三方 API 一起使用,还是只是为了检查国家代码是否有效?对于后者,我使用从 JSON 配置加载的国家代码数组。
  • 有点,虽然我建议使用HttpClientFactory,因为它旨在缓解因每次需要创建新客户端而导致的套接字耗尽,并且还可以缓解因使用单个 HttpClient。
  • 这解决了我的问题。请添加为答案

标签: c# .net validation asp.net-core .net-core


【解决方案1】:

您可以像任何其他可用的开箱即用验证器([Required]、[MaxLength]、[Range] 等)一样实施自定义模型验证。我将假设您正在使用某种类型的 ASP.net MVC 框架或核心(ApiController、Controller 等)。如果您需要自定义验证,例如 MyModel.Country,您可以使用自定义验证器属性来装饰模型的“Country”属性。您应该避免在模型中使用业务逻辑代码,例如验证,因为模型通常用于保存数据。

创建自定义验证器来验证 Country 属性。参考如何自定义模型验证。 https://docs.microsoft.com/en-us/aspnet/core/mvc/models/validation?view=aspnetcore-2.2#custom-attributes

public ValidateCountryAttribute:ValidationAttribute{

   protected override ValidationResult IsValid(object value, ValidationContext 
                                              validationContext)
   {
         string countryPropertyValue = (string)value;
         //Validate your country
         if (!ValidCountry(countryPropertyValue){
              return new ValidationResult("Country is not valid");
         }         


        //Return Validation.Success
        return ValidationResult.Success;
    }
    private bool ValidCountry(string countryName){
      //code to validate against 3rd party goes here.

      return true;
    }
 }

在你的模型类上:

public class MyModel{

 [ValidateCountry]
 public string Country{get;set;}

}

当您在控制器的方法中收到 MyModel 时,您调用 ModelState.IsValid 来确定您收到的 MyModel 实例是否有效。

public class MyController:Controller{

    public void Post(MyModel model){

      if (!ModelState.IsValid){
       //MyModel has invalid country, do something....

      }
    }

}

采用这种方法的好处是,如果您需要国家/地区验证,现在可以将 ValidateCountryAttribute 放在任何模型类的属性上。这种方法可以更轻松地重用并将验证业务逻辑排除在模型之外。

【讨论】:

    猜你喜欢
    • 2013-04-17
    • 2017-01-20
    • 2011-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-09
    相关资源
    最近更新 更多