Is it possible to invoke a View Component from controller and render it to a string? I am really looking for some code example for this. Any help will be much appreciated.
-
What do you mean by view component and when you say a string do you want to render a string in the view or the views component as a string? – IsakBosman Jan 18 '15 at 11:52
-
View components in mvc 6: http://www.asp.net/vnext/overview/aspnet-vnext/vc – eadam Jan 18 '15 at 11:56
5 Answers
As of beta7 it is now possible to return a ViewComponent directly from a controller. Check the MVC/Razor section of the announcement
The new ViewComponentResult in MVC makes it easy to return the result of a ViewComponent from an action. This allows you to easily expose the logic of a ViewComponent as a standalone endpoint.
So now the code for returning the sample view component just needs to be:
public class HomeController : Controller
{
public IActionResult Index()
{
return ViewComponent("My");
}
}
- 32,898
- 7
- 110
- 111
Please refer to example from official ASP.NET article on ViewComponent
In their example, the view component is called directly from the controller as follows:
public IActionResult IndexVC()
{
return ViewComponent("PriorityList", new { maxPriority = 3, isDone = false });
}
- 18,769
- 32
- 131
- 275
You can do that but you have to apply following thing as It is render by DefaultViewComponentHelper.
You have to create instance of this and to create that you need IViewComponentSelector and IViewComponentInvokerFactory.
To do this I have done following thing.
public class HomeController : Controller
{
Microsoft.AspNet.Mvc.DefaultViewComponentHelper helper = null;
Microsoft.AspNet.Mvc.Razor.RazorView razorView = null;
public HomeController(IViewComponentSelector selector,IViewComponentInvokerFactory factory,IRazorPageFactory razorPageFactory,IRazorPageActivator pageActivator,IViewStartProvider viewStartProvider)
{
helper = new DefaultViewComponentHelper(selector, factory);
razorView = new Microsoft.AspNet.Mvc.Razor.RazorView(razorPageFactory, pageActivator, viewStartProvider);
}
public IActionResult Index()
{
ViewContext context = new ViewContext(ActionContext, razorView, ViewData, null);
helper.Contextualize(context);
string st1 = helper.Invoke("My", null).ToString();
return View();
}
}
Here is my sample View Component.
public class MyViewComponent : ViewComponent
{
public MyViewComponent()
{
}
public IViewComponentResult Invoke()
{
return Content("This is test");
}
}
- 16,207
- 4
- 51
- 66
-
This doesn't work with latest bits. Try this: https://gist.github.com/pauldotknopf/b424e9b8b03d31d67f3cce59f09ab17f – Paul Knopf May 12 '18 at 19:28
-
This should not be the accepted answer anymore. See the other answers. You can just call `return ViewComponent(...` in .NET Core – Rubanov Jan 15 '21 at 10:50
Here's a tag helper that I created to embed components via HTML like syntax. Invoking from a TagHelper like this should closely match invoking from a Controller.
ViewComponent Tag Helper
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewComponents;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace TagHelperSamples.Web
{
[HtmlTargetElement("component")]
public class ComponentTagHelper : TagHelper
{
private DefaultViewComponentHelper _componentHelper;
[HtmlAttributeName("name")]
public string Name { get; set; }
[HtmlAttributeName("params")]
public object Params { get; set; }
[ViewContextAttribute] // inform razor to inject
public ViewContext ViewContext { get; set; }
public ComponentTagHelper(IViewComponentHelper componentHelper)
{
_componentHelper = componentHelper as DefaultViewComponentHelper;
}
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
_componentHelper.Contextualize(ViewContext);
output.Content.AppendHtml(
await _componentHelper.InvokeAsync(Name, Params)
);
}
}
}
Usage
<component name="RecentComments" params="new { take: 5, random: true }"></component>
- 219
- 2
- 2
Code from dotnetstep's answer updated for MVC 6.0.0-beta4 (VS2015 RC):
public class HomeController : Controller
{
Microsoft.AspNet.Mvc.ViewComponents.DefaultViewComponentHelper helper = null;
public HomeController(IViewComponentDescriptorCollectionProvider descriptorProvider, IViewComponentSelector selector, IViewComponentInvokerFactory invokerFactory)
{
helper = new DefaultViewComponentHelper(descriptorProvider, selector, invokerFactory);
}
public IActionResult Index()
{
ViewContext context = new ViewContext(ActionContext, null, ViewData, null, null);
helper.Contextualize(context);
string st1 = helper.Invoke("My", null).ToString();
return View();
}
}
- 43,528
- 14
- 63
- 63