我正在使用ASP.NET MVC 2,但我不认为我已经听说过在MVC 3或4中修复了这个问题,但无论如何:
这是我的测试视图代码:
<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
未将[
和]
字符替换为_
属性的for=""
。为什么呢?
我进入LabelFor
代码并看到它调用html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName));
而MVC的内部InputHelper
有自己的逻辑使用TagBuilder.CreateSanitizedId()
这解释了为什么它变得不同{{1}属性值。
MVC 2中是否有解决方法?
答案 0 :(得分:0)
ASP.NET MVC 2没有带有htmlAttributes参数的LabelFor扩展方法。见blog post。我们可以创建一个扩展,它将添加此参数以及解决您的上述问题。这是样本,
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 )%>