可移植类库HttpClient
本文关键字:HttpClient 类库 可移植 | 更新日期: 2023-09-27 18:10:25
对于我的一个项目,我想开发一个可以在不同平台(桌面,移动,表面等)上使用的库。因此我选择了可移植类库。
我正在开发一个类调用不同的API调用'使用HttpClient。我被困在如何调用方法,响应和工作周围。这是我的代码:-
public static async Task<JObject> ExecuteGet(string uri)
{
using (HttpClient client = new HttpClient())
{
// TODO - Send HTTP requests
HttpRequestMessage reqMsg = new HttpRequestMessage(HttpMethod.Get, uri);
reqMsg.Headers.Add(apiIdTag, apiIdKey);
reqMsg.Headers.Add(apiSecretTag, ApiSecret);
reqMsg.Headers.Add("Content-Type", "text/json");
reqMsg.Headers.Add("Accept", "application/json");
//response = await client.SendAsync(reqMsg);
//return response;
//if (response.IsSuccessStatusCode)
//{
string content = await response.Content.ReadAsStringAsync();
return (JObject.Parse(content));
//}
}
}
// Perform AGENT LOGIN Process
public static bool agentStatus() {
bool loginSuccess = false;
try
{
API_Utility.ExecuteGet("http://api.mintchat.com/agent/autoonline").Wait();
// ACCESS Response, JObject ???
}
catch
{
}
finally
{
}
与ExecuteGet一样,我也将创建ExecutePost。我的查询是从ExecuteGet,如果(1)我传递JObject解析时IsSuccessStatusCode只有,那么我怎么能知道任何其他错误或消息通知用户。(2)如果传递response,那么如何在这里赋值
response = API_Utility.ExecuteGet("http://api.mintchat.com/agent/autoonline").Wait();
给出错误。
处理这种情况的最好方法是什么?我需要调用多个API,不同的API会有不同的结果集。另外,您能否确认以这种方式设计并添加PCL参考,我将能够在多个项目中访问。
更新:-正如下面2个答案中提到的,我已经更新了我的代码。正如所提供的链接中提到的,我正在从其他项目中调用。这是我的代码:-
便携式类库:-
private static HttpRequestMessage getGetRequest(string url)
{
HttpRequestMessage reqMsg = new HttpRequestMessage(HttpMethod.Get, url);
reqMsg.Headers.Add(apiIdTag, apiIdKey);
reqMsg.Headers.Add(apiSecretTag, ApiSecret);
reqMsg.Headers.Add("Content-Type", "text/json");
reqMsg.Headers.Add("Accept", "application/json");
return reqMsg;
}
// Perform AGENT LOGIN Process
public static async Task<bool> agentStatus() {
bool loginSuccess = false;
HttpClient client = null;
HttpRequestMessage request = null;
try
{
client = new HttpClient();
request = getGetRequest("http://api.mintchat.com/agent/autoonline");
response = await client.SendAsync(request).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
string content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
JObject o = JObject.Parse(content);
bool stat = bool.Parse(o["status"].ToString());
///[MainAppDataObject sharedAppDataObject].authLogin.chatStatus = str;
o = null;
}
loginSuccess = true;
}
catch
{
}
finally
{
request = null;
client = null;
response = null;
}
return loginSuccess;
}
在另一个WPF项目中,在btn点击事件中,我这样调用它:-
private async void btnSignin_Click(object sender, RoutedEventArgs e)
{
/// Other code goes here
// ..........
agent = doLogin(emailid, encPswd);
if (agent != null)
{
//agent.OnlineStatus = getAgentStatus();
// Compile Error at this line
bool stat = await MintWinLib.Helpers.API_Utility.agentStatus();
...
我得到这4个错误:-
Error 1 Predefined type 'System.Runtime.CompilerServices.IAsyncStateMachine' is not defined or imported D:'...'MiveChat'CSC
Error 2 The type 'System.Threading.Tasks.Task`1<T0>' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Threading.Tasks, Version=1.5.11.0, Culture=neutral, PublicKeyToken=b03f5f7f89d50a3a'. D:'...'Login Form.xaml.cs 97 21
Error 3 Cannot find all types required by the 'async' modifier. Are you targeting the wrong framework version, or missing a reference to an assembly? D:'...'Login Form.xaml.cs 97 33
Error 4 Cannot find all types required by the 'async' modifier. Are you targeting the wrong framework version, or missing a reference to an assembly? D:'...'Login Form.xaml.cs 47 28
我试着只从PCL库添加System.Threading.Tasks,这给了7个不同的错误。我哪里做错了?如何使其工作?
请指点我一下。我花了很多时间来研究开发桌面应用程序库的最佳方法。Win Phone应用。任何帮助都是非常感激的。谢谢。
如果您在进行http调用时调用async
api,您还应该向用户公开该异步端点,而不是使用Task.Wait
阻止请求。
另外,在创建第三方库时,建议使用ConfigureAwait(false)
,以避免在调用代码试图访问Result
属性或Wait
方法时发生死锁。您还应该遵循指导原则,用Async
标记任何异步方法,因此该方法应该称为ExecuteStatusAsync
public static Task<bool> AgentStatusAsync()
{
bool loginSuccess = false;
try
{
// awaiting the task will unwrap it and return the JObject
var jObject = await API_Utility.ExecuteGet("http://api.mintchat.com/agent/autoonline").ConfigureAwait(false);
}
catch
{
}
}
And inside ExecuteGet
:
response = await client.SendAsync(reqMsg).ConfigureAwait(false);
string content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
如果IsSuccessStatusCode
为false,则可以向调用代码抛出异常以显示出错。要做到这一点,您可以使用HttpResponseMessage.EnsureSuccessStatusCode
,如果状态码!= 200 OK,它会抛出异常。
就我个人而言,如果ExecuteGet
是一个公共API方法,我绝对不会将其公开为JObject
,而是将其公开为强类型。
如果需要任务的结果,则需要使用Result
属性:
var obj = API_Utility.ExecuteGet("http://api.mintchat.com/agent/autoonline").Result;
然而,同步等待异步方法完成通常不是一个好主意,因为它可能导致死锁。更好的方法是await
方法:
var obj = await API_Utility.ExecuteGet("http://api.mintchat.com/agent/autoonline");
注意,您还需要使调用方法async
:
public static async Task<bool> agentStatus()
同步和异步代码不能很好地结合在一起,所以异步倾向于在整个代码库中传播。