EditorFor () 및 html 속성


113

Asp.Net MVC 2.0 미리보기 빌드는 다음과 같은 도우미를 제공합니다.

Html.EditorFor(c => c.propertyname)

속성 이름이 문자열이면 위 코드는 texbox를 렌더링합니다.

MaxLength 및 Size 속성을 텍스트 상자 또는 자체 CSS 클래스 속성에 전달하려면 어떻게해야합니까?

응용 프로그램의 각 크기 및 길이 조합에 대해 하나의 템플릿을 만들어야합니까? 그렇다면 기본 템플릿을 사용할 수 없습니다.

답변:


92

MVC3에서는 다음과 같이 너비를 설정할 수 있습니다.

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

62
@vondip. 편집자가 아닌 TEXTBOX인지 확인하십시오. 편집자와 함께 작업하십시오.
Kasper Skov 2011

1
또한 textareas에서도 작동합니다 : @ Html.TextAreaFor (c => c.PropertyName, new {style = "width : 500px;"})
Tarzan

일부 데이터 주석 등은 formatString 같은 EditorFor, 작업 것이다 TextBoxFor에 의해 지원되지 않습니다
AaronLS

14
이 대답은 질문의 내용, 즉 EditorFor-Template 기능을 완전히 무시하지 않습니까?
Philipp M

1
그러나 TextBoxFor를 사용하면 데이터 주석으로 설정된 표시 형식이 해제됩니다.
Anders Lindén

61

내 / Views / Shared / EditorTemplates 폴더에 String.ascx라는 EditorTemplate을 만들어이 문제를 해결했습니다.

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

나를위한 매력처럼 작동합니다!


1
brilliant-이미 템플릿 화 된 datepicker DateTime 드롭 다운이 있었지만 여기에 추가 속성을 전달하는 것은 고통 스러웠습니다. 이것이 저를 위해 해결되었습니다. 감사합니다!
Terry_Brown

최대 길이와 EditorFor는 (다른 한편으로 TextBoxFor는 않습니다) 나를 위해 작동하지 않습니다
Drejc

@tjeerdhans,이 코드를 사용하여 CSS를 사용자 지정했습니다. 작동하지만 불행히도 원래 CSS 값을 대체 합니다. 대신 원본 CSS에 추가 하려면 어떻게해야 합니까?
Rosdi Kasim 2013

33

@ Html.EditorFor에 대한 HTML 속성 설정에 대한이 스레드 또는 다른 스레드의 답변 중 어느 것도 나에게 많은 도움이되지 않았습니다. 그러나 나는 좋은 대답을 찾았다.

@ Html.EditorFor 도우미 스타일 지정

나는 동일한 접근 방식을 사용했으며 많은 추가 코드를 작성하지 않고도 아름답게 작동했습니다. Html.EditorFor의 html 출력의 id 속성이 설정되어 있습니다. 보기 코드

<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 C #을 사용합니다.


1
MVC4에서도 나를 위해 정말 잘 작동했습니다.
atconway

1
서식이 작동했지만 이제는 상자를 효과적으로 비활성화하는 데이터에 대해 null이 반환됩니다.
Joe

2
나는 그것이 MVC 사람들과 함께 무엇인지 모릅니다. 그것은 아무도 숫자에 대해 여러 언어와 형식으로 작동하는 웹 사이트를 작성하지 않은 것과 같습니다.
adudley

아주 좋아요. 이것은 간단하고 작동하며 실제로 대안을 제공하는 대신 OP의 질문에 대답합니다. MVC4 사용.
draconis

경고 : DateTimes는 생년월일에 대해 잘못된 type = "datetime"으로 렌더링되는 것으로 보이며, 일부 브라우저 (예 : Firefox 모바일)는 유효성 검사를 통과하지 못하고 어렵거나 어려울 수있는 시간 구성 요소를 포함하여 실제로 해당 입력 유형을 올바르게 지원합니다. 사용자가 제거 할 수 없습니다.
brianary

25

Kiran Chand의 블로그 게시물 을보고 싶을 수 있습니다 . 그는 뷰 모델에서 다음과 같은 사용자 지정 메타 데이터를 사용합니다.

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

이것은 메타 데이터를 사용하는 사용자 지정 템플릿과 결합됩니다. 제 생각에는 깨끗하고 간단한 접근 방식이지만 mvc에 내장 된이 일반적인 사용 사례를보고 싶습니다.


71
농담 해? 이것은 단순한 일에 너무 과잉입니다. 점점 더 순수한 HTML로 돌아가서 MVC 부풀린 도우미 메서드를 잊어 버립니다. 5 분 전에 jquery datepicker를 성공적으로 시작한 간단한 TextboxFor가있었습니다. 이제 미리로드 된 날짜 값의 형식을 변경하고 싶었 기 때문에 EditorFor로 변경해야했습니다. 그러나 이제 갑자기 과도하게 부풀려진 사용자 지정 확장 메서드와 도우미를 작성하지 않고는 내 HTML 속성을 더 이상 지정할 수 없습니다. 좋은 농담 이었어. 더 간단한 방법이 있어야합니다. 미친 교수님들은 언제 멈춰야할지 모릅니다.
Aaron

1
나는 당신이 맥락을 뒤섞 고 있다고 생각합니다. 제공 한 링크를 사용하여 각각 고유 한 크기와 최대 길이 값을 가져 오는 두 가지 EditorFor 호출을 어떻게 가질 수 있습니까? EditorFor를 사용하지 않으려면 항상 TextBox 도우미 또는 간단한 html을 사용할 수 있습니다. 그러나 그것은 문제가 아닙니다!
chandmk

@Aaron 최신 MVC에서 다음과 EditorFor같이 전달 하여 추가 html 속성을 지정할 수 있습니다 .new { htmlAttributes: { @class = "yourclass" } }
JoeBrockhaus

17

나는 아무도 그것을 "additionalViewData"에 전달하고 다른 쪽에서 읽는 것을 언급하지 않았다는 것에 놀랐다.

보기 (명확성을 위해 줄 바꿈 포함) :

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

편집기 템플릿 :

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

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

-이 I에 건물은 속성의 병합을 고려 도우미 만들어 stackoverflow.com/a/11498094/79842
콜린 Bowern

6

문제는 템플릿에 여러 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에는 더 나은 솔루션이 필요하다고 생각합니다. 아직 베타입니다-가서 물어보세요 ;-)


이 문제를 처리하는 더 좋은 방법은 여기서 언급했듯이 stackoverflow.com/questions/1647609/… ... 간단히 말해서 WPF가 문제를 처리하는 방식과 유사한 작업을 수행하는 것입니다. 속성) 템플릿에 전달되고 템플릿은 스타일을 적용 할 내부 요소를 결정합니다 ...
vdhant

6

CSS를 사용하는 것이 방법이라고 생각합니다. XAML에서와 같이 .NET 코딩으로 더 많은 일을 할 수 있기를 원하지만 브라우저에서는 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>


이것은 EditorFor템플릿을 사용할 때 특정 CSS 변경을 제어하는 ​​데 매우 효과적입니다 . 나는 MVC4를 사용하고 있으며 이것은 훌륭하게 작동했습니다.
atconway

6

MVC 5에서와 같이 속성을 추가하려면 간단히 수행 할 수 있습니다.

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

이 블로그 에서 찾은 정보


3

속성에 대한 속성을 정의 할 수 있습니다.

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

이것은 System.ComponentModel.DataAnnotations. ValidationAttribute필요한 것을 찾을 수없는 경우 항상 사용자 지정 속성을 정의 할 수 있습니다.

감사합니다, Carlos


3
그는 유효성 검사가 아닌 maxlength와 같은 Html 속성에 대해 이야기합니다.
Mathias F

나는 것이다 희망 뷰 엔진은 또한 DataAnnotations을 순종하는 것입니다. 나는 아직 MVC2를 엉망으로 만들지 않았습니다.
mxmissile

StringLength 데이터 주석을 시도했습니다. EditorFor에서는 작동하지 않았습니다.
wayne.blackmon

3

이것은 가장 매끄러운 솔루션은 아니지만 간단합니다. HtmlHelper.EditorFor 클래스에 대한 확장을 작성할 수 있습니다. 해당 확장에서 도우미의 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
    });
}

다음으로 옵션 개체 :

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을 표준화하는 데 도움이되는 템플릿 세트로 최대한 많이 래핑하려고하는 프로젝트에서 잘 작동하고 있습니다. http://bradwilson.typepad.com/blog/2009/ 10 / aspnet-mvc-2-templates-part-5-master-page-templates.html .


3

내 질문에 답하기 위해 블로그 항목을 작성했습니다.

템플릿에 대한 HTML 속성 지원 추가-ASP.Net MVC 2.0 베타


(보기) 모델에 HTML 형식 지정 속성을 넣는 아이디어는보기와 논리를 분리하는 MVC 아이디어에 위배됩니다! 모델이 HTML에서 다른 표현을 필요로한다면 어떻게 될까요?
saintedlama

2
@Saintedlama : 그것은 완벽 벌금에 데이터 주석을 넣어의 뷰 모델 뷰 모델의 유일한 목적은위한 구조화 된 데이터 모델을 제공하기 때문에, 보기를 . MVC 용어에서 일반적으로 뷰 관련 속성이 없어야하는 DB 엔티티를 나타내는 model 과 혼동하지 마십시오 . 하지만 그의 viewmodel 주석이 HTMLxxx로 시작하는 것은 유감 스러운데, 이는 HTML을 프리젠 테이션 레이어로 암시하기 때문입니다.하지만 선은 어딘가에 그려야합니다. :) 게다가, 그가 예를 들어 silverlight 앱에 대해 viewmodel을 재사용한다면, 그는 쉽게 그의 viewmodel에 SL 속성을 추가 할 수 있습니다.
Boris B.

3

Html.EditorFor에서 작동하지 않는 이유를 모르겠지만 TextBoxFor를 사용해 보았고 나를 위해 일했습니다.

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

... 또한 유효성 검사가 작동합니다.


당신이 필요@class = "className"
JoeBrockhaus

2

내 연습에서는 HtmlHelper가 하나만있는 EditorTemplates (대부분의 경우 TextBox)를 사용하는 것이 가장 좋습니다. 좀 더 복잡한 html 구조를위한 템플릿을 원한다면 별도의 HtmlHelper를 작성하겠습니다.

TextBox의 htmlAttributes 대신 전체 ViewData 개체를 고정 할 수 있다는 점을 감안할 때. 또한 특별한 처리가 필요한 경우 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">

2

질문은 TextBoxFor가 아닌 EditorFor WEFX의 제안이 작동하지 않기 때문입니다.

개별 입력 상자를 변경하려면 EditorFor 메서드의 출력을 처리 할 수 ​​있습니다.

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

MVC가 .text-box를 사용 하여 EditorFor 텍스트 상자의 클래스를 설정하므로 모든 EditorFors를 변경할 수도 있습니다 . 따라서 스타일 시트 또는 페이지에서이 스타일을 재정의 할 수 있습니다.

.text-box {
    width: 80em;
}

또한 스타일을 설정할 수 있습니다.

input[type="text"] {
    width: 200px;
}
  • 이것은 .text-box를 재정의하고 모든 입력 텍스트 상자, EditorFor 또는 기타를 변경합니다.

모든 EditorFor () 텍스트 상자가 input type = "text"인 것은 아닙니다. DateTime 속성은 type = "datetime"으로 렌더링되는 것 같습니다.
brianary

2

또한 MVC3에서 TextBox의 너비를 설정하는 데 문제가 있었지만 Clsss 특성을 설정하면 TextArea 컨트롤에는 작동하지만 TextBoxFor 컨트롤 또는 EditorFor 컨트롤에는 작동하지 않습니다.

나는 나를 위해 일한 다음을 시도했다.

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

이 경우에도 유효성 검사가 완벽하게 작동합니다.


2

이를 해결할 수있는 한 가지 방법은 뷰 모델에 대리자를 두어 이와 같은 특수 렌더링 인쇄를 처리하는 것입니다. 페이징 클래스에 대해이 작업을 수행했으며 모델에 공용 속성을 노출 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>
}

지나치게 복잡한 문제로 보일 수 있지만 저는이 호출기를 모든 곳에서 사용하며 렌더링을 위해 동일한 표준 코드를 볼 수 없었습니다.


1

업데이트 : 흠, 분명히 이것은 모델이 값으로 전달되어 속성이 유지되지 않기 때문에 작동하지 않습니다. 그러나 나는이 대답을 아이디어로 남겨 둡니다.

내 생각에 또 다른 해결책은 모델에 대한 자신의 속성을 확인하는 자신 만의 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)) %>

이것은 더 쉽지만 편리하고 유연하지는 않습니다.



0

/ Views / Shared / EditorTemplates 폴더에 String.ascx라는 EditorTemplate을 사용하는 @tjeerdans 답변이 정말 마음에 들었습니다. 이 질문에 대한 가장 직접적인 대답 인 것 같습니다. 그러나 Razor 구문을 사용하는 템플릿이 필요했습니다. 또한 MVC3는 String 템플릿을 기본값으로 사용하는 것으로 보입니다 (StackOverflow 질문 " mvc display template for strings is used for integers "참조). 따라서 모델을 문자열이 아닌 객체로 설정해야합니다. 내 템플릿이 지금까지 작동하는 것 같습니다.

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

0

나는 그것을 해결했다 !!
Razor의 경우 구문은 다음과
@Html.TextAreaFor(m=>m.Address, new { style="Width:174px" })같습니다. 텍스트 영역 너비를 스타일 매개 변수에 정의한 너비로 조정합니다.
ASPx의 경우 구문은 다음과
<%=Html.TextAreaFor(m => m.Description, new { cols = "20", rows = "15", style="Width:174px" })%>
같습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.