I want wrap this:
<textarea asp-for="@Model.Content" ...>
into reusable ViewComponent, where property will be parameter:
<vc:editor asp-for="@Model.Content" />
I was able to pass asp-for as parameter to the viewcomponent:
public class EditorViewComponent : ViewComponent
{
public IViewComponentResult Invoke(ModelExpression aspFor = null)
{
//when debugging, aspFor has correct value
return View(aspFor);
}
}
But I'm not able to evaluate it in component's view. This does not work:
<!-- ViewComponents/Editor/Default.cshtml -->
@model Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression
<textarea asp-for="@Model" />
Any ideas?
View Components in Controller Methods Rather than passing the name of your view component, you can pass its Type object, giving you some IntelliSense support, as in this example: return ViewComponent(typeof(CustomerAddressViewComponent), new { CustomerId = "A123"});
A view component class can be created by any of the following: Deriving from ViewComponent. Decorating a class with the [ViewComponent] attribute, or deriving from a class with the [ViewComponent] attribute. Creating a class where the name ends with the suffix ViewComponent.
A View Component class can be created in the following ways. Same as Controller class, View Component class must be non-abstract, public, and non-nested. This class fully supports constructor dependency injection. It does not take part in the Controller lifecycle so that we cannot use filters in the view component.
If you want to pass ModelExpression to underlying ViewComponent and then pass it to TagHelper, you have to do it using @TheModelExpression.Model
:
<!-- ViewComponents/Editor/Default.cshtml -->
@model Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression
<textarea asp-for="@Model.Model" />
As @JoelHarkes mentioned, in this particular case, custom taghelper could be more appropriate. Anyway, I still can render PartialView ala Template in the TagHelper:
[HtmlTargetElement("editor", Attributes = "asp-for", TagStructure = TagStructure.WithoutEndTag)]
public class EditorTagHelper : TagHelper
{
private HtmlHelper _htmlHelper;
private HtmlEncoder _htmlEncoder;
public EditorTagHelper(IHtmlHelper htmlHelper, HtmlEncoder htmlEncoder)
{
_htmlHelper = htmlHelper as HtmlHelper;
_htmlEncoder = htmlEncoder;
}
[HtmlAttributeName("asp-for")]
public ModelExpression For { get; set; }
[ViewContext]
public ViewContext ViewContext
{
set => _htmlHelper.Contextualize(value);
}
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
output.TagName = null;
var partialView = await _htmlHelper.PartialAsync("TagHelpers/Editor", For);
var writer = new StringWriter();
partialView.WriteTo(writer, _htmlEncoder);
output.Content.SetHtmlContent(writer.ToString());
}
}
the .cshtml template would then look exactly like in viewcomponent.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With