这是对api执行http请求的好方法吗?

时间:2019-05-30 18:53:48

标签: c# asp.net-mvc

我正在学习如何使用第三方API,并想知道我所拥有的是否是对API实施HTTP请求的好方法。我创建了一个私有方法,该方法用于向前端显示信息,我这样做是为了避免将所有内容都放入GetResult()方法中。有更好的方法吗?

更新2

  public ActionResult Main()
        {
            return View();
        }

        [HttpPost]
        public ActionResult GetResult(int zipCode)
        {
            ApiController api = new ApiController();
            var weather = api.GetResult(zipCode);

            var tuple = new Tuple<OpenWeatherMap, RootObject>(new OpenWeatherMap(), new RootObject());

            return View("Main", tuple);
        }
 public async Task<Json.RootObject> GetResult(int zipCode)
        {
            const string apiKey = "";
            var client = new HttpClient();


            var response = await client.GetAsync("http://api.openweathermap.org/data/2.5/weather?zip=" +
                                                 zipCode + ",us&APPID=" + apiKey);
            response.EnsureSuccessStatusCode();
            var rootObj = new Json.RootObject();

            var responseBody = await response.Content.ReadAsStringAsync();

            var deserialize = JsonConvert.DeserializeObject<Json.RootObject>(responseBody);

            if (response.IsSuccessStatusCode)
            {
                rootObj.id = deserialize.id;
                rootObj.weather[0].description = deserialize.weather[0].description;
            }

            return rootObj;
        }

1 个答案:

答案 0 :(得分:1)

让您请求隐藏在Gateway后面的其他系统,并将有关外部API的所有详细信息保留在此处。 best practice还要在每个应用程序中使用一个HttpClient,因为它们有一个设计缺陷,在处置套接字后会保留在套​​接字上。

如果使用的是dotnet核心,则使用HttpClientFactory获取池化HttpClient的实例

在Global.asax中创建HttpClient

{
  "status": 405,
  "errors": [
    {
      "exception": "class org.springframework.web.HttpRequestMethodNotSupportedException",
      "systemId": "91224",
      "code": null,
      "systemName": "sys-name",
      "meta": null,
      "detail": "Request method 'POST' not supported",
      "time": "2019-05-30T15:49:10.021",
      "type": "S",
      "message": null,
      "url": "http://localhost:8080/.../my-end-point"
    }
  ]
}

天真的实现可能是

public class MvcApplication : System.Web.HttpApplication
{

    public static HttpClient HttpClient { get; set; }


    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        HttpClient = new HttpClient();
    }


    protected void Application_End()
    {
        if (HttpClient == null) return;

        HttpClient.Dispose();
    }
}

替换您的模型和您要连接的网址。

然后您的控制器可以保持清洁。

类似

public class ExternalGateway
{
    private readonly HttpClient _httpClient;

    public ExternalGateway(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }

    public async Task<SomeModel> GetSomeExternalResource(Uri uri)
    {
        var response = await _httpClient.GetAsync(uri.AbsoluteUri);

        // TODO: check status
        // do some conversion of the content to your model

        response.EnsureSuccessStatusCode();

        var content = await response.Content.ReadAsStringAsync();

        return JsonConvert.DeserializeObject<SomeModel>(content);
    }
}

public class SomeModel
{
    public string SomeProperty { get; set; }
}

这假定您将对视图使用强类型模型而不是ViewBag。