HumanizerMetadataProvider 实现不适用于 Razor 页面模型

夏兰·加拉格尔

我希望设置一个 ASP.NET Core 应用程序,以便模型中的属性名称以某种方式自动“人性化”(例如,在属性名称中添加空格)。

例如,这是我的 SystemSettings 模型:

public class SystemSettings : IEntityBase
{
    public int Id { get; set; }

    [Display(Description = "Emails sent from system will be sent from this address.")]
    public string EmailFromAddress { get; set; }

    [Display(Description = "Name of the organisation")]
    public string CompanyName { get; set; }

    [Display(Description = "Name of the web application")]
    public string ProductName { get; set; }
}

我的目标是默认情况下自动设置每个属性的显示名称(但可以覆盖)。例如,默认情况下“EmailFromAddress”属性将具有标签“Email From Address”)。

为了实现这个目标,我看到了一段这样的代码:

public class HumaniserMetadataProvider : IDisplayMetadataProvider
{
    public void CreateDisplayMetadata(DisplayMetadataProviderContext context)
    {
        var propertyAttributes = context.Attributes;
        var modelMetadata = context.DisplayMetadata;
        var propertyName = context.Key.Name;

        if (IsTransformRequired(propertyName, modelMetadata, propertyAttributes))
        {
            modelMetadata.DisplayName = () => SplitCamelCase(propertyName);
        }
    }

    private static string SplitCamelCase(string str)
    {
        return Regex.Replace(
            Regex.Replace(
                str,
                @"(\P{Ll})(\P{Ll}\p{Ll})",
                "$1 $2"
            ),
            @"(\p{Ll})(\P{Ll})",
            "$1 $2"
        );
    }

    private static bool IsTransformRequired(string propertyName, DisplayMetadata modelMetadata, IReadOnlyList<object> propertyAttributes)
    {
        if (!string.IsNullOrEmpty(modelMetadata.SimpleDisplayProperty))
            return false;

        if (propertyAttributes.OfType<DisplayNameAttribute>().Any())
            return false;

        if (propertyAttributes.OfType<DisplayAttribute>().Any())
            return false;

        if (string.IsNullOrEmpty(propertyName))
            return false;

        return true;
    }
}

在我看到该代码的地方,他们在 Startup.cs 类中启用了它,如下所示:

services.AddRazorPages()
    .AddMvcOptions(options =>
    {
        options.ModelMetadataDetailsProviders.Add(new HumaniserMetadataProvider());
    });

然而,当我自己用 Razor Page 尝试这个时,标签没有以任何方式转换——它仍然是“EmailFromAddress”。为什么这行不通?我还尝试将 Razor Page 转换为 MVC 控制器,但这也没有任何区别。

这是我视图中的一个片段,它指定了“SystemSettings”的模型:

<form method="post">
    @Html.EditorFor(x => x.EmailFromAddress)
    <div class="row m-t-md">
        <div class="col-12">
            <button type="submit" class="btn btn-primary">Submit</button>
        </div>
    </div>
</form>

EditorFor 呈现此字符串模板:

@model string <div class="form-group">
    <label asp-for="@Model" class="m-b-none"></label>
    <span asp-description-for="@Model" class="help-block m-b-none small m-t-none"></span>
    <div class="input-group">
        <input asp-for="@Model" class="form-control" />
        <vc:text-box></vc:text-box>
        <partial name="_ValidationIcon" />
    </div>
    <span asp-validation-for="@Model" class="validation-message"></span> </div>
夏兰·加拉格尔

问题是因为 HumanizerMetadataProvider 中的这一行:

if (propertyAttributes.OfType<DisplayAttribute>().Any())
            return false;

我的模型有一个 [Display] 属性,我在其中指定了这样的描述:

[Display(Description = "Emails sent from system will be sent from this address.")]
public string EmailFromAddress { get; set; }

为了解决这个问题,我检查了 Display 属性的 'Name' 属性的值是 null 还是空。如果是,那么我允许转换。我修改了 HumanizerMetadataProvider 中的代码,如下所示:

if (propertyAttributes.OfType<DisplayAttribute>().Any())
{
    var displayName = modelMetadata.DisplayName?.Invoke();
    return string.IsNullOrEmpty(displayName);
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

页面对象模型不适用于Selenium Python

JsonConverter不适用于模型绑定

Django ORM不适用于模型

迁移不适用于特定模型

模态不适用于模型

自动递增不适用于模型

导航不适用于aspx页面

CSS 适用于 HTML 但不适用于 Razor 语法

Django:UniqueConstraint 验证器既不适用于模型也不适用于中间模型

404错误页面不适用于错误的动态页面

.htaccess重定向仅适用于某些页面,而不适用于其他页面

ASP.NET MVC模型绑定不适用于AJAX GET,但适用于Post

Opengl 照明适用于顶部、底部、正面、背面,但不适用于模型的侧面

Tensorflow Lite .tflite 模型不适用于 iOS,但适用于 android

Django:表单适用于索引,但不适用于特定页面

sendRedirect不适用于jsp,但适用于html页面

GitHub Pages Jekyll主题适用于页面,但不适用于帖子

为什么 CSS 规则不适用于真正的 HTML 页面,但适用于 JSFiddle?

从 localStorage 检索对象适用于控制台日志,但不适用于页面

EF Core适用于剃须刀页面,但不适用于MVC

自定义存档页面不适用于日期或标签,但适用于类别

curl似乎不适用于“动态Blogspot模型”

FluentValidation 不适用于外部模型对象的集合

update()不适用于通过lapply()创建的模型

SceneJS导入模型不适用于IE

Laravel isNotEmpty() 不适用于 Eloquent 模型

Vue选择的道具不适用于v模型

Sequelize模型关联不适用于打字稿

R Metric RMSE不适用于分类模型