I\'m trying to create a dropdown list with an enum property in ASP.NET MVC Core using the tag helper in a Razor view:
Here is the model:
public class Per
This is the way to implement Custom TagHelper DropDownList with enum in netcore 3
///
/// implementation targeting <enum-radio-button> elements with an asp-for attribute, value attribute.
///
[HtmlTargetElement("radio-button-enum", Attributes = RadioButtonEnumForAttributeName)]
public class RadioButtonEnumTagHelper : TagHelper
{
private const string RadioButtonEnumForAttributeName = "asp-for";
private const string RadioButtonEnumValueAttributeName = "value";
///
/// Creates a new .
///
/// The .
public RadioButtonEnumTagHelper(IHtmlGenerator generator)
{
Generator = generator;
}
///
public override int Order => -1000;
[HtmlAttributeNotBound]
[ViewContext]
public ViewContext ViewContext { get; set; }
protected IHtmlGenerator Generator { get; }
///
/// An expression to be evaluated against the current model.
///
[HtmlAttributeName(RadioButtonEnumForAttributeName)]
public ModelExpression For { get; set; }
[HtmlAttributeName(RadioButtonEnumValueAttributeName)]
public Enum Value { get; set; }
///
/// Does nothing if is null .
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (output == null)
{
throw new ArgumentNullException(nameof(output));
}
var childContent = await output.GetChildContentAsync().ConfigureAwait(true);
string innerContent = childContent.GetContent();
output.Content.AppendHtml(innerContent);
output.TagName = "div";
output.TagMode = TagMode.StartTagAndEndTag;
output.Attributes.Add("class", "btn-group btn-group-radio");
var modelExplorer = For?.ModelExplorer;
var metaData = For?.Metadata;
if (metaData?.EnumNamesAndValues != null)
{
foreach (var item in metaData.EnumNamesAndValues)
{
string enumId = $"{metaData.ContainerType.Name}_{metaData.PropertyName}_{item.Key}";
string enumInputLabelName = item.Key.ToString();
bool enumIsChecked = false;
if (Value != null)
{
if (enumInputLabelName == Value.ToString())
{
enumIsChecked = true; }
}
else
{
if (For.Model != null && enumInputLabelName == For.Model.ToString())
{
enumIsChecked = true;
}
}
var enumResourcedName = metaData.EnumGroupedDisplayNamesAndValues.FirstOrDefault(x => x.Value == item.Value);
if (enumResourcedName.Value != null)
{
enumInputLabelName = enumResourcedName.Key.Name;
}
var enumRadio = Generator.GenerateRadioButton(
ViewContext,
For.ModelExplorer,
metaData.PropertyName,
item.Key,
false,
htmlAttributes: new { @id = enumId });
enumRadio.Attributes.Remove("checked");
if (enumIsChecked)
{
enumRadio.MergeAttribute("checked", "checked");
}
output.Content.AppendHtml(enumRadio);
var enumLabel = Generator.GenerateLabel(
ViewContext,
For.ModelExplorer,
For.Name,
enumInputLabelName,
htmlAttributes: new { @for = enumId, @Class = "btn btn-default" });
output.Content.AppendHtml(enumLabel);
}
}
}
}