【发布时间】:2020-12-04 14:06:31
【问题描述】:
我有一个向供应商发布 HTTP 请求的过程,获取会话令牌,然后运行顺序 GET 请求。我得到一个没有太多输出的“连接错误”。如果我没有按顺序提交两者,辅助 GET 将返回响应,但由于第一个请求没有会话令牌而失败。它似乎都单独运行,但在一个接一个运行时失败。我应该可以重用实际上在网上看起来更好的“客户端”。我想知道它是否与任务和等待有关。任何建议都有帮助!
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
namespace actIntegration {
public class actApi {
// Static Encoura and mail variables.
public string username = "**********";
public string password = "**********";
public string email = "**********";
public string xApiKey = "**********";
public string sessionToken = "";
public string organizationUid = "";
/**
* Converts payload object to JSON string.
*
* @return string - Response from Encoura.
*/
public async Task<string> getActUploadFile() {
// Create the current client instance for Http requests.
using (HttpClient client = new HttpClient()) {
string response = string.Empty;
JObject responseData = new JObject();
var payload = new {
userName = username,
password = password,
acceptedTerms = true
};
// Convert JSON object to JSON string.
dynamic json = JsonConvert.SerializeObject(payload);
try {
response = await encouraLogin(client, json);
// Convert JSON response string back to a JSON object to parse and search for the token.
responseData = (JObject)JsonConvert.DeserializeObject(response);
sessionToken = responseData["sessionToken"].Value<string>();
organizationUid = responseData["user"]["organizations"][0]["uid"].Value<string>();
} catch (Exception e) {
// Capture additional data for the sendErrorEmail() function.
string data = "ERROR: " + response.ToString();
// Send error information to email function.
sendErrorEmail(e, data);
}
try {
response = await getExportList(client);
// Convert JSON export response string back to a JSON object to parse and search for the exports download URL.
responseData = (JObject)JsonConvert.DeserializeObject(response);
} catch (Exception e) {
// Capture additional data for the sendErrorEmail() function.
string data = "ERROR: " + response.ToString();
// Send error information to email function.
sendErrorEmail(e, data);
}
return responseData.ToString();
}
}
/**
* Get token via API request.
* See the web api documentation at https://helpcenter.encoura.org/hc/en-us/articles/360037582012-API-Documentation-for-Automating-Downloads-of-ACT-Score-Reports-
*
* @param json - JSON key/value collection string used for sending data through to the Encoura API as settings/options.
*
* @return string - Response from Encoura Authorization API POST.
*/
public async Task<string> encouraLogin(HttpClient client, dynamic json) {
string response = string.Empty;
try {
// Geth Authorization via supplied arguments.
response = await getAuthorization(client, json);
} catch (Exception e) {
// Capture additional data for the sendErrorEmail() function.
string data = "ERROR:" + response.ToString();
// Send error information to email function.
sendErrorEmail(e, data);
}
return response;
}
/**
* Appends the bearer authorization token to the current HttpClient request.
*
* @param client - Current class instance used for sending and receiving HTTP request/responses.
* @param json - Payload fro authentication.
*
* @return N/A - Adds the authorization bearer token to the header of the current client.
*/
public async Task<string> getAuthorization(HttpClient client, dynamic json) {
HttpResponseMessage response = null;
string sResponse = string.Empty;
try {
// Add application/json, x-api-key to the header of the current client.
client.DefaultRequestHeaders.Add("x-api-key", xApiKey);
// Add application/json to the header of the current client.
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// Convert object to HttpContent for POST.
StringContent content = new StringContent(json, Encoding.UTF8, "application/json");
// Post authorization information to the client.
response = await client.PostAsync("https://api.datalab.nrccua.org/v1/login", content);
response.EnsureSuccessStatusCode();
// Client response.
sResponse = await response.Content.ReadAsStringAsync();
} catch (Exception e) {
// Capture additional data for the sendErrorEmail() function.
string data = "ERROR - StatusCode:" + response.StatusCode + ", ReasonPhrase: " + response.ReasonPhrase + ", Response content = " + sResponse;
// Send error information to email function.
sendErrorEmail(e, data);
}
return sResponse;
}
/**
* Get export list via API request.
*
* @return string - Response from Encoura.
*/
public async Task<string> getExportList(HttpClient client) {
HttpResponseMessage response = null;
string sResponse = string.Empty;
try {
// Add application/json, x-api-key, JWT and Organization to the header of the current client.
client.DefaultRequestHeaders.Add("x-api-key", xApiKey);
client.DefaultRequestHeaders.Add("Authorization", "JWT " + sessionToken);
client.DefaultRequestHeaders.Add("Organization", organizationUid);
// Add application/json to the header of the current client.
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// Get export information from encoura.
UriBuilder builder = new UriBuilder("https://api.datalab.nrccua.org/v1/datacenter/exports");
builder.Query = "productKey=score-reporter&status=NotDelivered";
response = await client.GetAsync(builder.Uri);
//response = await client.GetAsync("https://api.datalab.nrccua.org/v1/datacenter/exports?productKey=score-reporter&status=NotDelivered");
response.EnsureSuccessStatusCode();
// Client response.
sResponse = await response.Content.ReadAsStringAsync();
} catch (Exception e) {
// Capture additional data for the sendErrorEmail() function.
string data = "ERROR - StatusCode:" + response.StatusCode + ", ReasonPhrase: " + response.ReasonPhrase + ", Response content = " + sResponse;
// Send error information to email function.
sendErrorEmail(e, data);
return data;
}
return sResponse;
}
/**
* Error function which emails Exception information and details of the error to the ITS-Process@usd.edu mailbox.
*
* @param e - Exception information passed to the function.
* @param data - Additional data captured for output.
*
* @return N/A void
*/
public void sendErrorEmail(Exception e, string additionalData = "No additoinal data supplied.") {
System.Net.Mail.MailMessage o = new System.Net.Mail.MailMessage(
"**********",
"**********; **********",
"Error - Encoura Connection",
"Data: \n" + e.Data + "\n\n" +
"HelpLink: \n" + e.HelpLink + "\n\n" +
"HResult: \n" + e.HResult + "\n\n" +
"InnerException: \n" + e.InnerException + "\n\n" +
"Message: \n" + e.Message + "\n\n" +
"Source: \n" + e.Source + "\n\n" +
"StackTrace: \n" + e.StackTrace + "\n\n" +
"TargetSite: \n" + e.TargetSite + "\n\n" +
"Additional Data: \n" + additionalData
);
System.Net.Mail.SmtpClient smtpobj = new System.Net.Mail.SmtpClient("**********", 25);
smtpobj.EnableSsl = false;
smtpobj.Send(o);
}
}
}
【问题讨论】:
-
服务器可能拒绝来自同一用户的第二个连接。看起来您有一个 using 块,应该在最后处理请求。但是你有一个异步块,所以第二个块与第一个块并行运行。我会尝试删除异步。
-
@jdweng 我错过了在他的 getActUploadFile 方法中并行运行的代码。你能解释一下你认为它在哪里并行运行吗?
-
您确定登录和身份验证不只是失败吗?您正在吃登录失败的异常。
-
你认为 ASYNC 有什么作用?
-
@jdweng 你觉得
await是做什么的? :)
标签: c# api post get httpclient