使用以下代码时,字段的id和标签的for属性中的id不相同.
x.Localizations["en"]) %> => Localizations[en]
x.Localizations["en"]) %> => Localizations_en_
x.Localizations["en"].Property) %>
=> Localizations[en]_Property
x.Localizations["en"].Property) %>
=> Localizations_en__Property
我在反射器中跟踪代码,发现生成值的方式不同.不使用相同的帮助方法.
LabelFor用途HtmlHelper.GenerateIdFromName和TextBoxFor用途TagBuilder#GenerateId.
有没有人知道这个的原因,或解决方法(除了编写你自己的整套输入/ textarea /选择助手)?或者这是一个错误?
更新:
因为我总是使用标签文本的第二个参数为标签使用html帮助器,我修改它以使用与表单字段助手相同的id生成代码.
public static MvcHtmlString LabelFor(this HtmlHelper helper, Expression> expression, string labelText)
{
// The main part of this code is taken from the internal code for Html.LabelFor(...).
var metaData = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
var fieldName = ExpressionHelper.GetExpressionText(expression);
TagBuilder builder = new TagBuilder("label");
// Generate the id as for the form fields (adds it to self).
builder.GenerateId(fieldName);
// Use the generated id for the 'for' attribute.
builder.Attributes.Add("for", builder.Attributes["id"]);
// Remove the id again.
builder.Attributes.Remove("id");
builder.SetInnerText(labelText);
return MvcHtmlString.Create(builder.ToString());
}
这解决了我的直接问题,但它没有回答为什么实现看起来像在MVC2中的问题.如果有原因的话.
顺便说一下:没有必要在HTML5中实际修改id/for属性,因为^~[]如果你愿意的话,拥有一个id是完全合法的.所有主流浏览器都支持它.Mathias Bynens很好地解释了这一点.
更新2:
这实际上并不能解决问题,因为DefaultModelBinder无论如何都无法绑定它.MVC 2中的字段名称生成器似乎不支持在字典中使用嵌套对象,因为它生成:
而不是模型绑定器想要的东西:
奇怪的是它以这种方式开箱即用.
我已经尝试为它创建一个自定义模型绑定器,但无论我尝试使用它,我都无法使用MVC2:
ModelBinders.Binders.Add(typeof(IDictionary), new DictionaryModelBinder());
ModelBinders.Binders.Add(typeof(IDictionary), new DictionaryModelBinder());
ModelBinders.Binders.Add(typeof(IDictionary), new DictionaryModelBinder());
ModelBinders.Binders.Add(typeof(Dictionary), new DictionaryModelBinder());
所以现在它似乎又回到了手动创建隐藏.Key字段的名称属性值.