Al usar el siguiente código, los id del campo y el id en el atributo for de la etiqueta no son idénticos.LabelFor y TextBoxFor no generan el mismo id.
<%: Html.LabelFor(x => x.Localizations["en"]) %> => Localizations[en]
<%: Html.TextBoxFor(x=> x.Localizations["en"]) %> => Localizations_en_
<%: Html.LabelFor(x => x.Localizations["en"].Property) %>
=> Localizations[en]_Property
<%: Html.TextBoxFor(x=> x.Localizations["en"].Property) %>
=> Localizations_en__Property
Rastreé el código en el reflector y vi que la forma en que se generan los valores es diferente. No usa el mismo método de ayuda.
LabelFor usa HtmlHelper.GenerateIdFromName
y TextBoxFor usa TagBuilder#GenerateId
.
¿Alguien sabe el motivo de esto o una solución alternativa (excepto escribir su propio conjunto completo de input/textarea/select helpers)? O se trata de un error?
ACTUALIZACIÓN:
Ya que de todos modos se utiliza un helper HTML para la etiqueta con un segundo parámetro para el texto de la etiqueta, que se modificó por utilizar el mismo código de identificación como la generación de los ayudantes de campo de formulario.
public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, string labelText)
{
// The main part of this code is taken from the internal code for Html.LabelFor<TModel, TValue>(...).
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());
}
esto resuelve mi problema inmediato, pero no responde a la pregunta de por qué la aplicación se ve como lo hace en MVC2. Si hay una razón para eso
Por cierto: no es necesario modificar realmente el atributo id/for en HTML5, ya que es perfectamente legal tener una identificación que se parezca a ^~[]
si lo desea. Todos los principales navegadores lo admiten. Esto está muy bien explicado por Mathias Bynens.
ACTUALIZACIÓN 2:
Esto no resuelve el problema en absoluto en realidad, ya que el DefaultModelBinder no puede unirse a él de todos modos. No parece el uso de objetos anidados en los diccionarios ser apoyado por el generador de nombres de campo en MVC 2, ya que genera:
<input type="text" name="Dict[en]" value="(VALUE)">
En lugar de lo que el ligante modelo quiere:
<input type="hidden" name="Dict[0].Key" value="en">
<input type="text" name="Dict[0].Value" value="(VALUE)">
extraño que sale de la caja de esta manera.
He intentado crear una carpeta de modelo personalizado para ello, pero no puedo conseguir MVC2 usarlo todo lo que trato de usarlo en:
ModelBinders.Binders.Add(typeof(IDictionary<string,object>), new DictionaryModelBinder());
ModelBinders.Binders.Add(typeof(IDictionary<string,string>), new DictionaryModelBinder());
ModelBinders.Binders.Add(typeof(IDictionary), new DictionaryModelBinder());
ModelBinders.Binders.Add(typeof(Dictionary), new DictionaryModelBinder());
Así que ahora mismo parece que es hora de volver a crear manualmente los valores de atributo de nombre con los campos ocultos .Key
.
he notado lo mismo. aunque nunca uso etiquetas en una estructura repetitiva. Yo uso una mesa ¿Lo intentó en un bucle foreach? ¿Cómo se ve eso? – Stefanvds
De hecho, lo uso en un bucle foreach, este fue un ejemplo simplificado con clave explícita para la legibilidad. –