FluentValidation.NET equivalent to [Display(Name)]



在fluentvalidation.net之前,我可以将自定义标签提供给像这样的适当标签:

[Display(Name="Blah")]
public string BlahBlahBlah { get; set; }

我可以通过几种方式消费:

@Html.LabelFor(m => m.BlahBlahBlah)
@Html.DisplayNameFor(m => m.BlahBlahBlah)
<label asp-for="BlahBlahBlah"></label>

现在,我想从我的模型中删除所有数据注释,然后移至流利的验证。在我的验证器中,我有一个:

RuleFor(o => o.BlahBlahBlah)
    .NotEmpty()
    .WithName("Blah");

但这不起作用。为什么?

WithName fluentValidation中的方法仅用于调整验证错误消息,如果要替换c#属性名称为smth更加用户友好(请参阅覆盖默认属性名称以获取详细信息)。

所以答案是 - 您不能通常用Display替换CC_2,而仅用于验证错误消息。

,如果它有帮助,我将一个小属性和助手扔在一起以使它更加动态。

intdisplayNameatTribute.cs

[AttributeUsage(AttributeTargets.Property)]
public class WithDisplayNameAttribute : Attribute
{
    public WithDisplayNameAttribute(string displayName)
    {
        DisplayName = displayName;
    }
    /// <summary>
    /// The preferred friendly name to display for this property during validation.
    /// </summary>
    public string DisplayName { get; set; }
}

intdisplaynamehelper.cs

internal static class WithDisplayNameHelper
{
    public static IReadOnlyDictionary<string, string> Map { get; }
    static WithDisplayNameHelper()
    {
        var core = typeof(WithDisplayNameHelper).Assembly;
        var map = new Dictionary<string, string>();
        foreach (var parentModelType in core.GetExportedTypes().Where(x => x.IsClass))
        {
            foreach (var prop in parentModelType.GetProperties())
            {
                var att = prop.GetCustomAttribute<WithDisplayNameAttribute>();
                if (att == null) continue;
                var key = GetKey(parentModelType, prop);
                if (!map.ContainsKey(key))
                {
                    map.Add(key, att.DisplayName);
                }
            }
        }
        Map = new ReadOnlyDictionary<string, string>(map);
    }
    /// <summary>
    /// Gets the key to use for this property.
    /// </summary>
    /// <param name="parent">The parent class containing the property.</param>
    /// <param name="prop">The property described by the display name.</param>
    /// <returns></returns>
    private static string GetKey(Type parent, PropertyInfo prop) => GetKey(parent, prop.Name);
    
    /// <inheritdoc cref="GetKey(System.Type,System.Reflection.PropertyInfo)"/>
    private static string GetKey(Type parent, string prop) => $"{parent.FullName}.{prop}";
    /// <summary>
    /// Retrieves the display name if one was set using the <see cref="WithDisplayNameAttribute"/>. Otherwise will return the given <paramref name="propertyName"/>.
    /// </summary>
    /// <param name="parent">The parent class containing the property.</param>
    /// <param name="propertyName">The property name.</param>
    /// <returns></returns>
    public static string GetDisplayNameOrDefault(Type parent, string propertyName) =>
        Map.TryGetValue(GetKey(parent, propertyName), out var value)
        ? value
        : propertyName;
    /// <summary>
    /// Attempts to retrieve the display name if one was set using the <see cref="WithDisplayNameAttribute"/>.
    /// </summary>
    /// <inheritdoc cref="GetDisplayNameOrDefault"/>
    /// <returns></returns>
    public static bool TryGetDisplayName(Type parent, string propertyName, out string result) =>
        Map.TryGetValue(GetKey(parent, propertyName), out result);

}

和扩展方法:

    /// <summary>
    /// Specifies a custom property name to use within the error message.
    /// </summary>
    /// <param name="rule">The current rule</param>
    /// <returns></returns>
    public static IRuleBuilderOptions<T, TProperty> WithDisplayName<T, TProperty>(
        this IRuleBuilderOptions<T, TProperty> rule)
    {
        
        return rule.Configure(x =>
        {
            if (WithDisplayNameHelper.TryGetDisplayName(typeof(T), x.PropertyName, out var displayName))
                x.DisplayName = new StaticStringSource(displayName);
        });
    }

相关内容

  • 没有找到相关文章

最新更新