Sam*_*Sam 6 c# asp.net asp.net-mvc asp.net-mvc-4
我有一个旧版本的ASP.NET MVC应用程序没有Startup.cs.我想实现一种干净的方式,HttpClient以便我可以使用我的API调用第三方.
这是我到目前为止基于我收到的关于这个问题的一些想法/建议所做的.问题是,当我进行API调用时,它无处可去.我把它放在一个try catch但我甚至没有得到例外.API提供商告诉我他们没有看到搜索参数.
首先,我HttpClientAccessor为延迟加载创建了这个.
public static class HttpClientAccessor
{
public static Func<HttpClient> ValueFactory = () =>
{
var client = new HttpClient();
client.BaseAddress = new Uri("https://apiUrl.com");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.TryAddWithoutValidation("APIAccessToken", "token1");
client.DefaultRequestHeaders.TryAddWithoutValidation("UserToken", "token2");
return client;
};
private static Lazy<HttpClient> client = new Lazy<HttpClient>(ValueFactory);
public static HttpClient HttpClient
{
get { return client.Value; }
}
}
Run Code Online (Sandbox Code Playgroud)
然后我创建了一个自己的API客户端,以便我可以在一个地方使用API调用函数,如下所示:
public class MyApiClient
{
public async Task GetSomeData()
{
var client = HttpClientAccessor.HttpClient;
try
{
var result = await client.GetStringAsync("somedata/search?text=test");
var output = JObject.Parse(result);
}
catch(Exception e)
{
var error = e.Message;
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后在我的ASP.NET控制器操作中,我这样做:
public class MyController : Controller
{
private static readonly MyApiClient _apiClient = new MyApiClient ();
public ActionResult ApiTest()
{
var data = _apiClient.GetSomeData().Wait();
}
}
Run Code Online (Sandbox Code Playgroud)
知道我的错误在哪里?
更新:这个简单的方法工作正常:
public class MyController : Controller
{
private static readonly HttpClient _client = new HttpClient();
public ActionResult ApiTest()
{
_client.BaseAddress = new Uri("https://apiUrl.com");
_client.DefaultRequestHeaders.Accept.Clear();
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
_client.DefaultRequestHeaders.TryAddWithoutValidation("APIAccessToken", "token1");
_client.DefaultRequestHeaders.TryAddWithoutValidation("UserToken", "token2");
var response = _client.GetStringAsync("somedata/search?text=test").Result;
}
}
Run Code Online (Sandbox Code Playgroud)
如上所述,依赖注入没有被利用,因此从技术上讲,不需要组合根,这些东西将被初始化.
如果在启动时无需实际初始化客户端,则可以考虑使用Lazy单例方法.
一个例子
public static class HttpClientAccessor {
public static Func<HttpClient> ValueFactory = () => {
var client = new HttpClient();
client.BaseAddress = new Uri("https://apiUrl.com");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.TryAddWithoutValidation("APIAccessToken", "token1");
client.DefaultRequestHeaders.TryAddWithoutValidation("UserToken", "token2");
return client;
};
private static Lazy<HttpClient> client = new Lazy<HttpClient>(ValueFactory);
public static HttpClient HttpClient {
get { return client.Value; }
}
}
Run Code Online (Sandbox Code Playgroud)
Lazy<HttpClient>如果客户端需要其他设置,则可以使工厂代表更复杂.
无论客户需要哪个地方,您都可以致电该服务
var client = HttpClientAccessor.HttpClient;
var response = await client.GetStringAsync("{url}");
Run Code Online (Sandbox Code Playgroud)
客户端将在首次使用时初始化,您将在后续的实例调用中获得相同的实例.
在控制器中使用时,您将异步调用与阻塞调用行.Wait()或.Result.这可能导致死锁,应该避免.
public class MyController : Controller {
private static readonly MyApiClient _apiClient = new MyApiClient ();
public async Task<ActionResult> ApiTest() {
var data = await _apiClient.GetSomeData();
//...
}
}
Run Code Online (Sandbox Code Playgroud)
代码应该始终是异步的.
| 归档时间: |
|
| 查看次数: |
870 次 |
| 最近记录: |