MVC 6自定义Taghelper验证-解决方案



从我几年前创建的HtmlHelpers开始,我有一个自定义Taghelper,它在开发过程中被标记为…

    <gdropdown asp-for="Type_ID" asp-items="cboType_SelectOne"></gdropdown>

一切正常,输出如下。。。

    <div>
        <select id="Type_ID" name="Type_ID">
            <option value=-1> - Select One - </option>
            <option value=9>Aux. Ext. Device</option>
            <option value=28>Backup Device</option>
            ...
        </select>
    </div>

现在,我正在寻求帮助来制作我自己的验证SPAN,以添加到输出中,如下所示。。。

    <div>
        <select id="Type_ID" name="Type_ID">
            <option value=-1> - Select One - </option>
            <option value=9>Aux. Ext. Device</option>
            <option value=28>Backup Device</option>
            ...
        </select>
        <span class="field-validation-valid" data-valmsg-replace="true" data-valmsg-for="Type_ID">
            <span for="Type_ID">Req!</span>
        </span>
    </div>

无论如何,我可以完成创建SPAN的基础工作,但我无法获得正在添加/编辑的字段的数据注释。

使用HtmlHelpers,我可以使用如下所示的htmlHelper.ValidationMessageFor()来自动生成输出。。。

    public static MvcHtmlString CustomLookupFor2<TModel, TValue>(this HtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, TValue>> exp, string url, bool includeValidation, object options)
    {
        ...
        if (includeValidation) sbCtrls.Append(htmlHelper.ValidationMessageFor(expression));
        ...
    }

从TagHelper ProcessAsync方法中,如何获取相同或相似的数据注释信息?或者更好的是,我如何以与上述类似的方式完全自动生成验证元素?

***解决方案-2016年3月13日***

您可以使用通过asp-for属性传入的ModelExpression。更具体地说是modExp.Metadata.ValidatorMetadata类。

我发现旧的验证注释方法还不能用于EF7。至少不是以我习惯的方式。

    [MetadataType(typeof(IT_AssetValidation))]
    public partial class IT_Asset
    {
        public class IT_AssetValidation
        {
            [Range(1, 1000000, ErrorMessage = "Req!")]
            public string Product_ID { get; set; }
            [Required(ErrorMessage = "Req!")]
            public string Date_Acquired { get; set; }
        }
    }

目前,在EF7支持额外的数据注释之前,我必须直接在我的POCO类中创建注释(目前仅用于开发/测试目的),如下所示。考虑到我只使用一个表来帮助创建我的新TagHelpers,这并不是什么大问题。这让我可以继续开发这些TagHelper,为我最终过渡到MVC 6做好准备,一旦EF7功能齐全并稍微稳定下来。

    public partial class IT_Asset
    {
        public int Asset_ID { get; set; }
        [Required(ErrorMessage = "Req!")]
        public DateTime? Date_Acquired { get; set; }
        [Range(1, 1000000, ErrorMessage = "Req!")]
        public int? Product_ID { get; set; }
    }

现在创建我的验证<span data-...></span>的代码看起来有点像下面。

    public static TagBuilder ValidationTag(ModelExpression modExp)
    {
        if ((modExp != null) && (modExp.Metadata.ValidatorMetadata.Count > 0))
        {
            //Construct the HTML span template
            var valTag = new TagBuilder("span");
            valTag.Attributes.Add("class", "");
            valTag.Attributes.Add("data-valmsg-for", modExp.Name);
            return valTag;
        }
        else return null;
    }

用于派生正在验证的标记的验证属性的代码如下所示。这是早期的伪代码。我稍后可能会更新。

    public static string ValidationAttributes(ModelExpression modExp)
    {
        if ((modExp != null) && (modExp.Metadata.ValidatorMetadata.Count > 0))
        {
            var ruleAttributes = new StringBuilder();
            //*PSUEDO CODE* Return the rules 
            foreach(...) {
                 If (REQ) ruleAttributes.Append(REQ attribute)
                 If (RANGE) ruleAttributes.Append(RANGE attribute)
                 etc. etc.
            }
            return ruleAttributes.ToString();
        }
        else return "";
    }

如果有人知道有一种比我在这里的手动方法更自动的方法来创建验证标记,和/或推导被验证标记的属性,我将不胜感激。

随着代码和理解的发展,我将更新此解决方案。

最新更新