GetFullHtmlFieldId返回不正确的id属性值 [英] GetFullHtmlFieldId returning incorrect id attribute value
问题描述
我使用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屋!