2013-02-06 23 views
7

Dưới đây là tài sản trong ViewModel của tôi:StringLength trong ViewModel không thiết maxlength trên textbox

[Display(Name = "Ext.")] 
[MaxLength(6, ErrorMessage = "Must be a maximum of 6 characters")] 
[StringLength(6)] 
public string Extension { get; set; } 

Và trong quan điểm của tôi:

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

Và nó ám:

<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="" /> 

nên này được thiết lập thuộc tính maxlength trên hộp văn bản của tôi? Nếu không, làm thế nào tôi có thể làm điều đó với DataAttributes?

+0

Bạn đã xác minh xem bạn có thể đăng chuỗi dài hơn 6 ký tự không? –

+0

Tôi nhận được một lỗi xác nhận, nhưng tôi muốn nó thực sự thiết lập thuộc tính maxlength. –

+0

Nếu bạn thay đổi nó thành 'TextBoxFor', bạn có thể chuyển các tùy chọn HTML. –

Trả lời

4

Tôi muốn thuộc tính mà tôi đặt trong ViewModel để kiểm soát điều này nếu có thể.

ASP.NET MVC cung cấp hệ thống mở rộng để thực hiện chính xác điều này. Dưới đây là những gì bạn cần làm:

  1. Thực hiện tùy chỉnh ModelMetadataProvider.
  2. Tìm kiếm StringLengthAttribute hoặc MaxLengthAttribute, trích xuất thông tin và thêm thông tin vào ModelMetadata.
  3. Cung cấp mẫu Trình chỉnh sửa tùy chỉnh sử dụng thông tin.

Bước 1: Thực hiện tùy chỉnh ModelMetadataProvider.

Tạo lớp học có nguồn gốc từ ModelMetadataProvider. Thông thường, bạn sẽ lấy được từ số DataAnnotationsModelMetadataProvider vì điều này cung cấp một số chức năng mặc định có nghĩa là bạn chỉ phải ghi đè lên một phương thức có tên là CreateMetadata.

Bước 2: Giải nén thông tin:

Để có được thông tin, bạn cần phải tìm kiếm các thuộc tính, trích xuất các thông tin dài tối đa và thêm nó vào từ điển AdditionalValues của ModelMetadata. Việc thực hiện sẽ giống như thế này (đây là toàn bộ thực hiện):

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

Để cho ASP.NET MVC sử dụng này, bạn cần phải đăng ký nó trong phương pháp Application_Start trong Global.asax.

ModelMetadataProviders.Current = new CustomModelMetadataProvider(); 

Bước 3: Tạo một mẫu biên tập tùy chỉnh.

Bây giờ bạn cần tạo chế độ xem sử dụng thông tin. Tạo chế độ xem mới có tên là String trong thư mục Views\Shared\.

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) 

Khi bạn chạy ứng dụng của bạn, bạn sẽ nhận được đầu ra HTML sau bằng cách gọi @Html.EditorFor.

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

Nếu bạn muốn biết thêm về hệ thống cung cấp mô hình siêu dữ liệu, Brad Wilson has a series of blog posts rằng chi tiết cách thức hoạt động (những được viết trước khi công cụ xem Razor vì vậy một số quan điểm Cú pháp là một chút sôi nổi nhưng nếu không thông tin Là âm thanh).

+0

Benjamin, bạn là một cỗ máy ngay hôm nay! –

+0

Không sao cả, tôi rất vui được giúp đỡ. –

2

tôi chạy vào một cái gì đó tương tự, đây là giải pháp nhanh chóng và dơ bẩn của tôi:

ở phía trên cùng của tập tin .cshtml bạn thêm dòng:

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

thấp hơn trong html của bạn thay thế các EditorFor với :

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

tôi cuối cùng quyết định rằng tôi chỉ muốn làm điều đó trong kịch bản:

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

nhưng nếu bạn không muốn thêm tập lệnh, ví dụ đầu tiên sẽ hoạt động.

+0

Mã này hoạt động, nhưng bạn có thể muốn giữ cho trình xem Razor của bạn sạch hơn bằng cách sử dụng một cái gì đó giống như một người trợ giúp. Xem câu trả lời của tôi cho một ví dụ về điều đó. – djule5

4

Về cơ bản dựa trên câu trả lời của Brad, được bọc trong một phần mở rộng trên helper Html sử dụng cú pháp lambda do đó bạn không gây ô nhiễm quan điểm Razor của bạn với sự phản ánh thứ:

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

Sử dụng nó như ví dụ:

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

nơi x đề cập đến mô hình của bạn.

Nếu số StringLengthAttribute không được khai báo cho thuộc tính, null sẽ được trả lại và thuộc tính maxlength sẽ trống trên phần tử hộp văn bản.

Hãy nhớ bao gồm việc sử dụng trang dao cạo của bạn để bạn có thể truy cập phương thức.

@using HtmlHelper 

Bạn cũng cần phải sử dụng không có kết quả không khả thi nào cho phương pháp khắc phục lỗi biên dịch.

Các vấn đề liên quan