2012-01-11 39 views
7

Tôi có một kiểu xem được chia sẻ bởi hai trang khác nhau. Các mô hình xem khá giống với ngoại lệ của một thuộc tính: Địa chỉ. Mô hình khung nhìn có chứa các trường tên và vị trí. Tuy nhiên, nhãn địa chỉ của khách hàng nên đọc: Địa chỉ khách hàng và nhãn địa chỉ của nhân viên nên đọc: Địa chỉ của nhân viên. Họ cũng sẽ hiển thị các thông báo lỗi khác nhau.Các thuộc tính ghi đè của Mô hình Xem cơ bản trong ASP.NET MVC 3

Dưới đây là một phiên bản đơn giản của những gì tôi đang cố gắng để hoàn thành:

public class BaseLocation 
{ 
    [Display(Name="Your Name")] 
    public string Name {get;set;} 

    public virtual string Address {get;set;} 
} 

public class CustomerLocation : BaseLocation 
{ 
    [Display(Name="Customer Address")] 
    public override string Address {get;set;} 
} 

public class EmployeeLocation : BaseLocation 
{ 
    [Display(Name="Employee Address")] 
    public override string Address {get;set;} 
} 

Sau đó, tôi đã tạo ra một phần cho các vị trí cơ sở, như vậy:

@model BaseLocation 
***ASP.NET MVC Helpers here: labels, text, validation, etc. 

Cuối cùng, trong khách hàng và Trang nhân viên, tôi sẽ gọi một phần và gửi cho nó loại được phân loại.

Customer.cshtml 
@model CustomerLocation 
@Html.Render("_BaseLocation", Model) 


Employee.cshtml 
@model EmployeeLocation 
@Html.Render("_BaseLocation", Model) 

Kết quả là tôi sẽ không thấy thuộc tính dữ liệu cho loại cụ thể. Ví dụ: trong trang khách hàng, tôi sẽ nhận được nhãn "Địa chỉ" thay vì "Địa chỉ khách hàng".

Tôi không muốn tạo hai phần có cùng dữ liệu cho từng loại cụ thể, đơn giản vì một thuộc tính trong mô hình chế độ xem được chia sẻ phải có nhãn và thông báo lỗi khác. Cách tốt nhất để giải quyết vấn đề này là gì? Cảm ơn.

+0

Hãy thử tạo bản tóm tắt cơ bản, xem liệu nó có thay đổi gì không. – gdoron

+0

@gdoron, nó sẽ không thay đổi gì cả. –

+0

@DarinDimitrov, Vì vậy, cách duy nhất tôi có thể nghĩ đến là viết 'HtmlHelper' của riêng bạn làm công việc đúng. – gdoron

Trả lời

1

Do cách thức xem hoạt động thừa kế và cách mô hình được xác định tham số được truyền vào một cái gì đó như LabelForTextBoxFor sử dụng loại mô hình được xác định trong lớp. Trong trường hợp của bạn nó sẽ luôn luôn là BaseLocation đó là lý do tại sao nó không bị ghi đè.

Bạn không nhất thiết phải tạo partials cho lớp học của mình nhưng bạn sẽ phải tạo hai chế độ xem cho khách hàng và một lượt xem cho nhân viên. Vì bạn đã có hai chế độ xem cụ thể cho mỗi loại, bạn sẽ chỉ phải tạo một chế độ xem vị trí khác hoặc hợp nhất chế độ xem baselocation vào bố cục đó.

Customer.cshtml 
@model CustomerLocation 
@Html.Render("_CustomerBaseLocation", Model) 


Employee.cshtml 
@model EmployeeLocation 
@Html.Render("_EmployeeBaseLocation", Model) 

Tôi chắc chắn hiểu vấn đề của bạn vì bạn chỉ muốn thay đổi một chế độ xem và bạn có thể có một số loại tình huống tương tự đã có với BaseLocation.

Bạn có thể làm một cái gì đó như thế này ...

public static IHtmlString LabelTextFor<TModel, TValue>(this HtmlHelper<TModel> html, object model, Expression<Func<TModel, TValue>> expression) 
{ 
    MemberExpression memberExpression = (MemberExpression)expression.Body; 
    var propertyName = memberExpression.Member is PropertyInfo ? memberExpression.Member.Name : null; 

    //no property name 
    if (string.IsNullOrWhiteSpace(propertyName)) return MvcHtmlString.Empty; 

    //get display text 
    string resolvedLabelText = null; 
    var displayattrib = model.GetType().GetProperty(propertyName) 
       .GetCustomAttributes(true) 
       .SingleOrDefault(f => f is DisplayAttribute) 
             as DisplayAttribute; 
    if (displayattrib != null) { 
     resolvedLabelText = displayattrib.Name; 
    } 

    if (String.IsNullOrEmpty(resolvedLabelText)) { 
     return MvcHtmlString.Empty; 
    } 

    TagBuilder tag = new TagBuilder("label"); 
    tag.Attributes.Add("for", TagBuilder.CreateSanitizedId(html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(""))); 
    tag.SetInnerText(resolvedLabelText); 
    return new HtmlString(tag.ToString()); 
} 

Sau đó, trong bạn _BaseLocation.cshtml bạn sẽ thực hiện cuộc gọi như:

@Html.LabelTextFor(Model, m => m.Address) 

Viết một phương pháp mở rộng thông thường để làm điều này là tất cả những gì tôi có thể nghĩ đến là

+0

Phương pháp cụ thể này dựa trên 'DisplayAttribute' và không cho phép các phương pháp thay thế thêm modelMetadata như sử dụng 'IModelMetadata'. – Buildstarted

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