ASP. NET Core - Как получить входной идентификатор из asp -для помощника тега в другом настраиваемом помощнике тега - PullRequest
0 голосов
/ 05 августа 2020

С классом модели 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;
        }
    }

1 Ответ

0 голосов
/ 05 августа 2020

Вы имеете в виду, что в <label></label><input asp-for="xxx" />, пусть <label> получает asp-for на входе. Если это так, я думаю, что в label он не может получить asp-for. Потому что может быть много input и много asp-for в представлении, а label не может определить местоположение asp-for.

Если вы хотите получить asp-for, вы можете добавить asp-for в label как <label asp-for="Member.Name"></label> .Так что можно использовать вот так.

public ModelExpression AspFor { get; set; }
 public override Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            string name = this.AspFor.Name;
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...