ASP.NET MVC 3 - аннотации данных и максимальная длина / размер для рендеринга текстового поля - PullRequest
8 голосов
/ 29 августа 2011

Я знаю в файле Razor View, мы можем сделать что-то вроде этого @ Html.TextBox ("username", null, new {maxlength = 20, autocomplete = "off"})

Однако я надеюсь создать модель для MVC, которую можно будет использовать для создания формы с явно заданным размером и максимальной длиной текстовых полей. Я пытаюсь использовать [StringLength (n)] поверх свойств модели, но, похоже, это только делает проверку, а не устанавливает размер текстового поля.

Есть ли в любом случае, что мы можем определить длину текстового поля как аннотацию данных поверх свойства модели?

Таким образом, в конечном итоге, мы могли бы просто создать целую форму, используя бритву для сопоставления с моделью, а не явно подбирать свойства модели по одному для установки размера текстового поля.

Ответы [ 3 ]

14 голосов
/ 29 августа 2011

Вот схема пользовательского помощника, который использует 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);
}
3 голосов
/ 29 августа 2011

Не работает ли это?

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

В представлении:

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

или:

@Html.EditorFor(x => x.UserName)
2 голосов
/ 24 марта 2015

Мне кажется, что я предпочитаю свои взгляды просто Позвонить Html.EditorFor (...) . Это означает, что шаблоны «Редактор» и «Отображение» определяют судьбу элементов управления в моем представлении, так что мой код представления сильно очищается - у него просто есть html и общие запросы для редакторов.

Следующая ссылка дает рабочий пример получения этой работы в Редакторе шаблонов https://jefferytay.wordpress.com/2011/12/20/asp-net-mvc-string-editor-template-which-handles-the-stringlength-attribute/

Я использую подобное в моем String.cshtml шаблоне редактора (входит в Shared / 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...

Тогда моя модель снабжена комментариями, такими как:

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

А мой Вид просто звонит:

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

Вы также можете заметить, что мой шаблон редактора String.cshtml также автоматически обрабатывает Enum, но это начинает отступать от текущей темы, поэтому я отменил этот код, просто скажу, что шаблон редактора строк потяните лишний вес, и, вероятно, Google имеет что-то на это https://www.google.com/search?q=string+editor+template+enum

Label With Tooltip For - это специальный HTML-помощник, который просто перетаскивает описание в заголовок метки для получения дополнительной информации о наведении указателя мыши на каждую метку.

Я бы порекомендовал этот подход, если вы хотите сделать это в шаблоне редактора .

...