如何在C#中将查询字符串添加到HttpClient.BaseAdress?

时间:2019-06-07 00:43:14

标签: c# httpclient

我正在尝试将查询字符串传递到BaseAddress,但是它不能识别引号“?”。

引号引起了URI

首先,我创建我的BaseAddress

httpClient.BaseAddress = new Uri($"https://api.openweathermap.org/data/2.5/weather?appid={Key}/"); 

然后我调用GetAsync方法,尝试添加另一个参数

using (var response = await ApiHelper.httpClient.GetAsync("&q=mexico"))....

这是代码正在调用的URI

https://api.openweathermap.org/data/2.5/&q=mexico

2 个答案:

答案 0 :(得分:2)

如果您需要将API密钥应用于每个单个请求,我很想使用DelegatingHandler

private class KeyHandler : DelegatingHandler
{
    private readonly string _escapedKey;

    public KeyHandler(string key)  : this(new HttpClientHandler(), key)
    {
    }

    public KeyHandler(HttpMessageHandler innerHandler, string key) : base(innerHandler)
    {
        // escape the key since it might contain invalid characters
        _escapedKey = Uri.EscapeDataString(key);
    }

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        // we'll use the UriBuilder to parse and modify the url
        var uriBuilder = new UriBuilder(request.RequestUri);

        // when the query string is empty, we simply want to set the appid query parameter
        if (string.IsNullOrEmpty(uriBuilder.Query))
        {
            uriBuilder.Query = $"appid={_escapedKey}";
        }
        // otherwise we want to append it
        else
        {
            uriBuilder.Query = $"{uriBuilder.Query}&appid={_escapedKey}";
        }
        // replace the uri in the request object
        request.RequestUri = uriBuilder.Uri;
        // make the request as normal
        return base.SendAsync(request, cancellationToken);
    }
}

用法:

httpClient = new HttpClient(new KeyHandler(Key));
httpClient.BaseAddress = new Uri($"https://api.openweathermap.org/data/2.5/weather"); 

// since the logic of adding/appending the appid is done based on what's in
// the query string, you can simply write `?q=mexico` here, instead of `&q=mexico`
using (var response = await ApiHelper.httpClient.GetAsync("?q=mexico"))

**注意:如果使用的是ASP.NET Core,则应调用services.AddHttpClient(),然后使用IHttpHandlerFactoryKeyHandler生成内部处理程序。

答案 1 :(得分:0)

这是我的解决方法:

Http客户端展示:

namespace StocksApi2.httpClients
{
    public interface IAlphavantageClient
    {
        Task<string> GetSymboleDetailes(string queryToAppend);
    }

    public class AlphavantageClient : IAlphavantageClient
    {
        private readonly HttpClient _client;

        public AlphavantageClient(HttpClient httpClient)
        {
            httpClient.BaseAddress = new Uri("https://www.alphavantage.co/query?apikey=<REPLACE WITH YOUR TOKEN>&");
            httpClient.DefaultRequestHeaders.Add("Accept", "application/json; charset=utf-8");
            httpClient.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");

            _client = httpClient;
        }

        public async Task<string> GetSymboleDetailes(string queryToAppend)
        {
            _client.BaseAddress = new Uri(_client.BaseAddress + queryToAppend);
            return await _client.GetStringAsync("");
        }
    }
}

控制器:

namespace StocksApi2.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class SymbolDetailsController : ControllerBase
    {
        private readonly IAlphavantageClient _client;

        public SymbolDetailsController(IAlphavantageClient client)
        {
            _client = client;
        }


        [HttpGet]
        public async Task<ActionResult> Get([FromQuery]string function = "TIME_SERIES_INTRADAY",
            [FromQuery]string symbol = "MSFT", [FromQuery]string interval = "5min")
        {

            try {
                string query = $"function={function}&symbol={symbol}&interval={interval}";
                string result = await _client.GetSymboleDetailes(query);
                return Ok(result);
            }catch(Exception e)
            {
                return NotFound("Error: " + e);
            }

        }
    }
}

并在ConfigureServices内的Startup.cs中:

  services.AddHttpClient();
  services.AddHttpClient<IAlphavantageClient, AlphavantageClient>();