2010-03-31 123 views
17

在做ASP.NET MVC 2幾個<%=Html.LabelFor(m=>m.MyProperty)%>和使用[DisplayName("Show this instead of MyProperty")]屬性從System.ComponentModel當我弄糊塗了。奇怪,爲什麼displayName屬性爲LabelFor忽略上覆蓋的屬性今天

事實證明,當我將屬性放在重寫的屬性上時,LabelFor似乎沒有注意到它。
但是,[Required]屬性對重寫的屬性正常工作,生成的errormessage實際上使用DisplayNameAttribute。

這是一些簡單的示例代碼,更現實的情況是我有一個databasemodel獨立於viewmodel,但爲了方便起見,我想繼承databasemodel,添加View-only屬性並裝飾ViewModel用戶界面的屬性。

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

強類型ViewPage<EditModel>包含:

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

標籤,然後顯示爲「PleaseOverrideMe」(使用DisplayNameAttribute )和「這個屬性只存在於EditModel」使用 DisplayNameAttribute)查看頁面時。
如果我發佈具有空值,這種ActionMethod觸發驗證:

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

<%= Html.ValidationMessageFor(model => model.PleaseOverrideMe) %>實際使用[DisplayName("This should be as label for please override me!")]屬性,併產生默認ERRORTEXT 的」這應該是作爲標籤,請忽略我的場!需要。」

一些友善的靈魂會對此有所瞭解嗎?

+0

拉塞,你不得不在此期間任何運氣? – 2010-09-02 13:31:27

+0

如果您使用反射來顯示所有屬性,則可以使用「ModelMetadata」類型。基本上你會這樣做'Html.Label(prop.GetDisplayName())'。 – 2013-08-27 20:58:53

回答

11

Model binding and metadata using the strongly-typed helpers looks at the declared, rather than the runtime, type of the model。我認爲這是一個錯誤,但顯然MVC團隊不同意我的看法,因爲我的Connect問題已被封閉爲「By Design」。

+4

那麼,我會嘗試將它作爲一個bug @ Connect提交,然後爲「By Design」做好準備。 謝謝! – 2010-04-04 21:01:00

+0

不是一個錯誤?我將整個項目移到了MVC 3,這讓我很痛苦。它曾經工作得很好 - DisplayName屬性現在不應該這樣工作嗎? – Jack 2010-09-18 14:27:42

+0

那麼當你重載編輯/顯示對象模板並使用'Html.EditorForModel'時會發生什麼?在你的模板中你使用'Html.Label()',你不能得到Display屬性。按設計?他們是否僱用IE團隊的白癡? – 2013-08-27 20:51:28

2

我有一個相同的問題,當我有一個局部視圖強類型的接口。該接口定義了DisplayName,並且實現該接口的類試圖覆蓋它。我發現讓它尊重覆蓋的唯一方法是鍵入實現類。我不得不改變視圖的模型類型或強制轉換。不幸的是,這完全否定了使用界面作爲模型類型的好處。我猜測我最終會得到一些級別的每個實現類的重複視圖標記,而不是在強類型的「助手」中投射。

在遠程機會,這種類型的解決方法甚至遠程幫助(沒有得到我的希望),這裏是一個例子。對於嘗試覆蓋名稱的所有可能的實現類,確實有辦法處理此問題,但肯定比應該更麻煩。

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

我跑進使用[DisplayName的(「配置文件名稱」)]這個問題,並用來代替[Display(Name = "Profile Name")]其固定在我的情況的問題。我不確定這是否有用。

前者來自System.ComponentModel而後者來自System.ComponentModel.DataAnnotations

+3

六年後,這個問題在MVC 5中修復了同樣的問題:) – pmbanka 2016-02-16 15:59:55

+1

+七。固定在覈心mvc *大拇指* – 2017-01-26 11:16:56

3

好吧,我似乎找到了一個解決方法,如果你不使用必需的標籤!只需使用正則表達式或長度屬性來確定是否存在有效的條目。希望這會有所幫助,雖然有點晚。

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

仍然有效。

3

在我的情況下,我被遺忘了使用getter和setters使它成爲一個屬性。 而不是

public string CompanyName; 

我應該用

public string CompanyName {get;set;}