I am trying to use the ViewComponents.InvokeAsync()
feature, but somehow this is not async at all. It is waiting for the component code to render.
http://docs.asp.net/en/latest/mvc/views/view-components.html
My code is very much similar to the one explained in above example. I am using the layout page which comes when you create new application in MVC 6.
I thought that ViewComponent.InvokeAsync()
method will render asynchronously with respect to the main page. But it does not. In order to achieve this, we need to use AJAX as explained here.
Server side async does not do partial page rendering in the web browser. The following code will block until GetItemsAsync
returns.
public async Task<IViewComponentResult> InvokeAsync()
{
var items = await GetItemsAsync();
return View(items);
}
And this code will block until the itemsTask
completes.
public async Task<IViewComponentResult> InvokeAsync()
{
var itemsTask = GetItemsAsync(maxPriority, isDone);
// We can do some other work here,
// while the itemsTask is still running.
var items = await itemsTask;
return View(items);
}
Server side async lets us do additional work on the server while we wait for some other server side task to complete.
To partially render the page in the web browser, we need to use client side AJAX. In the following example, we use AJAX to call /Home/GetHelloWorld
and render in in the body
.
~/HelloWorldViewComponent.cs
public class HelloWorldViewComponent : ViewComponent
{
public IViewComponentResult Invoke()
{
var model = new string[]
{
"Hello", "from", "the", "view", "component."
};
return View("Default", model);
}
}
~/HomeController.cs
public class HomeController : Controller
{
public IActionResult GetHelloWorld()
{
return ViewComponent("HelloWorld");
}
}
~/Views/Shared/Components/HelloWorld/Default.cshtml
@model string[]
<ul>
@foreach(var item in Model)
{
<li>@item</li>
}
</ul>
~/wwwroot/index.html
<body>
<script src="js/jquery.min.js"></script>
<script>
$.get("home/GetHelloWorld", function(data) {
$("body").html(data);
});
</script>
</body>
localhost:5000/index.html