2012-01-11 11 views
7

2つの異なるページで共有されるビューモデルがあります。ビューモデルは、1つのプロパティ(アドレス)を除いて、かなり似ています。ビューモデルには、名前と場所フィールドが含まれます。ただし、顧客ビューのアドレスラベルには「Customer Address」と表示され、従業員ビューのアドレスラベルには「Employee Address」と表示されます。また、さまざまなエラーメッセージが表示されます。ASP.NET MVC 3でのベースビューモデルのプロパティのオーバーライド

は、ここで私が達成しようとしているものの簡易版です。

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

は、それから私は、のようなので、基本場所の部分を作成しました:

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

を、お客様にと従業員のページでは、私は部分を呼び出し、サブクラス化された型を送信します。

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


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

結果、特定のタイプのデータ属性は表示されません。たとえば、顧客ページでは、「顧客アドレス」の代わりに「住所」のラベルを取得します。

共有ビューモデル内の1つのプロパティが異なるラベルとエラーメッセージを持つ必要があるため、特定のタイプごとに同じデータで2つの部分データを作成するのではなく、これについてはどうすればいいですか?ありがとう。

+0

何か変更があるかどうかを確認してください。 – gdoron

+0

@godon、それは何も変更されません。 –

+0

@DarinDimitrovだから、私が考えることができる唯一の方法は、仕事を正しく行うあなた自身の 'HtmlHelper'を書くことです。 – gdoron

答えて

1

ビュー継承の仕組みとモデルの定義方法のため、LabelForTextBoxForのようなものに渡されるパラメータは、クラスで定義されたモデルタイプを使用します。あなたの場合は常にそれがオーバーライドされていない理由はBaseLocationになるだろう。

クラスのパーシャルを作成する必要はありませんが、顧客用と従業員用の2つのビューを作成する必要があります。各タイプに固有の2つのビューがすでにあるので、別のロケーションビューを作成するか、ベースラインビューをその親にマージするだけで済みます。

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


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

あなたが1つのビューのみを変更したいとあなたがBaseLocationと、すでに状況のこれらの類似したタイプのいくつかを持っている可能性があるので、私は間違いなくあなたの問題を理解しています。はこのような何かを行うことができ

あなた...のように

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

はその後で、あなたの_BaseLocation.cshtmlあなたが電話をかけるでしょう。

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

これを行うには、カスタム拡張メソッドを書きます私が考えることができることのすべてについてです

+0

この特定のメソッドは、 'DisplayAttribute'に依存し、代替メソッドIModelMetadataを使用するなど、modelMetadataを追加する必要があります。 – Buildstarted

関連する問題