我需要在表单中呈现的表单元素的名称中添加前缀。我已经创建了一个自定义属性来装饰一个属性,该属性接受另一个属性的名称,该属性的值将用于名称前缀。
public class HtmlElementNamePrefixPropertyAttribute : Attribute {
public string PropertyName { get; set; }
public HtmlElementNamePrefixPropertyAttribute(string propertyName) {
PropertyName = propertyName;
}
}
我的自定义ModelMetadataProvider
public class AddressModelMetadataProvider : DataAnnotationsModelMetadataProvider {
protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName) {
ModelMetadata metadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
HtmlElementNamePrefixPropertyAttribute nameAttribute = attributes.OfType<HtmlElementNamePrefixPropertyAttribute>().FirstOrDefault();
if (nameAttribute != null) {
ModelMetadata prefixMetadata = ModelMetadataProviders.Current.GetMetadataForProperty(modelAccessor, metadata.ContainerType, nameAttribute.PropertyName);
metadata.PropertyName = string.Format("{0}{1}", prefixMetadata.Model, metadata.PropertyName);
}
return metadata;
}
}
例如,如果我用Address1
HtmlElementNamePrefixAttribute
[HtmlElementNamePrefix("AddressType")]
public string Address1 { get; set; }
public AddressType AddressType { get; set; }
在我的视图中,为Address1
@Html.TextBoxFor(m => m.Address1)
它应呈现为(假设AddressType == AddressType.Home
)
<input name="HomeAddress1" value="123 Street way"/>
我有一些问题:
AddressModelMetadataProvider
中呈现的名称html属性,或ModelMetadata
中的哪个属性允许我这样做。我目前的尝试是更改PropertyName
的{{1}}属性,但没有设置器。ModelMetadata
中呈现的任何类型的表单元素。我也不想创建字符串EditorTemplate,因为此场景仅适用于Address
对象及其属性。 为了更好地理解我想要完成的事情以及为什么,让我简单解释一下这个项目及其目的。
我们的应用程序允许用户创建“字段”。从最终用户的角度来看,“字段”可以是单行文本框,多行文本框(textarea),chooseMany(这是一组复选框),chooseOne(这是一个下拉列表),地址(由多个表单组成)元素,可以是家庭,商业或其他类型),联系人(电子邮件,电话,传真)等。我已经简化了很多,但我认为这是重点。
所有这些信息都存储在db(“字段”值,“字段”元数据,“字段”在请求的“表单”中等),并且在运行时用于配置“表单”,用户是请求(即:/ forms / 123)。因此,表单可以具有文本框和地址“字段”,或者可以是家庭地址“字段”和商业地址“字段”。每个“表单”由管理用户创建和配置。这些“字段”或更确切的模型继承自IDataItem并拥有自己的视图(模板),用于描述如何将它们呈现给UI。
由于“表单”的动态特性,需要自定义模型绑定和验证(即:自定义ValidationAttributes,ValidatorProviders,ModelBinders等)。验证规则和逻辑在运行时使用自定义和标准ValidationAttributes动态应用(即:RequiredAttribute用于简单的“字段”,如单行文本框或chooseOne)。这是在运行时完成的,因为构建“表单”的管理员可以根据需要标记“字段”(以及其他验证约束)。
地址“字段”的必需验证是不同的,因为除非填写了地址的所有部分(地址2和地址3除外),否则地址不被视为完整。
对于客户端验证,我们使用标准的mvc客户端验证库,jQuery验证。 这就是谎言我的问题...... jQuery根据表单元素的名称验证错误消息。因此,如果address1无效但表单上有一个家庭地址“field”和一个业务地址“field”,则需要在每个表单元素名称之间进行区分,以便可以将错误消息应用于正确的元素。 这是我需要在地址表单元素名称前添加Address
前缀的最大原因。
这是一个非常冗长的简化说明,但我认为它会传达应用程序的目的以及我的问题存在的原因。希望这有助于澄清一些混乱。