我希望设置一个 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] 删除。
我来说两句