我有一个基于 asp.net core 3.1 的应用程序。我喜欢利用 Display-Templates 和 Editor-Templates 来创建编辑器视图。我正在尝试找出如何使用编辑器模板为菜单创建编辑器模板的最佳方法。
我的第一个想法是为菜单创建一个通用视图模型,然后可以使用自定义编辑器模板轻松呈现
在第一次尝试中,我创建了一个看起来像这样的通用视图模型
public abstract class MenuViewModel
{
[BindNever]
public IEnumerable<SelectListItem> Options { get; set; }
public MenuViewModel()
{
Options = new List<SelectListItem>();
}
}
public class MenuViewModel<T> : MenuViewModel
{
public T Value { get; set; }
}
然后我希望在像这样的其他视图模型中使用它
public class CreateLocation
{
public string Title { get; set; }
public MenuViewModel<string> State { get; set; }
}
我想我可以让上面的代码工作......但是,我试图找出一种方法来将任何ValiationAttributes
从State
属性传递到State.Value
属性。
例如,如果State
装饰有RequiredAttribute
怎么办?换句话说,如果我的视图模型看起来像这样
public class CreateLocation
{
public string Title { get; set; }
[Required]
public MenuViewModel<string> State { get; set; }
}
在这种情况下,要使模型状态有效,State
Property 不能为 null,并且该属性State.Value
还必须有一个值。
问题是,我怎样才能将所需的属性传递给属性,Value
而无需创建多个 menu-vm 之类的RequiredMenuViewModel
and OptionalMenuViewModel
?
我考虑过创建IDisplayMetadataProvider
. 但即便如此,我也不确定如何将验证属性从父属性传递给子属性。
public class MenuMetadataProvider : IDisplayMetadataProvider
{
public void CreateDisplayMetadata(DisplayMetadataProviderContext context)
{
if (!context.Key.ModelType.IsClass)
{
return;
}
if(context.Key.ModelType.IsAssignableFrom(typeof(MenuViewModel)))
{
metadata.TemplateHint = nameof(MenuViewModel);
}
// get any validation attributes on the parent
var attributes = context.Key.ModelType.GetCustomAttributes(typeof(ValidationAttribute), false);
if (!attributes.Any())
{
// Parent has not attributes, ignore it
return;
}
// iterate over the properties of the child object
foreach (PropertyInfo childPoperty in context.Key.ModelType.GetProperties())
{
// find a child property that is decorated with InheritAttributesFromParentAttribute
var canInherit = Attribute.IsDefined(childPoperty, typeof(InheritAttributesFromParent));
if (!canInherit)
{
continue;
}
// some how pass the attributes to the childPoperty
}
}
}