gpt4 book ai didi

asp.net-mvc - 将新属性添加到 MVC ModelMetadata

转载 作者:行者123 更新时间:2023-12-02 23:15:18 25 4
gpt4 key购买 nike

我看到了替代方法,例如AdditionalValues,但我想知道是否有可能最终出现这样的情况:您可以向模板 View 中可用的 ModelMetadata 对象添加新属性。

例如,您可以:

@ViewData.ModelMetadata.MvvmBound

我想在编辑器和显示模板中使用它来将 MVVM 属性添加到正在呈现的 HTML 元素中。

我完全迷失了,但这是我迄今为止的努力:

public class MyModelMetaDataProvider : DataAnnotationsModelMetadataProvider
{
protected new MyModelMetaData CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
{
ModelMetadata modelMetaData = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
MyModelMetaData myMetaData = (MyModelMetaData)modelMetaData;

return myMetaData;
}
}

public class MyModelMetaData: ModelMetadata
{
public MyModelMetaData(ModelMetadataProvider provider, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
: base(provider, containerType, modelAccessor, modelType, propertyName)
{

}

public int MyProperty { get; set; }
}

然后在全局 asax 中我使用:

ModelMetadataProviders.Current =new MyModelMetaDataProvider();

问题是,如果我尝试在 View 中使用 MyProperty,它无法被识别,这是我预料到的,因为 VS 不知道自定义 ModelMetadata 类。

我什至不确定这是否可能?

最佳答案

有一本字典AdditionalValuesModelMetadata类(class)。 Ref here

您可以使用 AdditionalMetadata 将值添加到该字典中属性,如:

public class DummyModel
{
[AdditionalMetadata("MvvmBound", true)]
public string PropertyA{ get; set; }

public string PropertyB{ get; set; }
}

您可以在 string 中检查这些内容编辑器模板,例如:

@{
bool isBound = false;
if(ViewData.ModelMetadata.AdditionalValues.ContainsKey("MvvmBound"))
{
isBound = (bool)ViewData.ModelMetadata.AdditionalValues["MvvmBound"];
}
}

//use isBound to set some attributes in the html element

您可能还想在 DummyModel 的编辑器模板中检查这些属性。 ,您可以检索各个属性的元数据,如下所示:

@ModelMetadata.FromLambdaExpression(x => x.PropertyA, ViewData).AdditionalValues["MvvmBound"] 

这段代码本身有一些缺点。该方法需要将键名称传递给AdditionalValues 字典,并且您还需要将值从对象转换为正确的类型。您可以创建自己的扩展方法来从元数据中检索该值,而无需手动提供键名称并手动执行转换:

public static class ModelMetadataExtensions
{
public static bool IsMvvmBound(this ModelMetadata metadata)
{
if (!metadata.AdditionalValues.ContainsKey("MvvmBound")) return false;
return (bool)metadata.AdditionalValues["MvvmBound"];
}
}

这将使您在编辑器模板中获得更清晰的代码。例如,在 DummyModel 的编辑器模板中上面你可以做类似的事情(记住将扩展方法的命名空间添加到/Views 文件夹内的 Web.config 文件):

<h3>WholeModel Is MvvmBound?: @ViewData.ModelMetadata.IsMvvmBound()</h3>
<h3>PropertyA Is MvvmBound?: @ModelMetadata.FromLambdaExpression(x => x.PropertyA, ViewData).IsMvvmBound()</h3>
<h3>PropertyB Is MvvmBound?: @ModelMetadata.FromLambdaExpression(x => x.PropertyB, ViewData).IsMvvmBound()</h3>

您可以将该扩展方法与扩展 IMetadataAware 的自定义属性配对。因此,每次在属性上使用元数据值的键名称时,您无需对其进行硬编码:

public class IsMvvmBoundAttribute : Attribute, IMetadataAware 
{
public IsMvvmBoundAttribute()
{
this.IsMvvmBound = true;
}

public bool IsMvvmBound { get; set; }

//This is the single method of IMetadataAware, and what allows us to add the values into the AdditionalValues dictionary
public void OnMetadataCreated(ModelMetadata metadata)
{
metadata.AdditionalValues.Add("MvvmBound", this.IsMvvmBound);
}
}

public class DummyModel
{
//[AdditionalMetadata("MvvmBound", true)] <- replaced with the new attribute
[IsMvvmBoundAttribute]
public string PropertyA{ get; set; }

public string PropertyB{ get; set; }
}

因为ModelMetadata.AdditionalValuesDictionary<string,object> ,您不限于为每个键存储一个简单的值。您可以按照上面的代码创建自己的类,其中包含您需要的所有属性、可用于设置每个值并将该类的实例保存到 AnotherValues 字典的属性以及提取该实例的扩展方法字典中该类的名称。

正如您所看到的,您可以走很远而不需要您自己的 ModelMetadata类或扩展 ModelMetadataProvider .

希望对你有帮助!

关于asp.net-mvc - 将新属性添加到 MVC ModelMetadata,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22834146/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com