2013-02-06 4 views
7

내 뷰 모델에서 속성에 최대 길이를 설정하지 않는StringLength 여기에 텍스트 상자

@Html.EditorFor(model => model.Extension) 

그리고 렌더링 :

<input class="text-box single-line" data-val="true" data-val-length="The field Ext. must be a string with a maximum length of 6." data-val-length-max="6" id="Extension" name="Extension" type="text" value="" /> 

해야하는이 내 텍스트 상자에 maxlength 속성을 설정합니까? 그렇지 않다면 DataAttributes로 어떻게 할 수 있습니까?

+0

6 자 이상의 문자열을 게시 할 수 있는지 확인 했습니까? –

+0

유효성 검사 오류가 발생하지만 실제로 maxlength 속성을 설정해야합니다. –

+0

'TextBoxFor'로 변경하면 HTML 옵션을 전달할 수 있습니다. –

답변

4

나는 인 경우 이것을 제어하기 위해 ViewModel에서 설정 한 속성을 원합니다.

ASP.NET MVC는이를 정확히 수행 할 수있는 확장 가능한 시스템을 제공합니다. 다음은 수행해야 할 작업입니다.

  1. 사용자 정의 ModelMetadataProvider을 구현하십시오.
  2. StringLengthAttribute 또는 MaxLengthAttribute을 찾아 정보를 추출하여 ModelMetadata에 추가하십시오.
  3. 정보를 사용하는 사용자 정의 편집기 템플릿을 제공하십시오.

1 단계 : 사용자 정의 ModelMetadataProvider를 구현합니다.

ModelMetadataProvider에서 파생되는 클래스를 만듭니다. 일반적으로 DataAnnotationsModelMetadataProvider에서 파생됩니다. 기본 기능을 제공하기 때문에 CreateMetadata이라는 단일 메서드 만 재정의하면됩니다.

2 단계 :가 정보를 추출 :

이 정보를 얻으려면, 당신은 속성을 찾아 최대 길이 정보를 추출하고 ModelMetadataAdditionalValues 사전에 추가해야합니다. 구현 (이 전체 구현)과 같이 보일 것입니다 :

public class CustomModelMetadataProvider : DataAnnotationsModelMetadataProvider 
{ 
    protected override ModelMetadata CreateMetadata(
     IEnumerable<Attribute> attributes, 
     Type containerType, 
     Func<object> modelAccessor, 
     Type modelType, 
     string propertyName) 
    { 
     // Call the base class implementation to create the default metadata... 
     var metadata = base.CreateMetadata(
      attributes, 
      containerType, 
      modelAccessor, 
      modelType, 
      propertyName); 

     // Extract the stringLengthAttribute (you can do the same for the 
     // MaxLengthAttribute if you want). 
     var attr = attributes 
      .OfType<StringLengthAttribute>() 
      .First(); 

     // This could be getting called on a property that doesn't have the 
     // attribute so make sure you check for null! 
     if (attr != null) 
     { 
      metadata.AdditionalValues["maxLength"] = attr.MaximumLength; 
     } 

     return metadata; 
    } 
} 

위해 ASP.NET MVC 당신이 Global.asaxApplication_Start 방법에 등록하기 위해 필요한이를 사용하는.

ModelMetadataProviders.Current = new CustomModelMetadataProvider(); 

3 단계 : 사용자 정의 편집기 템플릿을 만듭니다.

이제 정보를 사용하는보기를 만들어야합니다. Views\Shared\ 폴더에 String이라는 새보기를 만듭니다. String.cshtml

@{ 
    object maxLength; 
    if (!ViewData.ModelMetadata.AdditionalValues 
      .TryGetValue("maxLength", out maxLength)) 
    { 
     maxLength = 0; 
    } 

    var attributes = new RouteValueDictionary 
    { 
     {"class", "text-box single-line"}, 
     { "maxlength", (int)maxLength }, 
    }; 
} 

@Html.TextBox("", ViewContext.ViewData.TemplateInfo.FormattedModelValue, attributes) 

당신이 @Html.EditorFor를 호출하여 다음과 같은 HTML 출력을 얻을 것이다 응용 프로그램을 실행

.

<input class="text-box single-line" id="Extension" maxlength="6" name="Extension" type="text" value="" /> 

당신이 모델 메타 데이터 제공 시스템은 (이들은 면도기보기 엔진 이전에 기록 된 작동 방법을 자세히 그렇게보기 구문의 일부는 약간 펑키 것을 Brad Wilson has a series of blog posts하지만, 그렇지 않은 정보에 대해 더 알고 싶다면 소리입니다.) 당신의 HTML을 대체 EditorFor와의 아래에서

@{ 
var max = ((System.ComponentModel.DataAnnotations.StringLengthAttribute)(typeof(MyType)) 
.GetProperty("MyProp") 
.GetCustomAttributes(typeof(System.ComponentModel.DataAnnotations.StringLengthAttribute), true)[0]).MaximumLength;  
} 

: 줄을 추가

당신의 .cshtml 파일의 상단에 :

+0

Benjamin, 당신은 오늘 기계입니다! –

+0

문제 없으니 기꺼이 도와 드리겠습니다. –

2

나는이었다 여기에, 비슷한 무언가로 내 신속하고 더러운 솔루션을 실행 : 난 그냥 스크립트에 그것을 할 오히려 것

@Html.TextBoxFor(model => model.Extension, htmlAttributes: new {maxlength=max }) 

나는 결국 결정했다

<script> 
    $(function() 
    { 
     var max = $("#myinput").attr("data-val-length-max"); 
     $("#myinput").attr("maxlength", max); 
    }); 
</script> 

그러나 스크립트를 추가하지 않으려면 첫 번째 예가 작동해야합니다. 당신이 반사 재료와 면도기의 전망을 오염시키지 않도록 람다 구문을 사용하여 HTML 헬퍼의 확장에 싸여 브래드의 답변에 따라

+0

이 코드는 작동하지만, 도우미와 같은 것을 사용하여 면도기보기를보다 깨끗하게 유지할 수 있습니다. 내 대답을 그 예를 보시오. – djule5

4

기본적으로 :

using System; 
using System.ComponentModel.DataAnnotations; 
using System.Linq; 
using System.Linq.Expressions; 
using System.Reflection; 
using System.Web.Mvc; 

public static class HtmlHelper 
{ 
    public static int? MaxLength<TModel, TProperty>(
     this HtmlHelper<TModel> htmlHelper, 
     Expression<Func<TModel, TProperty>> expression) 
    { 
     MemberExpression memberExpression = (MemberExpression)expression.Body; 

     PropertyInfo property = typeof(TModel) 
      .GetProperty(memberExpression.Member.Name); 

     StringLengthAttribute attribute = (StringLengthAttribute)property 
      .GetCustomAttributes(typeof(StringLengthAttribute), true) 
      .FirstOrDefault(); 

     if (attribute != null) 
     { 
      return attribute.MaximumLength; 
     } 

     return null; 
    } 
} 

등처럼 사용

@Html.TextBoxFor(x => x.Name, new { maxlength = Html.MaxLength(x => x.Name) }) 

여기에서 x은 모델을 나타냅니다.

StringLengthAttribute이 속성에 대해 선언되지 않은 경우 null이 반환되며 maxlength 특성은 textbox 요소에서 비어 있습니다.

방법에 액세스 할 수 있도록 면도기 페이지에서 사용하는 것을 잊지 마십시오.

@using HtmlHelper 

컴파일 오류를 극복하는 방법에 대해서는 null 가능 결과를 사용해야합니다.