我有一个流程,将 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 [email protected] 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 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 {
// Create the current client instance for Http requests.
static HttpClient client = new HttpClient();
// Static Encoura and mail variables.
public string username = "**********";
public string password = "**********";
public string email = "**********";
public string xApiKey = "**********";
/**
* Converts payload object to JSON string.
*
* @return string - Response from Encoura.
*/
public async Task<string> getActUploadFile() {
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 getExport(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> getExport(dynamic json) {
HttpResponseMessage response = null;
string sResponse = string.Empty;
JObject responseData = new JObject();
try {
/* Authorization Request */
// Add 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);
// Validate POST response success.
response.EnsureSuccessStatusCode();
// Client response.
sResponse = await response.Content.ReadAsStringAsync();
// Deserialize Object to get response data for sequential request.
responseData = (JObject)JsonConvert.DeserializeObject(sResponse);
/* Get Export(s) List Request */
// Add Authorization and Organization from previous request to the header of the current client.
client.DefaultRequestHeaders.Add("Authorization", "JWT " + responseData["sessionToken"].Value<string>());
client.DefaultRequestHeaders.Add("Organization", responseData["user"]["organizations"][0]["uid"].Value<string>());
// Build GET request and 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);
// Validate GET response success.
if (response.IsSuccessStatusCode) {
// 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;
}
/**
* Error function which emails Exception information and details of the error to the [email protected] 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);
}
}
}