validar textboxfor net mvc htmlattributes formulario example asp asp.net asp.net-mvc

asp.net - textboxfor - htmlattributes razor



¿Por qué CheckBoxFor representa una etiqueta de entrada adicional y cómo puedo obtener el valor con FormCollection? (5)

Creo que la solución más simple es renderizar el elemento INPUT directamente de la siguiente manera:

<input type="checkbox" id="<%=Html.IdFor(i => i.ReceiveRSVPNotifications)%>" name="<%=Html.NameFor(i => i.ReceiveRSVPNotifications)%>" value="true" checked="<%=Model.ReceiveRSVPNotifications ? "checked" : String.Empty %>" />

En la sintaxis Razor es incluso más fácil, porque el atributo ''checked'' se representa directamente con un valor "checked" cuando se le da un valor ''verdadero'' del lado del servidor.

En mi aplicación ASP.NET MVC, estoy procesando una casilla usando el siguiente código:

<%= Html.CheckBoxFor(i=>i.ReceiveRSVPNotifications) %>

Ahora, veo que esto representa tanto la etiqueta de entrada como una etiqueta de entrada oculta. El problema que estoy teniendo es cuando intento recuperar el valor de la casilla usando FormCollection:

FormValues["ReceiveRSVPNotifications"]

Obtengo el valor "verdadero, falso". Cuando miro el HTML renderizado, puedo ver lo siguiente:

<input id="ReceiveRSVPNotifications" name="ReceiveRSVPNotifications" value="true" type="checkbox"> <input name="ReceiveRSVPNotifications" value="false" type="hidden">

Entonces, la colección FormValues ​​parece unir estos dos valores ya que tienen el mismo nombre.

¿Algunas ideas?


Echa un vistazo aquí:

http://forums.asp.net/t/1314753.aspx

Esto no es un error, y de hecho es el mismo enfoque que utilizan Ruby on Rails y MonoRail.

Cuando envía un formulario con una casilla de verificación, el valor solo se publica si la casilla de verificación está marcada. Por lo tanto, si deja la casilla de verificación sin marcar, no se enviará nada al servidor cuando en muchas situaciones desee que se envíe falso en su lugar. Como la entrada oculta tiene el mismo nombre que la casilla de verificación, si la casilla de verificación está desmarcada, recibirá un mensaje de "falso" en el servidor.

Cuando se marca la casilla de verificación, ModelBinder se encargará automáticamente de extraer el ''verdadero'' de ''verdadero, falso''


Tuve el mismo problema que Shawn (arriba). Este enfoque podría ser genial para POST, pero realmente apesta para GET. Por lo tanto, implementé una extensión Html simple que simplemente saca el campo oculto.

public static MvcHtmlString BasicCheckBoxFor<T>(this HtmlHelper<T> html, Expression<Func<T, bool>> expression, object htmlAttributes = null) { var result = html.CheckBoxFor(expression).ToString(); const string pattern = @"<input name=""[^""]+"" type=""hidden"" value=""false"" />"; var single = Regex.Replace(result, pattern, ""); return MvcHtmlString.Create(single); }

El problema que tengo ahora es que no quiero un cambio en el framework MVC para romper mi código. Así que tengo que asegurarme de tener cobertura de prueba que explique este nuevo contrato.


Utilizo este método alternativo para mostrar las casillas de los formularios GET:

/// <summary> /// Renders checkbox as one input (normal Html.CheckBoxFor renders two inputs: checkbox and hidden) /// </summary> public static MvcHtmlString BasicCheckBoxFor<T>(this HtmlHelper<T> html, Expression<Func<T, bool>> expression, object htmlAttributes = null) { var tag = new TagBuilder("input"); tag.Attributes["type"] = "checkbox"; tag.Attributes["id"] = html.IdFor(expression).ToString(); tag.Attributes["name"] = html.NameFor(expression).ToString(); tag.Attributes["value"] = "true"; // set the "checked" attribute if true ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData); if (metadata.Model != null) { bool modelChecked; if (Boolean.TryParse(metadata.Model.ToString(), out modelChecked)) { if (modelChecked) { tag.Attributes["checked"] = "checked"; } } } // merge custom attributes tag.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)); var tagString = tag.ToString(TagRenderMode.SelfClosing); return MvcHtmlString.Create(tagString); }

Es similar al método de Chris Kemp , que está funcionando bien, excepto que este no usa el CheckBoxFor y el Regex.Replace subyacentes. Se basa en la fuente del método original Html.CheckBoxFor .


Aquí está el código fuente para la etiqueta de entrada adicional. Microsoft tuvo la amabilidad de incluir comentarios que abordan esto con precisión.

if (inputType == InputType.CheckBox) { // Render an additional <input type="hidden".../> for checkboxes. This // addresses scenarios where unchecked checkboxes are not sent in the request. // Sending a hidden input makes it possible to know that the checkbox was present // on the page when the request was submitted. StringBuilder inputItemBuilder = new StringBuilder(); inputItemBuilder.Append(tagBuilder.ToString(TagRenderMode.SelfClosing)); TagBuilder hiddenInput = new TagBuilder("input"); hiddenInput.MergeAttribute("type", HtmlHelper.GetInputTypeString(InputType.Hidden)); hiddenInput.MergeAttribute("name", fullName); hiddenInput.MergeAttribute("value", "false"); inputItemBuilder.Append(hiddenInput.ToString(TagRenderMode.SelfClosing)); return MvcHtmlString.Create(inputItemBuilder.ToString()); }