7

I'm currently building an ASP.NET MVC application. I'm trying to add items to the ViewBag property for all pages in my site. To achieve this, I've created a base controller that all my site controllers inherit from.

To add to the ViewBag, I've overridden the OnActionExecuting method: protected override void OnActionExecuting(ActionExecutingContext filterContext)

I know that the OnActionExecuting methods for MVC5 are not async, which is why I'm running into this issue. I need to be able to call some form of the following code to retrieve the newest items and put them into the ViewBag:

IList<PlaceListItemViewModel> places = await GetLatestPlaces(3);
ViewBag.FooterLatestPlaces = places;

Using the GetLatestPlaces(3).Result just causes a deadlock, so this is not an option.

Could anybody give me an option on how to achieve this. It doesn't have to be overriding the OnActionExecuting method either, if there is another way to add items to the ViewBag for every page (other than calling the code from every single action in every controller), I'm open to using that method.

Unfortunately I can't the GetLatestPlaces method to be non-async, as it's using the MongoDB 2.0 driver, which is async all the way.

2
  • Consider re-design so you can call the method later... There is really no good way to call asynchronous method synchronously. Commented May 27, 2015 at 3:18
  • What do you mean call the method later? Is there another method of adding data to the ViewBag (or similar) that can be used within the razor view files without adding heaps of c# code to the views? Commented May 27, 2015 at 3:33

1 Answer 1

16

There are two general methods to achieve what you wanted:

  1. Use ConfigureAwait(false) in your async library. In your case you should do it inside GetLatestPlaces() method.
  2. Call your async method in a different thread in order to not block the current context. So your code will look like this:

    IList<PlaceListItemViewModel> places = Task.Run(async () =>  await GetLatestPlaces(3)).Result;
    

For more info see Stephen Cleary's excellent blog post.

Sign up to request clarification or add additional context in comments.

4 Comments

The second method you described is working brilliantly! I'll be sure to have a read of that blog post too. Cheers.
@Juzzbott The first method should work too, read Stephen's blog post and you'll get all the concept.
Calling Task.Run in an ASP.NET application will hurt performance because of the unnecessary context switch.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.