Свойства EditorFor() и html

Asp.Net MVC 2.0 обеспечивает сборщик данных, например

Html.EditorFor(c => c.propertyname)

Если имя свойства является строкой, приведенный выше код отображает тексбокс.

Что делать, если я хочу передать свойства MaxLength и Size в текстовое поле или свое собственное свойство класса CSS?

Нужно ли мне создавать один шаблон для каждой комбинации размеров и длины в моем приложении? Если это так, это не делает используемые шаблоны по умолчанию.

Ответ 2

В MVC3 вы можете установить ширину следующим образом:

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

Ответ 3

Я решил это, создав EditorTemplate с именем String.ascx в папке /Views/Shared/EditorTemplates:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %>
<% 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 }) %>

На мой взгляд, я использую

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

Работает как очарование для меня!

Ответ 4

Ни один из ответов в этом или любом другом потоке по настройке атрибутов HTML для @Html.EditorFor не помог мне. Тем не менее, я нашел отличный ответ на

Укладка @Html.EditorFor helper

Я использовал тот же подход, и он работал красиво, не набирая много дополнительного кода. Обратите внимание, что установлен атрибут id для html-вывода Html.EditorFor. Код вида

<style type="text/css">
#dob
{
   width:6em;
}
</style>

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

Свойство модели с аннотацией данных и форматированием даты как "dd MMM yyyy"

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

Работал как шарм, не набирая лишнего кода. Этот ответ использует ASP.NET MVC 3 Razor С#.

Ответ 5

Возможно, вы захотите посмотреть запись в блоге Kiran Chand, он использует настраиваемые метаданные в модели представления, такие как:

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

Это сочетается с пользовательскими шаблонами, использующими метаданные. На мой взгляд, чистый и простой подход, но я хотел бы видеть этот общий вариант использования, встроенный в mvc.

Ответ 6

Я удивлен, что никто не упомянул о передаче его в "extraViewData" и читал его с другой стороны.

Просмотр (с разрывами строк, для ясности):

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

Шаблон редактора:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %>

<%= Html.TextBox("", Model, ViewData["htmlAttributes"])) %>

Ответ 7

Проблема заключается в том, что ваш шаблон может содержать несколько элементов HTML, поэтому MVC не будет знать, к какому из них следует применить ваш размер/класс. Вы должны определить его самостоятельно.

Создайте свой шаблон из своего класса TextBoxViewModel:

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

}

В шаблоне вы можете сделать это:

<input value="<%= Model.Value %>" <%= Model.GetAttributesString() %> />

По вашему мнению:

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

Первая форма будет отображать шаблон по умолчанию для строки. Вторая форма отобразит пользовательский шаблон.

Альтернативный синтаксис использует свободный интерфейс:

public class TextBoxViewModel
{
  public string Value { get; set; }
  IDictionary<string, object> moreAttributes;
  public TextBoxViewModel(string value, IDictionary<string, object> moreAttributes)
  {
    // set class properties here
    moreAttributes = new Dictionary<string, object>();
  }

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

Обратите внимание, что вместо этого в представлении вы также можете сделать это в контроллере или намного лучше в 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) });
}

Также обратите внимание, что вы можете создать базовый класс TemplateViewModel - общий язык для всех ваших шаблонов просмотров, который будет содержать базовую поддержку атрибутов и т.д.

Но в целом я думаю, что MVC v2 нуждается в лучшем решении. Это все еще Бета - попроси его, -)

Ответ 8

Я думаю, что использование CSS - это путь. Хотелось бы, я мог бы сделать больше с .NET-кодированием, как в XAML, но в браузере CSS является королем.

Site.css

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

.cshtml

<div class="editor-label"> 
  @Html.LabelFor(model => model.Note) 
</div> 
<div class="editor-field"> 
  @Html.EditorFor(model => model.Note, null, "account-note-input", null) 
  @Html.ValidationMessageFor(model => model.Note) 
</div>

Джо

Ответ 9

Как и в MVC 5, если вы хотите добавить какие-либо атрибуты, вы можете просто сделать

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

Информация из этот блог

Ответ 10

Вы можете определить атрибуты для своих свойств.

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

Это называется System.ComponentModel.DataAnnotations. Если вы не можете найти ValidationAttribute, который вам нужен, вы всегда можете определить пользовательские атрибуты.

С наилучшими пожеланиями, Карлос

Ответ 11

Это может быть не самое гладкое решение, но это просто. Вы можете написать расширение для класса HtmlHelper.EditorFor. В этом расширении вы можете указать параметр options, который будет записывать параметры в ViewData для помощника. Вот код:

Во-первых, метод расширения:

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

Далее, объект options:

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

И, наконец, вот строка из шаблона String.ascx:

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

Честно говоря, я думаю, что это ясно и ясно для бедной души, которая должна поддерживать ваш код в будущем. И это легко расширить для различных других бит информации, которую вы хотели бы передать своим шаблонам. Он работает до сих пор для меня в проекте, где я пытаюсь обернуть как можно больше в наборе шаблонов, чтобы помочь стандартизировать окружающий html, a la http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-5-master-page-templates.html.

Ответ 12

Я не знаю, почему это не работает для Html.EditorFor, но я попробовал TextBoxFor, и это сработало для меня.

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

... а также работает валидация.

Ответ 13

В моей практике я обнаружил, что лучше всего использовать EditorTemplates с одним HtmlHelper в нем - TextBox, который в большинстве случаев. Если мне нужен шаблон для более сложной структуры html, я напишу отдельный HtmlHelper.

Учитывая, что мы можем привязать весь объект ViewData вместо htmlAttributes TextBox. Кроме того, мы можем написать некоторый код настройки для некоторых свойств ViewData, если им нужна специальная обработка:

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

Ниже приведены примеры синтаксиса в представлении и выводимый html:

@Html.EditorFor(m => m.Date)
<input class="datepicker" data-val="true" data-val-required="&amp;#39;Date&amp;#39; must not be empty." id="Date" name="Date" type="text" value="01/08/2012">
@Html.EditorFor(m => m.Date, new { @class = "myClass", @format = "M/dd" })
<input class="myClass datepicker" data-val="true" data-val-required="&amp;#39;Date&amp;#39; must not be empty." id="Date" name="Date" type="text" value="1/08">

Ответ 14

Потому что вопрос для EditorFor не TextBoxFor WEFX предложение не работает.

Для изменения отдельных полей ввода вы можете обрабатывать выходные данные метода EditorFor:

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

Также возможно изменить ВСЕ ваши EditorFors, так как получается MVC устанавливает класс текстовых полей EditorFor с .text-box, поэтому вы можете просто переопределить этот стиль, в своей таблице стилей или в страница.

.text-box {
    width: 80em;
}

Кроме того, вы можете установить стиль для

input[type="text"] {
    width: 200px;
}
  • это переопределяет .text-box и изменяет все текстовые поля ввода, EditorFor или иначе.

Ответ 15

У меня также возникла проблема с установкой ширины TextBox в MVC3, а при установке атрибута Clsss для элемента управления TextArea, но не для элемента управления TextBoxFor или EditorFor:

Я пробовал следовать, и это сработало для меня:

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

также в этом случае проверки корректно работают.

Ответ 16

Один из способов, которыми вы могли бы обойти это, - это предоставить делегатам в модели представления обработку такого специального рендеринга. Я сделал это для класса подкачки, я раскрываю публичное свойство модели Func<int, string> RenderUrl, чтобы справиться с ней.

Определите, как будет записан пользовательский бит:

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

Вывести представление для класса Paging:

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

... и для фактического представления Paging:

@model Paging
@if (Model.Pages > 1)
{
    <ul class="paging">
    @for (int page = 1; page <= Model.Pages; page++)
    {
        <li><a href="@Model.RenderUrl(page)">@page</a></li>
    }
    </ul>
}

Это можно рассматривать как чрезмерно усложняющие вопросы, но я использую эти пейджеры повсюду и не мог видеть один и тот же шаблонный код, чтобы получить их.

Ответ 17

UPDATE: hm, очевидно, это не сработает, потому что модель передается по значению, поэтому атрибуты не сохраняются; но я оставляю этот ответ как идею.

Другим решением, я думаю, было бы добавить ваши собственные помощники TextBox/etc, которые будут проверять ваши собственные атрибуты на модели.

public class ViewModel
{
  [MyAddAttribute("class", "myclass")]
  public string StringValue { get; set; }
}

public class MyExtensions
{
  public static IDictionary<string, object> GetMyAttributes(object model)
  {
     // kind of prototype code...
     return model.GetType().GetCustomAttributes(typeof(MyAddAttribute)).OfType<MyAddAttribute>().ToDictionary(
          x => x.Name, x => x.Value);
  }
}

<!-- in the template -->
<%= Html.TextBox("Name", Model, MyExtensions.GetMyAttributes(Model)) %>

Это проще, но не так удобно/гибко.

Ответ 18

Это самый чистый и самый элегантный/простой способ получить решение здесь.

Блестящая запись в блоге и отсутствие беспорядочного переполнения в написании пользовательских методов расширения/помощника, таких как безумный профессор.

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

Ответ 19

Мне очень понравился ответ @tjeerdans, который использует EditorTemplate с именем String.ascx в папке /Views/Shared/EditorTemplates. Кажется, это самый прямой ответ на этот вопрос. Тем не менее, мне нужен шаблон с использованием синтаксиса Razor. Кроме того, похоже, что MVC3 использует шаблон String по умолчанию (см. Вопрос StackOverflow " используется шаблон отображения mvc для строк для целых чисел" ), поэтому вам нужно установить модель как объект, а не строку. Мой шаблон работает до сих пор:

@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})

Ответ 20

Я решил это!
Синтаксис для Razor:
@Html.TextAreaFor(m=>m.Address, new { style="Width:174px" }) это изменяет ширину области текста на ширину, определенную в параметре стиля.
Для ASPx синтаксис:
<%=Html.TextAreaFor(m => m.Description, new { cols = "20", rows = "15", style="Width:174px" })%>
это сделает трюк