How to create TagHelper who's value is a Model Property (without using @Model)?
Asked Answered
M

1

9

Tag Helper's are one of the sweet features of Asp.Net Core. I have created several tag helpers and they can be super helpful.

Now I would like to try something a bit more advanced. Tag helper attributes have the ability to be created in such as way that the attribute value is a model property.

And example of this is the following:

 //model
 public class MyModel{
      public int MyField {get;set;} = 10;
 }



  //in the view
  @model MyModel
   ...
  <input asp-for="MyField" />

In the above example the asp-for tag helper for the input tag directed references a property from the model. The documentation says that

The asp-for attribute value is a ModelExpression and the right hand side of a lambda expression. Therefore, asp-for="Property1" becomes m => m.Property1 in the generated code which is why you don't need to prefix with Model.

So this is pretty cool, and that same documentation appears to call this an "Expression name".

How do I create such a property in my own custom tag helper?

Mcintyre answered 7/4, 2017 at 19:17 Comment(0)
O
17

Just declare the parameter in your TagHelper as of type ModelExpression and then use it to generate the contents.

For example:

public class FooTagHelper : TagHelper
{
    public ModelExpression For { get; set; }

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        output.TagName = "div";
        output.Content.SetHtmlContent(
$@"You want the value of property <strong>{For.Name}</strong>
which is <strong>{For.Model}</strong>");
    }
}

If you use it in a view like this:

@model TestModel

<foo for="Id"></foo>
<foo for="Val"></foo>

And pass a model like new TestModel { Id = "123", Val = "some value" } then you will get the following output in your view (formatted for clarity):

<div>
    You want the value of property <strong>Id</strong>
    which is <strong>123</strong>
</div>
<div>
    You want the value of property <strong>Val</strong>
    which is <strong>some value</strong>
</div>
Onomatopoeia answered 8/4, 2017 at 10:56 Comment(1)
Is this possible for entire objects?Halliard

© 2022 - 2024 — McMap. All rights reserved.