自定义属性,用于更改html表单元素的名称属性

时间:2015-02-06 20:20:39

标签: asp.net-mvc custom-attributes

我需要在表单中呈现的表单元素的名称中添加前缀。我已经创建了一个自定义属性来装饰一个属性,该属性接受另一个属性的名称,该属性的值将用于名称前缀。

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"/>

我有一些问题:

  1. 我不确定如何影响AddressModelMetadataProvider中呈现的名称html属性,或ModelMetadata中的哪个属性允许我这样做。我目前的尝试是更改PropertyName的{​​{1}}属性,但没有设置器。
  2. 如果可能,我不想创建新的HtmlHelper,因为此属性可以应用于将在ModelMetadata中呈现的任何类型的表单元素。我也不想创建字符串EditorTemplate,因为此场景仅适用于Address对象及其属性。

  3. 为了更好地理解我想要完成的事情以及为什么,让我简单解释一下这个项目及其目的。

    我们的应用程序允许用户创建“字段”。从最终用户的角度来看,“字段”可以是单行文本框,多行文本框(textarea),chooseMany(这是一组复选框),chooseOne(这是一个下拉列表),地址(由多个表单组成)元素,可以是家庭,商业或其他类型),联系人(电子邮件,电话,传真)等。我已经简化了很多,但我认为这是重点。

    所有这些信息都存储在db(“字段”值,“字段”元数据,“字段”在请求的“表单”中等),并且在运行时用于配置“表单”,用户是请求(即:/ forms / 123)。因此,表单可以具有文本框和地址“字段”,或者可以是家庭地址“字段”和商业地址“字段”。每个“表单”由管理用户创建和配置。这些“字段”或更确切的模型继承自IDataItem并拥有自己的视图(模板),用于描述如何将它们呈现给UI。

    由于“表单”的动态特性,需要自定义模型绑定和验证(即:自定义ValidationAttributes,ValidatorProviders,ModelBinders等)。验证规则和逻辑在运行时使用自定义和标准ValidationAttributes动态应用(即:RequiredAttribute用于简单的“字段”,如单行文本框或chooseOne)。这是在运行时完成的,因为构建“表单”的管理员可以根据需要标记“字段”(以及其他验证约束)。

    地址“字段”的必需验证是不同的,因为除非填写了地址的所有部分(地址2和地址3除外),否则地址不被视为完整。

    对于客户端验证,我们使用标准的mvc客户端验证库,jQuery验证。 这就是谎言我的问题...... jQuery根据表单元素的名称验证错误消息。因此,如果address1无效但表单上有一个家庭地址“field”和一个业务地址“field”,则需要在每个表单元素名称之间进行区分,以便可以将错误消息应用于正确的元素。 这是我需要在地址表单元素名称前添加Address 前缀的最大原因。

    这是一个非常冗长的简化说明,但我认为它会传达应用程序的目的以及我的问题存在的原因。希望这有助于澄清一些混乱。

0 个答案:

没有答案