Jan 26 2023 06:34 AM - edited Jan 26 2023 08:03 AM
In my project we make use of an ESM web component library. In order to get it working with data binding, model validation and all we developed some Tag Helper classes that can output these custom element tags. As I'm not an expert in .NET application development, I wanted some feedback if this is the correct way to go about it. If not, can someone point me in the right direction?
For instance, the web component library exposes the custom input field:
<w-input></w-input>
To make it work with model binding, we created the respective Tag Helper class:
namespace TestApp.TagHelpers
{
[HtmlTargetElement("ds-input")]
public class DSInputTagHelper : TagHelper
{
protected IHtmlGenerator Generator { get; }
protected String TagName = "w-input";
[HtmlAttributeNotBound]
[ViewContext]
public ViewContext ViewContext { get; set; }
public ModelExpression AspFor { get; set; }
public DSInputTagHelper(IHtmlGenerator generator, String tagName)
{
TagName = tagName;
Generator = generator;
}
public override void Process(TagHelperContext context, TagHelperOutput output)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (output == null)
{
throw new ArgumentNullException(nameof(output));
}
if (AspFor != null)
{
var labelTagBuilder = Generator.GenerateLabel(ViewContext, AspFor.ModelExplorer, AspFor.Name, null, null);
if (labelTagBuilder != null)
{
output.MergeAttributes(labelTagBuilder);
if (labelTagBuilder.HasInnerHtml)
{
output.Attributes.Add("label", labelTagBuilder.InnerHtml);
}
}
var textBoxTagBuilder = Generator.GenerateTextBox(
ViewContext,
AspFor.ModelExplorer,
AspFor.Name,
AspFor.ModelExplorer.Model,
null,
htmlAttributes: new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase));
if (textBoxTagBuilder != null)
{
output.MergeAttributes(textBoxTagBuilder);
}
var validationTagBuilder = Generator.GenerateValidationMessage(
ViewContext,
AspFor.ModelExplorer,
AspFor.Name,
message: null,
tag: null,
htmlAttributes: new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase));
if (validationTagBuilder != null)
{
if (validationTagBuilder.HasInnerHtml)
{
output.Attributes.Add("invalid", null);
output.Attributes.Add("invalid-feedback", validationTagBuilder.InnerHtml);
}
}
output.TagName = TagName;
}
}
}
}
So in order to use it, in the page .cshtml we do:
@model Person
<ds-input asp-for="Person.firstName"></ds-input>
And finally we get the following output:
<w-input for="Person_firstName"
id="Person_firstName"
name="Person.firstName"
value="Victor"
size="md"
type="text"
label="First Name"
data-val="true"
data-val-minlength="First name is required"
data-val-minlength-min="1"
data-val-required="Name is mandatory!">
</w-input>
Is this the right way to go about it? If not, can you point me on the right direction?
Thank you all in advance!
Mar 02 2023 06:42 PM
Hi @vgabrieldesouza,
Thanks for posting your issue here.
However this platform is used for how-to discussions and sharing best practices for building any app with .NET.Since your issue is a technical question, welcome to post it in Microsoft Q&A forum, the support team and communities on Microsoft Q&A will help you for any technical questions.
Besides, it will be appreciated if you can share it here once you post this technical question Microsoft Q&A.
Best Regards,
Lan Huang