Advanced usage of tag assistant in asp.net core taghelper + form

Time:2021-6-24

In the last blog, I explained the basic usage of taghelper and the generation of custom tags, so I’ll strike while the iron is hot, and share the advanced usage of taghelper with you ~ ~, you can also leave a message under my blog.

For my initial contact with asp.net core, you can see my understanding and views on taghelper

New features of asp.net core (1): taghelper

After that, I will continue to write blog articles and share some new features of asp.net core, such as Di, viewcomponent, bower and other new things that are not available in asp.net MVC.

OK, let’s start~~

In my previous sharing of taghelper, I mentioned that taghelper can replace some functions in the @ HTML help class, such as form, a and other tags. Moreover, it is more comfortable to write in HTML code and conforms to the syntax of HTML.

<!-- Label assistant form -- >
<form asp-controller="Home" asp-action="Index" method="post">

</form>
<!-- HTML help class version form -- >
@using (Html.BeginForm("Index", "Home", FormMethod.Post,, new { Class = "form-horizontal" }))
{

}

So, in the HTML help class, the most useful conversion between model and tag, automatic form generation, does Microsoft also provide a solution? The answer is yes. Microsoft also has a separate description page to talk about the automatic form generation of taghelper. Students with good English skills can directly view the official documents of MS《Introduction to using tag helpers in forms in ASP.NET Core》。

It is mentioned in the document that for form controls, we can directly fill in the attribute name in the model in the ASP for attribute to automatically generate the corresponding control type and fill in the default value.

OK, let’s have a try.

(1) Create ViewModel class

public class SignUpViewModel
 {
 [Required]
 [display (name = user name)]
 [MaxLength (30, ErrorMessage = user name cannot exceed 30 ')]
 public string UserName { get; set; }

 [Required]
 [DataType(DataType.Password)]
 [RegularExpression(@"((?=.*\ d)(?=.*\ D)|(?=.*[ a-zA-Z])(?=.*[^ A-za-z])) ^ $", ErrorMessage =" password contains at least two characters ")]
 [display (name = password)]
 public string Password { get; set; }

 [DataType(DataType.MultilineText)]
 public string Description { get; set; }
 }

For developers who have written asp.net MVC, this verification method is certainly familiar~~

(2) Writing taghelper Tags

To distinguish it from HTML, I wrote a comparative version of the two

<form asp-controller="Home" asp-action="SignUp" method="post">
 <div>
 <label asp-for="UserName"></label>
 <input asp-for="UserName" />
 <span asp-validation-for="UserName"></span>
 </div>
 <div>
 @Html.LabelFor(m=>m.Password)
 @Html.PasswordFor(m=>m.Password)
 @Html.ValidationMessageFor(m=>m.Password)
 </div>
 <div>
 <label asp-for="Description"></label>
 <textarea asp-for="Description"></textarea>
 <span asp-validation-for="Description"></span>
 </div>
 <div>
 < input type = submit "value = submit / >
 < input type = reset value = reset / >
 </div>
</form>

(3) Validation form


public IActionResult SignUp(SignUpViewModel model)
 {
  if (ModelState.IsValid)
  {
  return RedirectToAction("Index");
  }
  else
  {
  return RedirectToAction("Index",model);
  }
 }


(4) Results

OK, if you think this is the end, then it’s not an advanced application of taghelper, it can only translate MS documents at best.

Now, the point is, since MS allows us to create a custom taghelper, why can’t I use the value of model in taghelper? So I began to search in the open source GitHub project of asp.net core, and finally found the source code of imprettagheelper.

In the source code, the label is generated by three objects


protected IHtmlGenerator Generator { get; }

 [HtmlAttributeNotBound]
 [ViewContext]
 public ViewContext ViewContext { get; set; }

 /// <summary>
 /// An expression to be evaluated against the current model.
 /// </summary>
 [HtmlAttributeName(ForAttributeName)]
public ModelExpression For { get; set; }


The three objects are generated by dependency injection.

(1) Generator is responsible for generating various types of tags

(2) Viewcontext is the view context to obtain the view context related information

(3) For gets the relevant information of the current model, including required and other key information

With these three tags, we can also get the model information you want in the custom tag assistant. For example, I can fill in the model information in the form and let the tag assistant automatically generate all the content in the form; You can also fill the UL tag with tree information to automatically generate a tree list and so on

Here’s the auto generated form I wrote

//The custom label assistant is called BG form
 [HtmlTargetElement("bg-form")]
 public class FormTagHelper : TagHelper
 {
  [ViewContext]
  [HtmlAttributeNotBound]
  public ViewContext ViewContext { get; set; }

  [HtmlAttributeName("asp-for")]
  public ModelExpression For { get; set; }

  protected IHtmlGenerator Generator { get; }

  public FormTagHelper(IHtmlGenerator generator)
  {
   Generator = generator;
  }

  [HtmlAttributeName("asp-controller")]
  public string Controller { get; set; }

  [HtmlAttributeName("asp-action")]
  public string Action { get; set; }

  //Asynchronous method
  public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
  {
   output.TagName = "form";
   if (!string.IsNullOrWhiteSpace(Controller))
   {
    output.Attributes.Add("action", "/" + Controller + "/" + Action);
   }

   output.Attributes.Add("class", "form-horizontal");

   //Get child properties
   var props = For.ModelExplorer.Properties;
   foreach (var prop in props)
   {
    //Generate form
    var div = new TagBuilder("div");
    div.AddCssClass("form-group");
    var label = Generator.GenerateLabel(ViewContext, prop, null, prop.Metadata.DisplayName, null);
    var input = Generator.GenerateTextBox(ViewContext, prop, prop.Metadata.PropertyName, null, null, null);
    var span = Generator.GenerateValidationMessage(ViewContext, prop, prop.Metadata.PropertyName, null, ViewContext.ValidationMessageElement, null);
    div.InnerHtml.AppendHtml(label);
    div.InnerHtml.AppendHtml(input);
    div.InnerHtml.AppendHtml(span);
    output.Content.AppendHtml(div);
   }
   //Add button
   var btn = new TagBuilder("div");
   btn.AddCssClass("form-group");
   var submit = new TagBuilder("input");
   submit.Attributes.Add("type", "submit");
   Submit. Attributes. Add ("value", "submit");
   var reset = new TagBuilder("input");
   reset.Attributes.Add("type", "reset");
   Reset. Attributes. Add ("value", "reset");
   btn.InnerHtml.AppendHtml(submit);
   btn.InnerHtml.AppendHtml(reset);
   output.Content.AppendHtml(btn);
   //Add the original content to the label
   output.Content.AppendHtml(await output.GetChildContentAsync());

  }
 }

Just add in HTML


<bg-form asp-controller="Home" asp-action="SignUp" asp-for="@Model">
</bg-form>

The form is automatically generated

Over, let’s share about taghelper today

The above is the whole content of this article, I hope to help you learn, and I hope you can support developer more.

Recommended Today

Programming Xiaobai must understand the network principle

How is the network composed? Why can we easily surf the Internet now?Whether you are a computer major or not, you may always have such questions in your heart!And today we will solve this matter and tell you the real answer! Basic composition of network First, let’s look at this sentence Connect all computers together […]