【发布时间】:2021-09-20 21:24:12
【问题描述】:
我无法在 Microsoft Dynamics 365 中使用 Twilio SDK(Twilio 库未安装在 Dynamics 中,并且无法在我的插件注册中包含 dll),因此我不得不使用 HttpClient 进行 http 发布。对 Twilio 的调用成功发生,因为 Twilio 能够向我发送一封验证电子邮件,但 PostAsync 之后的断点从未被命中,也没有捕获到异常。我需要从 PostAsync 捕获输出。我做错了什么?
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public class TwilioMessageInput
{
public string To { get; set; }
public string Channel { get; set; }
}
public class TwilioMessageOutput
{
public string Message { get; set; }
}
private void button1_Click(object sender, EventArgs e)
{
// https://www.twilio.com/docs/verify
// https://www.twilio.com/docs/verify/email
string url = "https://verify.twilio.com/v2/Services/VA********************************/Verifications/";
string authToken = "AC********************************:********************************"; //-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN
string email = "***************@************.com";
var formContent = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("To", email),
new KeyValuePair<string, string>("Channel", "email")
});
using (var client = new Rest(url))
{
var response = client.PostAsync<TwilioMessageOutput>(url, formContent, authToken).Result;
}
}
}
public class Rest : IDisposable
{
private readonly TimeSpan _timeout;
private HttpClient _httpClient;
private HttpClientHandler _httpClientHandler;
private readonly string _baseUrl;
private const string ClientUserAgent = "twillio-client-v1";
private const string MediaTypeJson = "application/json";
public Rest(string baseUrl, TimeSpan? timeout = null)
{
_baseUrl = NormalizeBaseUrl(baseUrl);
_timeout = timeout ?? TimeSpan.FromSeconds(90);
//_timeout = TimeSpan.FromSeconds(1);
}
private async Task<string> PostAsyncInternal(string url, FormUrlEncodedContent input, string authToken)
{
try
{
EnsureHttpClientCreated();
var byteArray = Encoding.ASCII.GetBytes(authToken);
_httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
using (var response = await _httpClient.PostAsync(url, input))
{
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
}
catch (Exception ex)
{
throw ex;
}
}
public async Task<TResult> PostAsync<TResult>(string url, FormUrlEncodedContent input, string authToken) where TResult : class, new()
{
var strResponse = await PostAsyncInternal(url, input, authToken);
return JsonConvert.DeserializeObject<TResult>(strResponse, new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
});
}
public void Dispose()
{
_httpClientHandler?.Dispose();
_httpClient?.Dispose();
}
private void CreateHttpClient()
{
_httpClientHandler = new HttpClientHandler
{
AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip
};
_httpClient = new HttpClient(_httpClientHandler, false)
{
Timeout = _timeout
};
_httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(ClientUserAgent);
if (!string.IsNullOrWhiteSpace(_baseUrl))
{
_httpClient.BaseAddress = new Uri(_baseUrl);
}
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypeJson));
}
private void EnsureHttpClientCreated()
{
if (_httpClient == null)
{
CreateHttpClient();
}
}
private static string ConvertToJsonString(object obj)
{
if (obj == null)
{
return string.Empty;
}
return JsonConvert.SerializeObject(obj, new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
});
}
private static string NormalizeBaseUrl(string url)
{
return url.EndsWith("/") ? url : url + "/";
}
}
【问题讨论】: