EditorFor () y propiedades html

Las versiones de vista previa de Asp.Net MVC 2.0 proporcionan ayudantes como

Html.EditorFor(c => c.propertyname) 

Si el nombre de la propiedad es una cadena, el código anterior representa un texbox.

¿Qué pasa si quiero pasar las propiedades MaxLength y Size al cuadro de texto o a mi propia propiedad de la clase css?

¿Necesito crear una plantilla para cada tamaño y combinación de longitud en mi aplicación? Si es así, eso no hace que las plantillas predeterminadas sean utilizables.

En MVC3, puede establecer el ancho de la siguiente manera:

 @Html.TextBoxFor(c => c.PropertyName, new { style = "width: 500px;" }) 

Lo resolví creando una Plantilla de Editor llamada String.ascx en mi carpeta / Views / Shared / EditorTemplates:

 <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> <% int size = 10; int maxLength = 100; if (ViewData["size"] != null) { size = (int)ViewData["size"]; } if (ViewData["maxLength"] != null) { maxLength = (int)ViewData["maxLength"]; } %> <%= Html.TextBox("", Model, new { Size=size, MaxLength=maxLength }) %> 

En mi opinión, yo uso

 <%= Html.EditorFor(model => model.SomeStringToBeEdited, new { size = 15, maxLength = 10 }) %> 

¡Funciona como un encanto para mí!

Ninguna de las respuestas en este o cualquier otro hilo sobre la configuración de atributos HTML para @ Html.EditorFor fue de mucha ayuda para mí. Sin embargo, encontré una gran respuesta en

Diseñando un @ Html.EditorFor helper

Usé el mismo enfoque y funcionó muy bien sin escribir mucho código adicional. Tenga en cuenta que se establece el atributo id de la salida html de Html.EditorFor. El código de vista

  @using (Html.BeginForm()) { Enter date: @Html.EditorFor(m => m.DateOfBirth, null, "dob", null) } 

La propiedad del modelo con anotación de datos y formato de fecha como “dd MMM aaaa”

 [Required(ErrorMessage= "Date of birth is required")] [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd MMM yyyy}")] public DateTime DateOfBirth { get; set; } 

Funcionó como un amuleto sin escribir un montón de código adicional. Esta respuesta usa ASP.NET MVC 3 Razor C #.

Quisiera mirar la publicación del blog de Kiran Chand , usa metadatos personalizados en el modelo de vista como:

 [HtmlProperties(Size = 5, MaxLength = 10)] public string Title { get; set; } 

Esto se combina con plantillas personalizadas que hacen uso de los metadatos. Un enfoque limpio y simple en mi opinión, pero me gustaría ver este caso de uso común incorporado en mvc.

Me sorprende que nadie mencionara pasarlo en “additionalViewData” y leerlo en el otro lado.

Vista (con saltos de línea, para mayor claridad):

 <%= Html.EditorFor(c => c.propertyname, new { htmlAttributes = new { @class = "myClass" } } )%> 

Plantilla de editor:

 <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> <%= Html.TextBox("", Model, ViewData["htmlAttributes"])) %> 

El problema es que su plantilla puede contener varios elementos HTML, por lo que MVC no sabrá a cuál aplicar su tamaño / clase. Tendrás que definirlo tú mismo.

Haz que tu plantilla derive de tu propia clase llamada TextBoxViewModel:

 public class TextBoxViewModel { public string Value { get; set; } IDictionary moreAttributes; public TextBoxViewModel(string value, IDictionary moreAttributes) { // set class properties here } public string GetAttributesString() { return string.Join(" ", moreAttributes.Select(x => x.Key + "='" + x.Value + "'").ToArray()); // don't forget to encode } 

}

En la plantilla puedes hacer esto:

  /> 

En su opinión lo hace:

 <%= Html.EditorFor(x => x.StringValue) %> or <%= Html.EditorFor(x => new TextBoxViewModel(x.StringValue, new IDictionary { {'class', 'myclass'}, {'size', 15}}) %> 

El primer formulario representará la plantilla predeterminada para la cadena. El segundo formulario representará la plantilla personalizada.

La syntax alternativa usa una interfaz fluida:

 public class TextBoxViewModel { public string Value { get; set; } IDictionary moreAttributes; public TextBoxViewModel(string value, IDictionary moreAttributes) { // set class properties here moreAttributes = new Dictionary(); } public TextBoxViewModel Attr(string name, object value) { moreAttributes[name] = value; return this; } 

}

  // and in the view <%= Html.EditorFor(x => new TextBoxViewModel(x.StringValue).Attr("class", "myclass").Attr("size", 15) %> 

Tenga en cuenta que en lugar de hacer esto en la vista, también puede hacer esto en el controlador, o mucho mejor en ViewModel:

 public ActionResult Action() { // now you can Html.EditorFor(x => x.StringValue) and it will pick attributes return View(new { StringValue = new TextBoxViewModel(x.StringValue).Attr("class", "myclass").Attr("size", 15) }); } 

También tenga en cuenta que puede hacer una clase base de TemplateViewModel, un terreno común para todas sus plantillas de vista, que contendrá soporte básico para atributos / etc.

Pero, en general, creo que MVC v2 necesita una mejor solución. Todavía es Beta, ve y pídelo 😉

Creo que usar CSS es el camino a seguir. Me gustaría poder hacer más con la encoding .NET, como en XAML, pero en el navegador, CSS es el rey.

Site.css

 #account-note-input { width:1000px; height:100px; } 

.cshtml

 
@Html.LabelFor(model => model.Note)
@Html.EditorFor(model => model.Note, null, "account-note-input", null) @Html.ValidationMessageFor(model => model.Note)

Joe

Como en MVC 5, si desea agregar atributos simplemente puede hacer

  @Html.EditorFor(m => m.Name, new { htmlAttributes = new { @required = "true", @anotherAttribute = "whatever" } }) 

Información encontrada en este blog

Puede definir atributos para sus propiedades.

 [StringLength(100)] public string Body { get; set; } 

Esto se conoce como System.ComponentModel.DataAnnotations . Si no puede encontrar el ValidationAttribute que necesita, siempre puede definir atributos personalizados.

Saludos cordiales, Carlos

Esta puede no ser la solución más hábil, pero es sencilla. Puede escribir una extensión a la clase HtmlHelper.EditorFor. En esa extensión, puede suministrar un parámetro de opciones que escribirá las opciones en ViewData para el ayudante. Aquí hay un código:

Primero, el método de extensión:

 public static MvcHtmlString EditorFor(this HtmlHelper helper, Expression> expression, TemplateOptions options) { return helper.EditorFor(expression, options.TemplateName, new { cssClass = options.CssClass }); } 

A continuación, el objeto de opciones:

 public class TemplateOptions { public string TemplateName { get; set; } public string CssClass { get; set; } // other properties for info you'd like to pass to your templates, // and by using an options object, you avoid method overload bloat. } 

Y finalmente, aquí está la línea de la plantilla String.ascx:

 <%= Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { @class = ViewData["cssClass"] ?? "" }) %> 

Francamente, creo que esto es sencillo y claro para la pobre alma que tiene que mantener tu código en el futuro. Y es fácil de ampliar para otros bits de información que le gustaría pasar a sus plantillas. Hasta ahora, está funcionando bien para mí en un proyecto en el que trato de envolver todo lo que puedo en un conjunto de plantillas para ayudar a estandarizar el html circundante, a la http://bradwilson.typepad.com/blog/2009/ 10 / aspnet-mvc-2-templates-part-5-master-page-templates.html .

Escribí una entrada de blog para responder mi propia pregunta

Agregar soporte de atributos html para Plantillas – ASP.Net MVC 2.0 Beta

No sé por qué no funciona para Html.EditorFor pero probé TextBoxFor y funcionó para mí.

 @Html.TextBoxFor(m => m.Name, new { Class = "className", Size = "40"}) 

… y también funciona la validación.

En mi práctica, encontré que lo mejor es usar EditorTemplates con solo un HtmlHelper en él – TextBox que es en la mayoría de los casos. Si quiero una plantilla para una estructura html más compleja, escribiré un HtmlHelper por separado.

Dado que podemos pegar todo el objeto ViewData en lugar de htmlAttributes del TextBox. Además, podemos escribir algunos códigos de personalización para algunas de las propiedades de ViewData si necesitan un tratamiento especial:

 @model DateTime? 
 @* 1) applies class datepicker to the input; 2) applies additionalViewData object to the attributes of the input 3) applies property "format" to the format of the input date. *@ 
 @{ if (ViewData["class"] != null) { ViewData["class"] += " datepicker"; } else { ViewData["class"] = " datepicker"; } string format = "MM/dd/yyyy"; if (ViewData["format"] != null) { format = ViewData["format"].ToString(); ViewData.Remove("format"); } } @Html.TextBox("", (Model.HasValue ? Model.Value.ToString(format) : string.Empty), ViewData) 

A continuación se muestran los ejemplos de la syntax en la vista y el html generado:

 @Html.EditorFor(m => m.Date) 
  
 @Html.EditorFor(m => m.Date, new { @class = "myClass", @format = "M/dd" }) 
  

Porque la pregunta es para EditorFor no TextBoxFor la sugerencia de WEFX no funciona.

Para cambiar los cuadros de entrada individuales, puede procesar el resultado del método EditorFor:

 <%: new HtmlString(Html.EditorFor(m=>m.propertyname).ToString().Replace("class=\"text-box single-line\"", "class=\"text-box single-line my500pxWideClass\"")) %> 

También es posible cambiar TODOS sus EditorFors, ya que resulta que MVC establece la clase de cuadros de texto EditorFor con .text-box , por lo tanto, puede anular este estilo, en su hoja de estilo o en la página.

 .text-box { width: 80em; } 

Además, puedes establecer el estilo para

 input[type="text"] { width: 200px; } 
  • esto anula .text-box y cambiará todos los cuadros de texto de entrada, EditorFor u otros.

También tuve problemas para establecer el ancho de TextBox en MVC3, mientras configuraba el atributo de Clsss para el control de TextArea, pero no para el control de TextBoxFor o el control de EditorFor:

Intenté seguir y eso funcionó para mí:

@ Html.TextBoxFor (model => model.Title, new {Class = “textBox”, style = “width: 90%;”})

también en este caso las validaciones funcionan a la perfección.

Una forma de evitarlo es haciendo que los delegates en el modelo de vista manejen la impresión de un renderizado especial como este. He hecho esto para una clase de búsqueda, expongo una propiedad pública en el modelo Func RenderUrl para manejarlo.

Así que defina cómo se escribirá el bit personalizado:

 Model.Paging.RenderUrl = (page) => { return string.Concat(@"/foo/", page); }; 

Muestra la vista para la clase de Paging :

 @Html.DisplayFor(m => m.Paging) 

… y para la vista de Paging real:

 @model Paging @if (Model.Pages > 1) { 
    @for (int page = 1; page <= Model.Pages; page++) {
  • @page
  • }
}

Podría ser visto como una complicación excesiva, pero utilizo estos localizadores en todas partes y no podía soportar ver el mismo código repetitivo para que se renderizaran.

ACTUALIZACIÓN: hm, obviamente esto no funcionará porque el modelo se pasa por valor para que los atributos no se conserven; pero dejo esta respuesta como una idea.

Otra solución, creo, sería agregar tus propios ayudantes TextBox / etc, que verificarán tus propios atributos en el modelo.

 public class ViewModel { [MyAddAttribute("class", "myclass")] public string StringValue { get; set; } } public class MyExtensions { public static IDictionary GetMyAttributes(object model) { // kind of prototype code... return model.GetType().GetCustomAttributes(typeof(MyAddAttribute)).OfType().ToDictionary( x => x.Name, x => x.Value); } }  <%= Html.TextBox("Name", Model, MyExtensions.GetMyAttributes(Model)) %> 

Este es más fácil pero no tan conveniente / flexible.

Esta es la forma más limpia y más elegante / simple de obtener una solución aquí.

Brillante entrada de blog y sin excesos excesivos al escribir métodos personalizados de extensión / ayuda como un profesor enojado.

http://geekswithblogs.net/michelotti/archive/2010/02/05/mvc-2-editor-template-with-datetime.aspx

Me gustó mucho la respuesta de @tjeerdans que utiliza la Plantilla del Editor llamada String.ascx en la carpeta / Views / Shared / EditorTemplates. Parece ser la respuesta más directa a esta pregunta. Sin embargo, quería una plantilla usando la syntax de Razor. Además, parece que MVC3 utiliza la plantilla String como valor predeterminado (consulte la pregunta de StackOverflow “La plantilla de visualización mvc para cadenas se usa para enteros “) por lo que debe establecer el modelo en objeto en lugar de cadena. Mi plantilla parece estar funcionando hasta ahora:

 @model object @{ int size = 10; int maxLength = 100; } @if (ViewData["size"] != null) { Int32.TryParse((string)ViewData["size"], out size); } @if (ViewData["maxLength"] != null) { Int32.TryParse((string)ViewData["maxLength"], out maxLength); } @Html.TextBox("", Model, new { Size = size, MaxLength = maxLength}) 

¡Lo resolví!
Para Razor, la syntax es:
@Html.TextAreaFor(m=>m.Address, new { style="Width:174px" }) esto ajusta el ancho del área de texto al ancho que @Html.TextAreaFor(m=>m.Address, new { style="Width:174px" }) en el parámetro de estilo.
Para ASPx, la syntax es:
<%=Html.TextAreaFor(m => m.Description, new { cols = "20", rows = "15", style="Width:174px" })%>
esto hará el truco