需要帮助获得高于8.0.0的EpiServer CMS版本的JSON帖子(Need help getting JSON post working for EpiServer CMS version h

编程入门 行业动态 更新时间:2024-10-28 02:25:14
需要帮助获得高于8.0.0的EpiServer CMS版本的JSON帖子(Need help getting JSON post working for EpiServer CMS version higher than 8.0.0)

我们有多个EpiServer站点,我们在其中添加了将JSON发布到站点监控API的功能。 我能够在我们的EpiServer CMS 8.0.0版本站点上成功运行JSON帖子,但遇到了CMS版本8.8.1及更高版本的问题。

以下是我们成功的工作代码的样子。

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."); } } }

上面的方法依赖于几个using语句也在这个类中。

using System.Net.Http; using System.Net.Http.Headers;

以上内容在我们的EpiServer CMS 8.0.0解决方案中取得了成功。 但是当我们将相同的代码移植到其中一个较高的CMS版本时,帖子会卡在这一行:

HttpResponseMessage response = await httpClient.PostAsJsonAsync(access.EndpointDirectory, content);

“卡住”我的意思是Visual Studio调试器在该行停止,并且永远不会进入下一行。

研究这个,我发现了一个使用PostAsync而不是PostAsJsonAsync的建议。 所以这是我对EpiServer 9解决方案的一次尝试。 但最终会以text/plain而不是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."); } } }

比较Fiddler中的帖子,成功的代码具有Content-Type of application/json 。 但是不成功的代码块具有Content-Type of text/plain 。 我认为Content-Type基于StringContent对象,我将ContentType设置如下:

StringContent stringContent = new StringContent(jsonMaintenanceEvent, Encoding.UTF8, "application/json");

我不明白为什么PostAsync忽略了这个设置。 该对象具有application/json的mediaType。

如果我将帖子从PostAsync更改为PostAsJsonAsync ,帖子就会卡住,如上所述。

最后,我只需要在EpiServer版本高于8.0.0的情况下使用JSON帖子。 经过几天的努力,这简直莫名其妙。 谢谢你的帮助。

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.

最满意答案

我不知道调用代码是什么样的,但是发生了什么是死锁,你可以通过在PostAsJsonAsync调用上使用PostAsJsonAsync .ConfigureAwait(false)来避免这种情况:

HttpResponseMessage response = await httpClient.PostAsJsonAsync(access.EndpointDirectory, content).ConfigureAwait(false);

在这里使用async / await时,您可以阅读有关死锁的更多信息: http : //blog.stephencleary.com/2012/07/dont-block-on-async-code.html

他的例子看起来很像你的问题。

顶级方法调用GetJsonAsync(在UI / ASP.NET上下文中)。 GetJsonAsync(在UI / ASP.NET上下文中)。 GetJsonAsync通过调用HttpClient.GetStringAsync(仍在上下文中)启动REST请求。 GetStringAsync返回未完成的Task,表示REST请求未完成。 GetJsonAsync等待GetStringAsync返回的任务。 捕获上下文,稍后将用于继续运行GetJsonAsync方法。 GetJsonAsync返回未完成的Task,表示GetJsonAsync方法未完成。 顶级方法同步阻止GetJsonAsync返回的任务。 这会阻止上下文线程。 ...最终,REST请求将完成。 这样就完成了GetStringAsync返回的任务。 GetJsonAsync的延续现在可以运行了,它等待上下文可用,以便它可以在上下文中执行。 僵局。 顶级方法是阻塞上下文线程,等待GetJsonAsync完成,GetJsonAsync正在等待上下文空闲,以便它可以完成。

斯蒂芬列出了两种避免死锁的方法

在“库”异步方法中,尽可能使用ConfigureAwait(false)

不要阻止任务; 一直使用async。

在没有看到实际调用SendMaintenanceEvent方法的代码的情况下,很难说出实际导致死锁的原因。

I don't know what the calling code looks like but what's happening is a deadlock, you can avoid this by using .ConfigureAwait(false) on your PostAsJsonAsync call like this:

HttpResponseMessage response = await httpClient.PostAsJsonAsync(access.EndpointDirectory, content).ConfigureAwait(false);

You can read more about deadlocks when using async/await here: http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html

His example looks a lot like your problem.

The top-level method calls GetJsonAsync (within the UI/ASP.NET context). GetJsonAsync (within the UI/ASP.NET context). GetJsonAsync starts the REST request by calling HttpClient.GetStringAsync (still within the context). GetStringAsync returns an uncompleted Task, indicating the REST request is not complete. GetJsonAsync awaits the Task returned by GetStringAsync. The context is captured and will be used to continue running the GetJsonAsync method later. GetJsonAsync returns an uncompleted Task, indicating that the GetJsonAsync method is not complete. The top-level method synchronously blocks on the Task returned by GetJsonAsync. This blocks the context thread. … Eventually, the REST request will complete. This completes the Task that was returned by GetStringAsync. The continuation for GetJsonAsync is now ready to run, and it waits for the context to be available so it can execute in the context. Deadlock. The top-level method is blocking the context thread, waiting for GetJsonAsync to complete, and GetJsonAsync is waiting for the context to be free so it can complete.

Stephen lists 2 ways to avoid deadlocks

In your “library” async methods, use ConfigureAwait(false) wherever possible.

and

Don’t block on Tasks; use async all the way down.

Without seeing the code that actually calls your SendMaintenanceEvent method it's difficult to tell what's actually causing the deadlock.

更多推荐

EpiServer,CMS,JSON,PostAsync,电脑培训,计算机培训,IT培训"/> <meta name="

本文发布于:2023-07-26 02:46:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1269973.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:高于   版本   帖子   CMS   EpiServer

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!