- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个旧版本的 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; }
}
}
然后我创建了自己的 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;
}
}
}
然后在我的 ASP.NET Controller 操作中,我这样做:
public class MyController : Controller
{
private static readonly MyApiClient _apiClient = new MyApiClient ();
public ActionResult ApiTest()
{
var data = _apiClient.GetSomeData().Wait();
}
}
知道我的错误在哪里吗?
更新:这种简单的方法效果很好:
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;
}
}
最佳答案
如前所述,没有使用依赖注入(inject),因此从技术上讲,不需要在这些东西已经初始化的地方使用组合根。
如果不需要在启动时实际初始化客户端,您可以考虑使用惰性单例方法。
一个例子
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; }
}
}
Lazy<HttpClient>
的工厂代表如果客户端需要额外的设置,可以变得更复杂。
在需要客户的地方调用服务
var client = HttpClientAccessor.HttpClient;
var response = await client.GetStringAsync("{url}");
客户端将在第一次使用时初始化,您将在后续调用该实例时获得相同的实例。
如在您的 Controller 中使用的那样,您将异步调用与阻塞调用行混合在一起 .Wait()
或 .Result
.这可能会导致死锁,应该避免。
public class MyController : Controller {
private static readonly MyApiClient _apiClient = new MyApiClient ();
public async Task<ActionResult> ApiTest() {
var data = await _apiClient.GetSomeData();
//...
}
}
代码应该始终是异步的。
关于c# - 在没有启动的情况下在旧的 ASP.NET MVC 应用程序中创建 HttpClient,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49621741/
我是 Java 新手,这是我的代码, if( a.name == b.name && a.displayname == b.displayname && a.linknam
在下面的场景中,我有一个 bool 值。根据结果,我调用完全相同的函数,唯一的区别是参数的数量。 var myBoolean = ... if (myBoolean) { retrieve
我是一名研究 C++ 的 C 开发人员: 我是否正确理解如果我抛出异常然后堆栈将展开直到找到第一个异常处理程序?是否可以在不展开的情况下在任何 throw 上打开调试器(即不离开声明它的范围或任何更高
在修复庞大代码库中的错误时,我观察到一个奇怪的情况,其中引用的动态类型从原始 Derived 类型更改为 Base 类型!我提供了最少的代码来解释问题: struct Base { // some
我正在尝试用 C# 扩展给定的代码,但由于缺乏编程经验,我有点陷入困境。 使用 Visual Studio 社区,我尝试通过控制台读出 CPU 核心温度。该代码使用开关/外壳来查找传感器的特定名称(即
这可能是一个哲学问题。 假设您正在向页面发出 AJAX 请求(这是使用 Prototype): new Ajax.Request('target.asp', { method:"post", pa
我有以下 HTML 代码,我无法在所有浏览器中正常工作: 我试图在移动到
我对 Swift 很陌生。我如何从 addPin 函数中检索注释并能够在我的 addLocation 操作 (buttonPressed) 中使用它。我正在尝试使用压力触摸在 map 上添加图钉,在两
我设置了一个详细 View ,我是否有几个 Nib 文件根据在 Root View Controller 的表中选择的项目来加载。 我发现,对于 Nibs 的类,永远不会调用 viewDidUnloa
我需要动态访问 json 文件并使用以下代码。在本例中,“bpicsel”和“temp”是变量。最终结果类似于“data[0].extit1” var title="data["+bpicsel+"]
我需要使用第三方 WCF 服务。我已经在我的证书存储中配置了所需的证书,但是在调用 WCF 服务时出现以下异常。 向 https://XXXX.com/AHSharedServices/Custome
在几个 SO 答案(1、2)中,建议如果存在冲突则不应触发 INSERT 触发器,ON CONFLICT DO NOTHING 在触发语句中。也许我理解错了,但在我的实验中似乎并非如此。 这是我的 S
如果进行修改,则会给出org.hibernate.NonUniqueObjectException。在我的 BidderBO 类(class)中 @Override @Transactional(pr
我使用 indexOf() 方法来精细地查找数组中的对象。 直到此刻我查了一些资料,发现代码应该无法正常工作。 我在reducer中尝试了上面的代码,它成功了 let tmp = state.find
假设我有以下表格: CREATE TABLE Game ( GameID INT UNSIGNED NOT NULL, GameType TINYINT UNSIGNED NOT NU
代码: Alamofire.request(URL(string: imageUrl)!).downloadProgress(closure: { (progress) in
我是一名优秀的程序员,十分优秀!