У меня есть свой собственный помощник по тегам для <select>
элементов HTML. Он работает правильно при использовании в обычном представлении, но при использовании в шаблоне редактора он неправильно устанавливает атрибут имени. Кажется, что встроенные помощники тегов работают правильно.
Должно быть установлено значение: Object.PropertyName
, но вместо этого установлено значение PropertyName
.
Я использую ModelExpression.Name
, чтобы установить атрибут имени в конце моего кода. Должен ли я использовать что-то еще?
[HtmlTargetElement("select", Attributes = "asp-for")]
public class SelectOptionTagHelper : TagHelper
{
private readonly IPersonalTitleRepository _personalTitleRepository;
public SelectOptionTagHelper(IPersonalTitleRepository personalTitleRepository)
{
_personalTitleRepository = personalTitleRepository;
}
public override int Order { get; } = int.MaxValue;
[HtmlAttributeName("asp-for")]
public ModelExpression AspFor { get; set; }
[HtmlAttributeName("asp-items")]
public IEnumerable<SelectListItem> AspItems { get; set; }
private Dictionary<string, string> GetDropdownListValues(ListOptions option)
{
Dictionary<string, string> dict;
switch (option)
{
case ListOptions.Titles:
dict = _personalTitleRepository.GetAll()
.ToDictionary(x => x.PersonalTitleId.ToString(), x => x.Title);
break;
default:
throw new Exception("ListOptions enum has not been added to SelectOptionTaghelper");
}
return dict;
}
public override void Process(TagHelperContext context, TagHelperOutput output)
{
//if it is normal use of select list - process as normal
if (AspItems != null)
{
base.Process(context, output);
return;
}
string selected = "";
if (AspFor.Model != null)
{
selected = AspFor.Model.ToString();
}
//get the SelectList attribute
var type = AspFor.Metadata.ContainerType; //Get Object Type
var propertyName = AspFor.Metadata.PropertyName; //Get property name like "FundingId" (excludes full name like Application[i].FundingId)
var property = type.GetProperty(propertyName);
var attribute = property.GetCustomAttribute(typeof(SelectListAttribute)) as SelectListAttribute;
if (attribute == null)
{
throw new Exception("You must either supply an SelectList to asp-items or have a [SelectList(ListOptions.Option)] attribute");
}
Dictionary<string, string> dict = GetDropdownListValues(attribute.Option);
output.Content.AppendHtml($"<option value=\"\" disabled selected>Please select an option</option>");
//build option list
foreach (var item in dict)
{
if (!string.IsNullOrWhiteSpace(selected) && item.Key == selected)
{
output.Content.AppendHtml($"<option value=\"{item.Key}\" selected>{item.Value}</option>");
}
else
{
output.Content.AppendHtml($"<option value=\"{item.Key}\">{item.Value}</option>");
}
}
//Issue is here - setting the name property
output.Attributes.SetAttribute("Name", AspFor.Name);
output.Attributes.SetAttribute("Id", AspFor.Name);
}
}