2010-03-31 33 views
17

hôm nay tôi đã nhầm lẫn khi thực hiện một vài số <%=Html.LabelFor(m=>m.MyProperty)%> trong ASP.NET MVC 2 và sử dụng thuộc tính [DisplayName("Show this instead of MyProperty")] từ System.ComponentModel.Tự hỏi tại sao thuộc tính DisplayName bị bỏ qua trong LabelFor trên thuộc tính bị ghi đè

Khi nó bật ra, khi tôi đặt thuộc tính trên thuộc tính bị ghi đè, LabelFor dường như không nhận thấy nó.
Tuy nhiên, thuộc tính [Required] hoạt động tốt trên thuộc tính bị ghi đè và thông báo lỗi được tạo thực sự sử dụng DisplayNameAttribute.

Đây là một số câu hỏi tầm thường, kịch bản thực tế hơn là tôi có một databasemodel tách biệt với viewmodel, nhưng để thuận tiện, tôi muốn kế thừa từ databasemodel, thêm thuộc tính chỉ xem và trang trí viewmodel với thuộc tính cho giao diện người dùng.

public class POCOWithoutDataAnnotations 
{ 
    public virtual string PleaseOverrideMe { get; set; }   
} 
public class EditModel : POCOWithoutDataAnnotations 
{ 
    [Required] 
    [DisplayName("This should be as label for please override me!")] 
    public override string PleaseOverrideMe 
    { 
     get { return base.PleaseOverrideMe; } 
     set { base.PleaseOverrideMe = value; } 
    } 

    [Required] 
    [DisplayName("This property exists only in EditModel")] 
    public string NonOverriddenProp { get; set; } 
} 

Các mạnh mẽ gõ ViewPage<EditModel> chứa:

 <div class="editor-label"> 
      <%= Html.LabelFor(model => model.PleaseOverrideMe) %> 
     </div> 
     <div class="editor-field"> 
      <%= Html.TextBoxFor(model => model.PleaseOverrideMe) %> 
      <%= Html.ValidationMessageFor(model => model.PleaseOverrideMe) %> 
     </div> 

     <div class="editor-label"> 
      <%= Html.LabelFor(model => model.NonOverriddenProp) %> 
     </div> 
     <div class="editor-field"> 
      <%= Html.TextBoxFor(model => model.NonOverriddenProp) %> 
      <%= Html.ValidationMessageFor(model => model.NonOverriddenProp) %> 
     </div> 

Các nhãn này sau đó được hiển thị như "PleaseOverrideMe" (không sử dụng DisplayNameAttribute) và "Khách sạn này chỉ tồn tại trong EditModel" (sử dụng DisplayNameAttribute) khi xem trang.
Nếu tôi đăng với các giá trị rỗng, gây ra xác nhận với ActionMethod này:

[HttpPost] 
    public ActionResult Edit(EditModel model) 
    { 
     if (!ModelState.IsValid) 
      return View(model); 
     return View("Thanks"); 
    } 

các <%= Html.ValidationMessageFor(model => model.PleaseOverrideMe) %> thực sự sử dụng [DisplayName("This should be as label for please override me!")] thuộc tính, và tạo ra mặc định errortext "Các này nên càng nhãn cho xin vui lòng ghi đè tôi lĩnh vực là! cần thiết."

Một số linh hồn thân thiện có thể làm sáng tỏ điều này không?

+0

Lasse, bạn có bất kỳ may mắn trong thời gian chuyển tiếp? –

+0

Nếu bạn đang sử dụng sự phản chiếu để hiển thị tất cả các thuộc tính của bạn, bạn có kiểu 'ModelMetadata' có sẵn cho bạn. Về cơ bản bạn sẽ làm điều này 'Html.Label (prop.GetDisplayName())'. –

Trả lời

11

Model binding and metadata using the strongly-typed helpers looks at the declared, rather than the runtime, type of the model. Tôi coi đây là một lỗi, nhưng dường như nhóm MVC không đồng ý với tôi, vì vấn đề Connect của tôi về vấn đề này đã bị đóng lại là "Thiết kế".

+4

Vâng, tôi sẽ thử nộp nó như là một lỗi @ Kết nối và được chuẩn bị cho "By Design" sau đó. Cảm ơn! –

+0

Không phải là lỗi? Tôi đã chuyển toàn bộ dự án của mình sang MVC 3 và đây là một nỗi đau ở bên cạnh tôi. Nó được sử dụng để làm việc tốt - là thuộc tính DisplayName không phải làm việc theo cách này ngay bây giờ? – Jack

+0

Vậy điều gì sẽ xảy ra khi bạn ghi đè lên mẫu đối tượng chỉnh sửa/hiển thị và sử dụng 'Html.EditorForModel'? Trong khuôn mẫu của bạn, bạn sử dụng 'Html.Label()' và bạn không thể lấy thuộc tính Display. Thiết kế bởi? Họ đã thuê morons từ nhóm IE chưa ?. –

2

Tôi gặp vấn đề tương tự khi tôi đã xem một phần được đánh mạnh vào giao diện. Giao diện được định nghĩa là DisplayName và lớp đã triển khai giao diện đã cố gắng ghi đè giao diện đó. Cách duy nhất tôi tìm thấy để có được nó để tôn trọng việc ghi đè là gõ vào lớp thực hiện. Tôi đã phải thay đổi kiểu hoặc loại bỏ của chế độ xem. Thật không may, điều đó hoàn toàn phủ nhận lợi ích của việc sử dụng giao diện như kiểu mô hình. Tôi đoán rằng tôi sẽ kết thúc với một số mức độ đánh dấu xem trùng lặp cho mỗi lớp thực hiện trong khi không đúc trong "người giúp đỡ" mạnh mẽ đánh máy.

Trong cơ hội từ xa rằng kiểu giải pháp này thậm chí còn hữu ích từ xa (không nhận được hy vọng của tôi), đây là một ví dụ. Có chắc chắn cách xử lý làm việc này cho tất cả các lớp thực hiện có thể cố gắng ghi đè tên, nhưng nó chắc chắn là rắc rối hơn nó phải được.

public interface IAddressModel { 
    ... 
    [DisplayName("Province")] 
    public string Province { get; set; } 
    ... 
} 
public class UsAddressModel : IAddressModel { 
    ... 
    [DisplayName("State")] 
    public string Province { get; set; } 
    ... 
} 

<%= Html.LabelFor(m => m.State) %> <!--"Province"--> 
<%= Html.LabelFor(m => (m as UsAddressModel).State) %> <!--"State"--> 
11

Tôi gặp sự cố này khi sử dụng [DisplayName ("Tên hồ sơ")] và thay vào đó sử dụng [Display(Name = "Profile Name")] để khắc phục sự cố trong trường hợp của tôi. Tôi không chắc liệu điều này có hữu ích không.

Giá trị cũ là từ System.ComponentModel trong khi số thứ hai là từ System.ComponentModel.DataAnnotations.

+3

Sáu năm sau, điều này cố định cùng một vấn đề trong MVC 5 :) – pmbanka

+1

+ bảy. Đã sửa lỗi trong mvc * lõi * –

3

Ok, có vẻ như tôi đã tìm thấy giải pháp thay thế nếu bạn không sử dụng thẻ Bắt buộc với nó! chỉ cần sử dụng biểu thức chính quy hoặc thuộc tính độ dài để xác định xem có mục nhập hợp lệ hay không. Hy vọng điều này sẽ giúp, mặc dù hơi trễ một chút.

[RegularExpression(@"^[1-9][0-9][0-9]$")] //validates that there is at least 1 in the quantity and no more than 999 
[DisplayName("Quantity:")] 
public string quantity { get; set; } 

Vẫn hoạt động.

3

Trong trường hợp của tôi, tôi đã quên biến nó trở thành tài sản bằng cách sử dụng getters và setters. Thay vì

public string CompanyName; 

tôi nên đã sử dụng

public string CompanyName {get;set;} 
Các vấn đề liên quan