into a reusable ViewComponent, wh...">

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?

+6
source share
2 answers

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.

+1
source

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"> 
+2
source

Source: https://habr.com/ru/post/1265606/


All Articles