2011-08-29 8 views
8

So che sul file Razor View, possiamo fare qualcosa di simile a questo @ Html.TextBox ("username", null, new {maxlength = 20 , completamento automatico = "disattivato"})ASP.NET MVC 3 - Data Annoation e Max Length/Size per Textbox Rendering

Tuttavia, spero di creare un modello per MVC che possa essere utilizzato per creare un modulo con la definizione esplicita della dimensione e della lunghezza massima delle caselle di testo. Provo [StringLength (n)] sopra le proprietà del modello, ma questo sembra fare solo la validazione piuttosto che impostare la dimensione della casella di testo.

Esiste comunque la possibilità di definire la lunghezza del campo di testo come annotazione di dati sopra una proprietà di un modello?

Quindi, in definitiva, potremmo semplicemente creare l'intero modulo usando il rasoio per mappare un modello piuttosto che prelevare esplicitamente le proprietà del modello una ad una per impostare la dimensione della casella di testo.

risposta

14

Ecco uno schema di un aiutante personalizzata che utilizza 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

Sembra fantastico! Sarebbe possibile avere qualcosa di simile a quello che hai menzionato sopra per essere usato in Html.EditorForModel()? Grazie per il vostro aiuto. – frostshoxx

+0

@frostshoxx Forse lo si può fare usando [UIHintAttribute] (http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.uihintattribute.aspx) e creando modelli personalizzati per ogni tipo di dati. Non ho provato questo però. – Eranga

3

Non funziona?

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

Nella Vista:

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

o:

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

Le sintassi che hai citato sono corrette, ma spero di chiamare @ Html.EditorForModel() e renderizzare tutti i campi dal modello piuttosto che rendere esplicitamente ogni campo singolarmente. Oltre a questo, vorrei anche essere in grado di definire la dimensione dei campi di testo come parte del tag di annotazione dei dati. Si noti che avere [StringLength (20)] non sembra impostare la dimensione del campo di testo su 20. Spero che questo chiarisca un po 'di più .. Grazie! – frostshoxx

+0

@frostshoxx Specificare la logica di presentazione come la dimensione del campo di testo nel modello viola i principi principali di MVC. A meno che non intenda maxlength .. – redwards510

2

trovo che preferisco le mie opinioni per chiamare solo Html.EditorFor (...). Ciò significa che i modelli Editor e Display decidono il destino dei controlli nella mia vista, in modo tale che il mio codice di vista venga ripulito molto - ha solo richieste html e generiche per gli editor.

Il seguente link dà un esempio di lavoro di ottenere questo lavoro in un Template Editor https://jefferytay.wordpress.com/2011/12/20/asp-net-mvc-string-editor-template-which-handles-the-stringlength-attribute/

sto usando simile nel mio String.cshtml Template Editor (vale a condivise/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... 

Poi il mio modello è annotato come ad esempio:

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

E il mio View chiama semplicemente:

<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> 

È possibile inoltre notare che la mia String.cshtml Template Editor gestisce anche auto-magicamente Enum, ma sta iniziando a divagare dall'argomento corrente, quindi ho rimosso quella c In questo caso, dirò semplicemente che il modello di editor di stringhe può aumentare il peso, e probabilmente google ha qualcosa su quello https://www.google.com/search?q=string+editor+template+enum

Label With Tooltip For è un helper HTML personalizzato che lascia cadere la descrizione nel titolo dell'etichetta, per maggiori informazioni al passaggio del mouse per ogni etichetta.

mi consiglia questo approccio se si vuole fare questo in un Template Editor.