Custom ViewComponent with asp-for as parameter
I want to wrap this:
<textarea asp-for="@Model.Content" ...> into a reusable ViewComponent, where the property will be a parameter:
<vc:editor asp-for="@Model.Content" /> I managed to pass the asp-for 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 can not evaluate it in the presentation of components. This does not work:
<!-- ViewComponents/Editor/Default.cshtml --> @model Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression <textarea asp-for="@Model" /> Any ideas?
If you want to pass ModelExpression to the underlying ViewComponent and then pass it to TagGelper, you must do this using @TheModelExpression.Model :
<!-- ViewComponents/Editor/Default.cshtml --> @model Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression <textarea asp-for="@Model.Model" /> As @JoelHarkes noted, in this particular case, a custom taghelper might be more appropriate. Anyway, I can still display the PartialView ala template in 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()); } } then the .cshtml template will look exactly the same as in viewcomponent.
I think you are mixing ViewComponents and TagHelpers: https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components
View components
View components are invoked in the following question:
@await Component.InvokeAsync("EditorView", @Model.Property); // or <vc:[view-component-name]> Try the following snipp:
<vc:editor for="@Model.Content" /> Taghelpers
tag helpers are only called like this:
<textarea asp-for="@Model.Content">