С классом модели Member
public class Member
{
public int PersonId { get; set; }
public string Name { get; set; }
[EmailAddress]
public string Email { get; set; }
[DataType(DataType.Password)]
public string Password { get; set; }
[DataType(DataType.PhoneNumber)]
public string Telephone { get; set; }
[Display(Name="Date of Birth")]
public DateTime DateOfBirth { get; set; }
public decimal Salary { get; set; }
[Url]
public string Website { get; set; }
[Display(Name="Send spam to me")]
public bool SendSpam { get; set; }
public int? NumberOfCats { get; set; }
public IFormFile Selfie { get; set; }
}
И моделью страницы
public class RegisterModel : PageModel
{
[BindProperty]
public Member Member { get; set; }
public void OnGet()
{
}
}
This CS HTML
<form method="post">
<input asp-for="Member.PersonId" /><br />
<input asp-for="Member.Name" /><br />
<input asp-for="Member.Email" /><br />
<input asp-for="Member.Password" /><br />
<input asp-for="Member.Telephone" /><br />
<input asp-for="Member.Website" /><br />
<input asp-for="Member.DateOfBirth" /><br />
<input asp-for="Member.Salary" /><br />
<input asp-for="Member.SendSpam" /><br />
<input asp-for="Member.NumberOfCats" /><br />
<input asp-for="Member.Selfies" /><br />
<button>Submit</button>
</form>
Создать:
<form method="post">
<input type="number" data-val="true" data-val-required="The PersonId field is required." id="Member_PersonId" name="Member.PersonId" value="" /><br />
<input type="text" id="Member_Name" name="Member.Name" value="" /><br />
<input type="email" data-val="true" data-val-email="The Email field is not a valid e-mail address." id="Member_Email" name="Member.Email" value="" /><br />
<input type="password" id="Member_Password" name="Member.Password" /><br />
<input type="tel" id="Member_Telephone" name="Member.Telephone" value="" /><br />
<input type="url" data-val="true" data-val-url="The Website field is not a valid fully-qualified http, https, or ftp URL." id="Member_Website" name="Member.Website" value="" /><br />
<input type="datetime-local" data-val="true" data-val-required="The Date of Birth field is required." id="Member_DateOfBirth" name="Member.DateOfBirth" value="" /><br />
<input type="text" data-val="true" data-val-number="The field Salary must be a number." data-val-required="The Salary field is required." id="Member_Salary" name="Member.Salary" value="" /><br />
<input data-val="true" data-val-required="The Send spam to me field is required." id="Member_SendSpam" name="Member.SendSpam" type="checkbox" value="true" /><br />
<input type="number" id="Member_NumberOfCats" name="Member.NumberOfCats" value="" /><br />
<input type="file" id="Member_Selfie" name="Member.Selfie" /><br />
<button>Submit</button>
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8I..." />
<input name="Member.SendSpam" type="hidden" value="false" />
</form>
У меня есть собственный LabelTagHelper
, который устанавливает содержимое тега метки в Описание атрибута отображения. Эта часть работает нормально. Но мне нужно добавить атрибут тега «for», чтобы иметь значение идентификатора входного тега. Например, в поле Member_Name в строке <input type="text" id="Member_Name" name="Member.Name" value="" />
. Как мне получить значение Member_Name в вспомогательной функции настраиваемого тега для описания? Вот код LabelTagHelper
:
[HtmlTargetElement("label", Attributes = DescriptionForAttributeName)]
public class LabelDescriptionTagHelper : TagHelper
{
private const string DescriptionForAttributeName = "asp-description-for";
private const string ForAttribute = "for";
/// <summary>
/// Factory of StringLocalizer
/// </summary>
private readonly IStringLocalizerFactory _localizerFactory;
/// <summary>
/// Creates a new <see cref="LabelDescriptionTagHelper"/>.
/// </summary>
/// <param name="generator">The <see cref="IHtmlGenerator"/>.</param>
/// <param name="factory">Factory of string localizers</param>
public LabelDescriptionTagHelper(IHtmlGenerator generator, IStringLocalizerFactory factory) =>
(Generator, _localizerFactory) = (generator, factory);
/// <inheritdoc />
public override int Order => -1000;
[HtmlAttributeNotBound]
[ViewContext]
public ViewContext ViewContext { get; set; }
protected IHtmlGenerator Generator { get; }
/// <summary>
/// An expression to be evaluated against the current model.
/// </summary>
[HtmlAttributeName(DescriptionForAttributeName)]
public ModelExpression DescriptionFor { get; set; }
/// <inheritdoc />
/// <remarks>Does nothing if <see cref="DescriptionFor"/> is <c>null</c>.</remarks>
public override Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (output == null)
{
throw new ArgumentNullException(nameof(output));
}
if (DescriptionFor.Metadata is DefaultModelMetadata defaultMetadata)
{
// Get the DisplayAttribute from the selected property
object attributeObject = defaultMetadata
.Attributes
.PropertyAttributes
.FirstOrDefault(attr => attr is DisplayAttribute);
if (attributeObject != null && attributeObject is DisplayAttribute displayAttribute)
{
// Actual content of the description of the property
string description = displayAttribute.Description;
if (!string.IsNullOrEmpty(description))
{
// Get the type of the parent object of the selected property
Type parentType = DescriptionFor.Metadata.ContainerType;
// Get the string localizer of the parent type by using the stirng localizer factory
IStringLocalizer localizer = _localizerFactory.Create(parentType);
// Get the description from the localizer
description = localizer[description];
}
// Set the content of the tag to the description content
output.Content.SetContent(description);
// HERE'S HERE I NEED TO SET THE ID OF THE INPUT TAG. HOW?
output.Attributes.Add(ForAttribute, DescriptionFor.Metadata.Name);
output.TagMode = TagMode.StartTagAndEndTag;
}
}
return Task.CompletedTask;
}
}