We have multiple EpiServer sites where we are adding the ability to post JSON to a site monitoring API. I was able to get the JSON posts successfully working on our EpiServer CMS version 8.0.0 sites, but encountered problems with CMS versions 8.8.1 and higher.
Below is what our successful working code looks like.
private async Task SendMaintenanceEvent(object maintenanceEvent)
{
string endpoint = "https://OurEndpointURL.com/omitted/";
string endpointDirectory = "target";
// Provide basic authorization. Credentials must be base-64 encoded to be recognized.
string credentials = "AuthCredentialsOmitted";
string credentialsBase64 = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(credentials));
// Convert the maintenanceEvent object to consumable JSON.
string maintenanceEventJson = System.Web.Helpers.Json.Encode(maintenanceEvent);
StringContent content = new StringContent(maintenanceEventJson, Encoding.UTF8, "application/json");
using (HttpClient httpClient = new HttpClient())
{
httpClient.BaseAddress = new Uri(endpoint);
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentialsBase64);
HttpResponseMessage response = await httpClient.PostAsJsonAsync(endpointDirectory, content);
if (!response.IsSuccessStatusCode)
{
throw new System.Exception("Error sending maintenance event.");
}
}
}
The above method depends on a couple of using statements are also in this class.
using System.Net.Http;
using System.Net.Http.Headers;
The above succeeds in our EpiServer CMS 8.0.0 solutions. But when we port the same code over to one of the higher CMS versions, the posts get stuck at this line:
HttpResponseMessage response = await httpClient.PostAsJsonAsync(access.EndpointDirectory, content);
By "gets stuck" I mean the Visual Studio debugger stops on that line and never proceeds to the following line.
Researching this, I found a suggestion to use PostAsync instead of PostAsJsonAsync. So here is one of my attempts on an EpiServer 9 solution. But this ends up posting as text/plain instead of as application/json.
private async Task SendMaintenanceEvent(object maintenanceEvent)
{
string endpointAddress = "https://OurEndpointURL.com/omitted/";
string endpointDirectory = "target";
// Provide basic authorization. Credentials must be base-64 encoded to be recognized.
string credentials = "AuthCredentialsOmitted";
string credentialsBase64 = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(credentials));
// Convert the maintenanceEvent object to consumable JSON.
//string maintenanceEventToPost = System.Web.Helpers.Json.Encode(maintenanceEvent);
//StringContent stringContent = new StringContent(maintenanceEventToPost, Encoding.UTF8, "application/json");
string jsonMaintenanceEvent = JsonConvert.SerializeObject(maintenanceEvent);
StringContent stringContent = new StringContent(jsonMaintenanceEvent, Encoding.UTF8, "application/json");
using (HttpClient httpClient = new HttpClient())
{
httpClient.BaseAddress = new Uri(endpointAddress);
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentialsBase64);
HttpResponseMessage httpResponseMessage = await httpClient.PostAsync(endpointDirectory, stringContent);
if (!httpResponseMessage.IsSuccessStatusCode)
{
throw new System.Exception("Error sending maintenance event to Monitor.");
}
}
}
Comparing the posts in Fiddler, the successful code has a Content-Type of application/json. But the unsuccessful block of code has a Content-Type of text/plain. I thought that Content-Type was based on the StringContent object, and I've set the ContentType as follows:
StringContent stringContent = new StringContent(jsonMaintenanceEvent, Encoding.UTF8, "application/json");
I don't understand why PostAsync disregards that setting. The object has a mediaType of application/json.
And if I change the post from PostAsync to PostAsJsonAsync, the post just gets stuck, as mentioned above.
Ultimately I just need to get the JSON post working in EpiServer versions higher than 8.0.0. After working on this for several days, this is just baffling. Thanks for your help.
HttpResponseMessage response = await httpClient.PostAsJsonAsync(access.EndpointDirectory, content).ConfigureAwait(false);Btw, you shouldn't new up HttpClient like that: aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong - JOSEFtwSendMaintananceEvent? It's always recommended to useConfigureAwait(false)unless you need to have access to the same context further down your method. - JOSEFtw