Calling view components in ASP.NET Core views may lead to long and ugly code lines containing generic type parameter of view component and anonymous type for InvokeAsync() method parameters. Something my readers have been interested in has been here for long time – tag helper syntax for view components.
ASP.NET Core pager example
Suppose you have pager implemented as view component and there’s support for multiple views.
public class PagerViewComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync(PagedResultBase pagedResult,
string viewName = "Default")
{
var action = RouteData.Values["action"].ToString();
pagedResult.LinkTemplate = Url.Action(action, new { page = "{0}" });
return await Task.FromResult(View(viewName, pagedResult));
}
}
This is how you call pager view component in views. Arguments are given as anonymous object that is matched by argument list of component’s InvokeAsync() method.
@(await Component.InvokeAsync<PagerViewComponent>(new { pagedResult = Model, viewName = "PagerSmall" }))
Nice thing is – you don’t need such a long call in your views. ASP.NET Core supports special tag helper syntax for view components. There’s special namespace called “vc” and through this we can call view components using tag helper syntax. You can replace the call above with shorter one shown here.
<vc:pager paged-result="@Model" view-name="PagerSmall" />
NB! Make sure you add your view components namespace to _ViewImports.cs file that is located in Views folder. If you don’t, then ASP.NET Core cannot find your view components.
Default parameters are ignored
There are two gotchas you have to know about:
- Taghelper syntax doesn’t support default parameters – you must specify all parameters that InvokeAsync() method of view component has.
- View components support only one InvokeAync() method. There cannot be overloads or you will get compiler error.
Based on code above and gotchas mentioned this call will not work.
<vc:pager result="@Model.References" />
InvokeAsync() method has also viewName argument and although the argument has default value the taghelper declaration here is not valid as view-name attribute is not specified.
It’s even worse – if arguments are not matched then taghelper declaration is left to output exactly like it is.
Wrapping up
View components and tag helpers are powerful features in ASP.NET Core. Tag helpers have nice and clean syntax that view components lack when included in views. There’s special “vc” tag prefix in ASP.NET Core that brings tag helper syntax for view components to Razor views. Instead of anonymous object with arguments we can use tag attributes to give values to InvokeAsync() method of view component. This leads us to shorter and cleaner views that are easier to handle.