【问题标题】:Getting property attributes in TagHelpers在 TagHelpers 中获取属性属性
【发布时间】:2023-03-22 08:23:01
【问题描述】:

一些模型属性具有“必需”数据注释,我需要在 TagHelper 类中读取。

public partial class Sale
{
    [Required]
    public string CustomerId { get; set; }
    ...

在销售视图中,我为客户创建了一个自定义选择:

<customer asp-for="CustomerId " value="@Model.CustomerId"></customer>

并且在 CustomerTagHelper 类中还有 process 方法:

public override void Process(TagHelperContext context, TagHelperOutput output)
{

此时我如何发现当前绑定属性是否具有“必需”属性?我正在使用 asp-net 核心。

【问题讨论】:

    标签: c# asp.net-core tag-helpers


    【解决方案1】:

    您可以通过ModelExpression访问自定义属性。

    public class CustomTagHelper : TagHelper
    {
        [HtmlAttributeName("asp-for")]
        public ModelExpression For { get; set; }
    
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {            
            CustomAttribute attribute = For.Metadata
                                           .ContainerType
                                           .GetProperty(For.Name)
                                           .GetCustomAttribute(typeof(CustomAttribute)) 
                                           as CustomAttribute;
            if (attribute != null)
            {
                output.Attributes.Add("some-attr", attribute.Text);
            }
        }
    }
    

    然后在你的模板中使用它&lt;custom asp-for="SomeProp"&gt;&lt;/custom&gt;

    【讨论】:

    • 看起来属性名称必须是 [HtmlAttributeName("asp-for")] 使用 [HtmlAttributeName("for")]does not work for me ASP.NET core 2.2
    【解决方案2】:

    标签助手不知道除了您为其属性提供的输入之外的任何内容。所以你想创建一个标签助手,你可以使用如下:

    @model WebApplication4.Models.Sale
    ...
    <customer asp-for="CustomerId" />
    

    然后您将声明与asp-for 属性关联的ModelSource 类型的属性。这将使您不仅可以访问属性的值,还可以访问如下元数据(以及更多!):

    • 属性值:source.Model
    • 属性名称:source.Name
    • 容器型号类型:source.Metadata.ContainerType
    • IsRequired 标志: source.Metadata.IsRequired

    您还将在 VS 中获得智能感知,以便为 asp-for 模型选择模型中的属性之一,如果该值不是模型属性的名称,则会引发错误。


    作为一个例子,看看这个标签助手:

    public class CustomerTagHelper: TagHelper
    {
        [HtmlAttributeName("asp-for")]
        public ModelExpression Source { get; set; }
    
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            output.TagName = "p";
            output.TagMode = TagMode.StartTagAndEndTag;
    
            var contents = $@"
                Model name: {Source.Metadata.ContainerType.FullName}<br/>
                Property name: {Source.Name}<br/>
                Current Value: {Source.Model}<br/> 
                Is Required: {Source.Metadata.IsRequired}";
    
            output.Content.SetHtmlContent(new HtmlString(contents));
        }
    }
    

    那么如果你有这两个模型:

    public class Sale
    {
        [Required]
        public string CustomerId { get; set; }
    }
    public class Promotion
    {        
        public string CustomerId { get; set; }
    }
    

    这两个动作和视图中使用了哪些:

    public IActionResult Sale()
    {
        return View();
    }
    
    @model WebApplication4.Models.Sale
    ...
    <customer asp-for="CustomerId" />
    
    
    public IActionResult Promotion()
    {
        return View(new Models.Promotion { CustomerId = "abc-123" });
    }
    
    @model WebApplication4.Models.Promotion
    ...
    <customer asp-for="CustomerId" />
    

    将产生这些输出:

    Tag helper for: WebApplication4.Models.Sale
    Property name: CustomerId
    Current Value: 
    Is Required: True
    
    Model name: WebApplication4.Models.Promotion
    Property name: CustomerId
    Current Value: abc-123
    Is Required: False
    

    【讨论】:

    • 我使用“For.Metadata.IsRequired”而不是“Source.Metadata.IsRequired”。工作。
    • 是的,无论您使用什么名称,fpr 类型的属性都是ModelExpression
    • 访问其他属性怎么样?
    • 查看Source.Metadata,因为它使您可以访问有关该特定模型属性的更多信息,包括其类型及其包含类型
    【解决方案3】:

    你可以这样做:

        var type = typeof(YOUR_CLASS);
        var property = type.GetProperty("FIELD_NAME");
        var isRequired = Attribute.IsDefined(property, typeof(Required));
    

    【讨论】:

      猜你喜欢
      • 2015-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多