2011-08-29 11 views
8

Sé en el archivo Razor View, podemos hacer algo como esto @ Html.TextBox ("nombre de usuario", nulo, nuevo {maxlength = 20 , autocompletar = "off"})ASP.NET MVC 3 - Anotación de datos y longitud/tamaño máximos para la representación de cuadros de texto

Sin embargo, estoy esperando crear un modelo para el MVC que se pueda usar para crear un formulario con el tamaño y la longitud máxima de los cuadros de texto definidos explícitamente. Intento [StringLength (n)] en la parte superior de las propiedades del modelo, pero parece que solo la validación en lugar de establecer el tamaño del cuadro de texto.

¿Hay alguna forma de que podamos definir la longitud del campo de texto como una anotación de datos sobre una propiedad de un modelo?

Por lo tanto, en última instancia, podríamos simplemente crear el formulario completo utilizando una afeitadora para asignar a un modelo en lugar de recoger las propiedades del modelo una a una para establecer el tamaño del cuadro de texto.

Respuesta

14

Aquí es un esquema de un ayudante personalizada que utiliza StringLengthAttribute.

public class MyModel 
{ 
    [StringLength(50)] 
    public string Name{get; set;} 
} 

public MvcHtmlString MyTextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> helper, 
     Expression<Func<TModel, TProperty>> expression) 
{ 

    var attributes = new Dictionary<string, Object>(); 
    var memberAccessExpression = (MemberExpression)expression.Body; 
    var stringLengthAttribs = memberAccessExpression.Member.GetCustomAttributes(
     typeof(System.ComponentModel.DataAnnotations.StringLengthAttribute), true); 

    if (stringLengthAttribs.Length > 0) 
    { 
     var length = ((StringLengthAttribute)stringLengthAttribs[0]).MaximumLength; 

     if (length > 0) 
     { 
      attributes.Add("size", length); 
      attributes.Add("maxlength", length); 
     } 
    } 

    return helper.TextBoxFor(expression, attributes); 
} 
+0

¡Eso se ve genial! ¿Sería posible tener algo similar a lo que mencionas arriba para usar en Html.EditorForModel()? Gracias por su ayuda. – frostshoxx

+0

@frostshoxx Quizás pueda hacerlo utilizando [UIHintAttribute] (http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.uihintattribute.aspx) y crear plantillas personalizadas para cada tipo de datos. No he intentado esto sin embargo. – Eranga

3

¿Esto no funciona?

public class ViewModel 
{ 
    [StringLength(20)] 
    public string UserName {get;set;} 
} 

En la Vista:

@Html.TextBoxFor(x => x.UserName, new {autocomplete = "off"}) 

o:

@Html.EditorFor(x => x.UserName) 
+2

Las sintaxis que mencionas son correctas, pero espero simplemente llamar a @ Html.EditorForModel() y hacer que muestre todos los campos del modelo en lugar de representarlos explícitamente. Además de eso, también me gustaría poder definir el tamaño de los campos de texto como parte de la etiqueta de anotación de datos. Tenga en cuenta que tener [StringLength (20)] no parece establecer el tamaño del campo de texto en 20. Espero que esto aclare un poco más ... ¡Gracias! – frostshoxx

+0

@frostshoxx La especificación de la lógica de presentación, como el tamaño del campo de texto en el modelo, infringe los principios básicos de MVC. A menos que quieras decir maxlength .. – redwards510

2

me parece que prefiero mis puntos de vista a Sólo tiene que llamar Html.EditorFor (...). Esto significa que las plantillas de Editor y Pantalla deciden el destino de los controles en mi vista, de modo que mi código de vista se limpia mucho, solo tiene solicitudes html y genéricas para editores.

El siguiente enlace da una muestra de trabajo de conseguir este trabajo en un Editor de plantillas de https://jefferytay.wordpress.com/2011/12/20/asp-net-mvc-string-editor-template-which-handles-the-stringlength-attribute/

estoy usando similar en mi String.cshtml Editor de plantillas (va en Común/EditorTemplates) .

@model object 
@using System.ComponentModel.DataAnnotations 
@{ 
    ModelMetadata meta = ViewData.ModelMetadata; 
    Type tModel = meta.ContainerType.GetProperty(meta.PropertyName).PropertyType; 
} 
@if(typeof(string).IsAssignableFrom(tModel)) { 

    var htmlOptions = new System.Collections.Generic.Dictionary<string, object>(); 

    var stringLengthAttribute = (StringLengthAttributeAdapter)ViewData.ModelMetadata.GetValidators(this.ViewContext.Controller.ControllerContext).Where(v => v is StringLengthAttributeAdapter).FirstOrDefault(); 
    if (stringLengthAttribute != null && stringLengthAttribute.GetClientValidationRules().First().ValidationParameters["max"] != null) 
    { 
     int maxLength = (int)stringLengthAttribute.GetClientValidationRules().First().ValidationParameters["max"]; 

     htmlOptions.Add("maxlength", maxLength); 

     if (maxLength < 20) 
     { 
      htmlOptions.Add("size", maxLength); 
     } 
    } 

    htmlOptions.Add("class", "regular-field"); 

    <text> 
     @Html.TextBoxFor(m => m, htmlOptions) 
    </text> 
} 
else if(typeof(Enum).IsAssignableFrom(tModel)) { 
    //Show a Drop down for an enum using: 
    //Enum.GetValues(tModel) 
    //This is beyond this article 
} 
//Do other things for other types... 

Entonces mi modelose anota como:

[Display(Name = "Some Field", Description = "Description of Some Field")] 
[StringLength(maximumLength: 40, ErrorMessage = "{0} max length {1}.")] 
public string someField{ get; set; } 

Y mi Ver simplemente llama:

<div class="editor-label"> 
    @Html.LabelWithTooltipFor(model => model.something.someField) 
</div> 
<div class="editor-field"> 
    @Html.EditorFor(model => model.something.someField) 
    @Html.ValidationMessageFor(model => model.something.someField) 
</div> 

También se podría notar que mi Editor de plantillas String.cshtml también maneja automáticamente Enum, pero eso está empezando a desviarse del tema actual, así que rechacé esa c ode, solo diré aquí que la plantilla del editor de cadenas puede aumentar el peso, y probablemente google tenga algo sobre eso https://www.google.com/search?q=string+editor+template+enum

Label With Tooltip For es un helper HTML personalizado que simplemente suelta la descripción en el título de la etiqueta, para más información sobre el mouse para cada etiqueta.

Recomendaría este enfoque si desea hacer esto en una plantilla de editor .

Cuestiones relacionadas