1

I'm cross posting this question from the Sitefinity forum to gather as many strategies as possible. This question is similar to this one, but I'm posting it anyway to get feedback on which of the suggested workarounds we've come up with might be a better fit.

Sitefinity supports the creation of widgets using MVC Controllers. However, these controllers cannot be async nor return Task<>. Usually, this is fine as we would normally be interacting with Sitefinity data, which has managers that are not asynchronous.

However, in this case, we are creating widgets that will be showing data coming from a 3rd party API, and are using HttpClient to fetch that data, and those operations are async. To be clear, these are server-to-server api calls, and can't be done directly via client-side ajax calls.

From what I've been able to research and read about this, the prevailing strategy is to replace HttpClient with WebClient and make the calls synchronous (as suggested here). This seems simple enough but I'm concerned that this may impact performance since we expect peak times to handle several hundred if not thousands of users at once, and these are purchasing transactions, so it is especially important that they are performant...

the only other strategy I can think of is to implement this part of the site as a SPA using angular and doing everything on the client side. But we don't want to expose our API calls on the client side, so we'd have to build a proxy to pass them through on the server side, probably using a regular controller ("classic" as it is called in Sitefinity, one that does not drive widgets).

Are there any other strategies we can leverage to make async calls in a controller that does not support async? Would you agree that making the calls synchronous via WebClient is the better choice in this case? If not, what other option would you suggest to work around this limitation?

Community
  • 1
  • 1
SelAromDotNet
  • 4,715
  • 5
  • 37
  • 59
  • You can implement your own WebApiControllers in the project, while utilizing the Sitefinity Content API's to gather the CMS content you need for display on the widget. – maccettura May 09 '17 at 16:53
  • thank you for your input, this would work fine if all we needed was SF content, but these widgets are not for SF content they are for external content that we have to fetch via HTTP calls to a REST api, and those calls are asynchronous with HttpClient, and so we cannot make such call from the actions of our Sitefinity MVC widget controller, because asynchronous actions are not supported in Sitefinity. – SelAromDotNet May 09 '17 at 17:06
  • I understand that. Literally all you would need to do is create a WebApiController in VisualStudio in the project. If you do not need Sitefinity content that is fine, you can still use HttpClient to call out to external API's (obfuscating the API calls from the client side). You can mark these controller actions as async with no issue – maccettura May 09 '17 at 17:18
  • okay yes I get that, but I cannot use those controllers to create widgets, and that's the problem. If you mean that I can call those WebApiControllers from my regular sitefinity widget controllers, wouldn't I still have the same problem? since those are async, I'd still have to call them async from the controllers? if you mean to call my custom webapi controllers synchronously would it then make more sense to just make the webcalls from the widgets to api directly synchronous using WebClient instead? – SelAromDotNet May 09 '17 at 18:20
  • Maybe I have misunderstood your problem. My understanding was that you needed to create widgets (creating meaning dragging a widget from the toolbox onto your page designer). The API calls would be done from the JS in the views of those widgets. If this is not the case disregard what I've said – maccettura May 09 '17 at 18:23
  • 2
    you are correct that I am making widgets that will drag onto the page, but the api calls are done from the *server side* actions of those widgets, not via client side ajax. if they are client side ajax we can do it, but the api calls are server-to-server – SelAromDotNet May 09 '17 at 18:28
  • i see what you're saying now, you're saying to use the webapi as a proxy to do the server-to-server calls, and initiate them with ajax. this is a big workaround to replace a simple async http call. i'm curious to know if this is a better solution than just making the calls using webclient, which is far less work (there is a lot to cover in the remote api) – SelAromDotNet May 09 '17 at 18:58

1 Answers1

4

Usually, async methods are working like that: enter image description here

All async actions invoked by AsyncControllerActionInvoker class.

But this will not work for sitefinity, because Telerik.Sitefinity.Mvc.ControllerActionInvoker (who is processing mvc widgets) is synchronous.

I am pretty sure that other limitations might be not only in "Invoke Action" level, somewhere deeper. I think only Sitefinity core developers can answer to this question in deep details

Victor Leontyev
  • 8,488
  • 2
  • 16
  • 36
  • thank you for the graphic, this is definitely the way I understand it. it seems that while supporting async would free a thread during processing that's about it, so I would be safe just using WebClient instead of HttpClient to service these requests in my widgets. if SF ever adds async I can swap the httpclient back in. Am I shooting myself in the foot here performance wise? I mean this is how we did it for years before async anyway right? – SelAromDotNet May 09 '17 at 19:27
  • Yeah, i am surprised why Progress still didn't implement async methods for DataAccess ORM and async controllers for Sitefinity. I guess in your case, you can just use WebClient. Of course it will be slower than async HttpClient – Victor Leontyev May 09 '17 at 20:07