GetFullHtmlFieldId返回不正确的id属性值 [英] GetFullHtmlFieldId returning incorrect id attribute value

查看:248
本文介绍了GetFullHtmlFieldId返回不正确的id属性值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用ASP.NET MVC 2,但我不认为我已经听说过这个被固定在MVC 3或4,但不管怎么说:

I'm using ASP.NET MVC 2, but I don't think I've heard about this being fixed in MVC 3 or 4, but anyway:

这是我的测试视图code:

This is my test view code:

<br />
<%= Html.LabelFor( m => m.FieldFoo ) %>
<%= Html.TextBoxFor( m => m.FieldFoo ) %>

<br />
<%= Html.LabelFor( m => m.CustomFieldValues[0].Value ) %>
<%= Html.TextBoxFor( m => m.CustomFieldValues[0].Value ) %>

而这就是呈现:

<br />
<label for="FieldFoo">Foo?</label>
<input id="FieldFoo" name="FieldFoo" type="text" value="foo" />

<br />
<label for="CustomFieldValues[0]_Value">Value</label>
<input id="CustomFieldValues_0__Value" name="CustomFieldValues[0].Value" type="text" value="bar" />

现货的区别:索引属性 CustomFieldValues​​ 是不是有它的 []取代字符 _ 为=属性。为什么呢?

Spot the difference: the indexed property CustomFieldValues is not having its [ and ] characters replaced with _ for the for="" attribute. Why?

我踩了 LabelFor code里面,看到它调用 html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName)); 而MVC的内部 InputHelper 已使用其自己的逻辑 TagBuilder.CreateSanitizedId()这就解释了为什么它变得不同 ID =属性值。

I stepped inside the LabelFor code and saw that it calls html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName)); whereas MVC's internal InputHelper has its own logic using TagBuilder.CreateSanitizedId() which explains why it's getting different id="" attribute values.

有没有MVC 2的解决方法呢?

Is there any workaround for this in MVC 2?

推荐答案

ASP.NET MVC 2没有与htmlAttributes parameteres LabelFor扩展方法。看到这个<一个href=\"http://weblogs.asp.net/imranbaloch/archive/2010/07/03/asp-net-mvc-labelfor-helper-with-htmlattributes.aspx\"相对=nofollow>博客文章。我们可以创建一个扩展,这将增加该放慢参数,以及解决您的上述问题。下面是示例,

ASP.NET MVC 2 doesn't have LabelFor extension method with htmlAttributes parameteres. See this blog post. We can create an extension which will add this paramter as well as solve your above issue. Here is the sample,

public static class MyTagBuilder
{
    public static string CreateSanitizedId(string originalId)
    {
        return CreateSanitizedId(originalId, HtmlHelper.IdAttributeDotReplacement);
    }

    public static string CreateSanitizedId(string originalId, string invalidCharReplacement)
    {
        if (String.IsNullOrEmpty(originalId))
        {
            return null;
        }

        if (invalidCharReplacement == null)
        {
            throw new ArgumentNullException("invalidCharReplacement");
        }

        char firstChar = originalId[0];
        if (!Html401IdUtil.IsLetter(firstChar))
        {
            // the first character must be a letter
            return null;
        }

        StringBuilder sb = new StringBuilder(originalId.Length);
        sb.Append(firstChar);

        for (int i = 1; i < originalId.Length; i++)
        {
            char thisChar = originalId[i];
            if (Html401IdUtil.IsValidIdCharacter(thisChar))
            {
                sb.Append(thisChar);
            }
            else
            {
                sb.Append(invalidCharReplacement);
            }
        }

        return sb.ToString();
    }

    private static class Html401IdUtil
    {
        private static bool IsAllowableSpecialCharacter(char c)
        {
            switch (c)
            {
                case '-':
                case '_':
                case ':':
                    // note that we're specifically excluding the '.' character
                    return true;

                default:
                    return false;
            }
        }

        private static bool IsDigit(char c)
        {
            return ('0' <= c && c <= '9');
        }

        public static bool IsLetter(char c)
        {
            return (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'));
        }

        public static bool IsValidIdCharacter(char c)
        {
            return (IsLetter(c) || IsDigit(c) || IsAllowableSpecialCharacter(c));
        }
    }

}
public static class LabelExtensions
{
    public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object htmlAttributes)
    {
        return LabelFor(html, expression, new RouteValueDictionary(htmlAttributes));
    }
    public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, IDictionary<string, object> htmlAttributes)
    {
        ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
        string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
        string labelText = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last();
        if (String.IsNullOrEmpty(labelText))
        {
            return MvcHtmlString.Empty;
        }

        TagBuilder tag = new TagBuilder("label");
        tag.MergeAttributes(htmlAttributes);
        tag.Attributes.Add("for", MyTagBuilder.CreateSanitizedId(html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(htmlFieldName)));
        tag.SetInnerText(labelText);
        return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal));
    }
}


<%@ Import Namespace="NameSpaceOfTheExtensionMethodClass" %>


<%= Html.LabelFor(m => m.CustomFieldValues[0].Value, new { })%>
<%= Html.TextBoxFor( m => m.CustomFieldValues[0].Value )%>

这篇关于GetFullHtmlFieldId返回不正确的id属性值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆