4

我想知道是否有可能获取生成元素的 HTML 属性“ID”,链接 ASP.NET Web Forms Field.ClientID。

所以我想要完成的是在 JavaScript 中获取 id 。目前我正在使用表单验证器,所以我有

剃刀模板

@Html.TextEditorFor(m => m.aspnet_Membership.Email);

然后 JS 进行验证

$('#MyForm').validate({
   rules : {
      //and this is the part where I need email ID
      //I can do this by manually typing aspnet_Membership_Email
      //but I'm asking is there a way to get it like 
      @Html.GetElementID(m => m.aspnet_Membership.Email): {
        required: true,
        email: true
     }
   }
});

有很多字段,所以我需要这个以避免用户输入错误,如 apsnet .....

记住 JS 在模板中。不在外部 js 文件中。(我不是初学者:))

请不要只关注 Validator,我已将其添加为示例。如果我为表单中的每个字段添加将来的前缀以便在页面上具有唯一的 ID,那么如果字段 ID 是固定的,我会遇到修复我的 js 的问题。

提前致谢。

4

4 回答 4

2

助手IdFor可以帮助您完成此任务:

@html.IdFor(m => m.aspnet_Membership.Email)
于 2012-11-27T19:15:57.670 回答
1

我会编写自己的扩展方法:

public static class Helper
{
    public static MvcHtmlString GetElementID<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
    {
        return MvcHtmlString.Create(GetPropertyName(expression));
    }

    private static string GetPropertyName(Expression lambdaExpression)
    {
        IList<string> list = new List<string>();
        var e = lambdaExpression;

        while (true)
        {
            switch (e.NodeType)
            {
                case ExpressionType.Lambda:
                    e = ((LambdaExpression)e).Body;
                    break;
                case ExpressionType.MemberAccess:
                    var propertyInfo = ((MemberExpression)e).Member as PropertyInfo;
                    var prop = propertyInfo != null
                                      ? propertyInfo.Name
                                      : null;
                    list.Add(prop);

                    var memberExpression = (MemberExpression)e;
                    if (memberExpression.Expression.NodeType != ExpressionType.Parameter)
                    {
                        var parameter = GetParameterExpression(memberExpression.Expression);
                        if (parameter != null)
                        {
                            e = Expression.Lambda(memberExpression.Expression, parameter);
                            break;
                        }
                    }
                    return string.Join("_", list.Reverse());
                default:
                    return null;
            }
        }
    }

    private static ParameterExpression GetParameterExpression(Expression expression)
    {
        while (expression.NodeType == ExpressionType.MemberAccess)
        {
            expression = ((MemberExpression)expression).Expression;
        }
        return expression.NodeType == ExpressionType.Parameter ? (ParameterExpression)expression : null;
    }
}

以及导致aspnet_Membership_Email的用法:

@Html.GetElementID(m => m.aspnet_Membership.Email);

这为您提供了基于 lambda 表达式的串联属性链。基本上它类似于@Html.IdForMVC4 中的实现(但是我不检查它们的实现)。

于 2012-11-27T19:27:09.447 回答
0

我认为您对 ID 生成逻辑进行了封装,尽管它相对简单。您的 Html 帮助器想法似乎是一种有效的方法(而不是说,在模型中公开一堆 ID 值和字段值)。

但是,我很好奇您为什么不使用不显眼的验证功能并让它为您生成验证器?

如果您将 [Required] 属性添加到您的 Email 属性并在页面中包含不显眼的验证器 javascript,那么您现在正在喝 pina coladas。

在您的模型中:

[Required]
[Display(Name = "First Name")]
[RegularExpression("([\r-~])*", ErrorMessageResourceType = typeof (AccountMessages),
    ErrorMessageResourceName = "FormFieldInvalid")]
[StringLength(50)]
public string FirstName { get; set; }

在您的标记中:

@Html.LabelFor(model => model.User.FirstName)
@Html.TextBoxFor(model => model.User.FirstName)  
@Html.ValidationMessageFor(model => model.User.FirstName, null, new { @class = "errorMessageField" })
于 2012-11-27T19:15:26.373 回答
0

框架用来构建名称的类(不是每个 ID)是一个静态类ExpressionHelper,它在 MVC3 中是可公开访问的。它有一个名为的函数GetExpressionText,它接受一个 lambda。话虽如此,您必须制作自己的 IdFor 包装器才能从中获取所需的语法。

这是 MVC4 中存在的类:

public static class NameExtensions
{
    public static MvcHtmlString Id(this HtmlHelper html, string name)
    {
        return MvcHtmlString.Create(html.AttributeEncode(html.ViewData.TemplateInfo.GetFullHtmlFieldId(name)));
    }

    [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
    [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Users cannot use anonymous methods with the LambdaExpression type")]
    public static MvcHtmlString IdFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression)
    {
        return Id(html, ExpressionHelper.GetExpressionText(expression));
    }

    public static MvcHtmlString IdForModel(this HtmlHelper html)
    {
        return Id(html, String.Empty);
    }

    [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", MessageId = "1#", Justification = "This is a shipped API.")]
    public static MvcHtmlString Name(this HtmlHelper html, string name)
    {
        return MvcHtmlString.Create(html.AttributeEncode(html.ViewData.TemplateInfo.GetFullHtmlFieldName(name)));
    }

    [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
    [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Users cannot use anonymous methods with the LambdaExpression type")]
    public static MvcHtmlString NameFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression)
    {
        return Name(html, ExpressionHelper.GetExpressionText(expression));
    }

    public static MvcHtmlString NameForModel(this HtmlHelper html)
    {
        return Name(html, String.Empty);
    }
}
于 2012-11-27T19:27:50.347 回答