2011-02-09 32 views
0

我曾經在某處看過如何在博客上做這個,但我忘記了在哪裏或如何。可以說我在類庫中有一個域。我想數據註釋這個域的屬性作爲我的viewmodel在web項目中。ASP.NET MVC數據註釋在web項目中的域模型

我該如何做到這一點?

例如。您正在訪問的是在我的類庫:

public class Person { 
    public int Id {get; set;} 
    public string FirstName {get; set;} 
} 

在我的web項目中,有這樣的:

//Do i need to set some attribute here? 
public class CreatePersonViewModel{ 

    [Required()] 
    [DisplayName("First Name")] 
    public string FirstName {get; set;} 
} 

該代碼可以被映射到Person不使用工具。可能是部分或某事。

+0

不,你不需要設置屬性,你有'//我需要在這裏設置一些屬性嗎?如果您的控制器操作具有參數類型「CreatePersonViewModel」,則驗證屬性將運行以確定「ModelState」是否有效。 –

+2

我低估了所有鼓勵使用元數據類的答案。元數據夥伴類完全使得擁有一個域或關注點分離的目的無效。界面應該指向你的域名,而不是指向你的用戶界面的域名。這是一個令人沮喪的可怕做法。 – jfar

+0

@jfar:嚴格來說,元數據類正在分離一個問題 - 儘管這不是你輕易做的事情。這是一個很好的觀點,但你的行爲在這裏做一些傷害:在你的模型生成的情況下,很可能你不能註釋實際的屬性,但很可能你可以添加一個屬性到部分類定義。 –

回答

4

使用視圖模型的整體思路是從你的域模型脫鉤,並有一些東西,是適應需求的看法。視圖模型應該在web項目中聲明幷包含這個特定視圖可能需要的所有必要的屬性和格式屬性。域模型不應該受到任何視圖特定數據註釋的污染。所以,如果你的模型是這樣的:

public class Person { 
    public int Id { get; set; } 
    public string FirstName { get; set; } 
} 

你可以有以下視圖模型:

public class CreatePersonViewModel { 
    [Required] 
    [DisplayName("First Name")] 
    public string FirstName { get; set; } 
} 

,然後讓控制器從某些存儲庫中取出模型,將其映射到視圖模型(AutoMapper可以幫助你)並將視圖模型傳遞給視圖。

+0

我不同意 - 我有我的數據層聲明我的註釋,因爲數據庫字段「TownSuburb」總是會有一個「城鎮/郊區」的標籤。 ..爲什麼我想在我的視圖中爲我的站點的不同組件設置2,3,4倍,因爲我在多個前端共享數據庫? – Rob

+0

@Rob,因爲您正在將模型綁定到特定的演示文稿。如果在另一個應用程序中該字段應該被稱爲別的東西呢? –

+0

這是正確的,所以這個答案是不正確的 - 正確的答案是「它取決於域」 - 此外,爲什麼你想要解耦特定於數據庫列的驗證規則?你不想改變INT列的驗證規則,爲什麼不把它與模型緊密結合呢? – Rob

1

你說的是這種類型的事情?:

using System.ComponentModel.DataAnnotations; 

public MyClass 
{ 


    [DisplayName("Street Address")] 
    public string StreetAddress { get; set; } 

} 

編輯:

如果您需要將數據添加註解生成的類好像是實體做到這一點:

using System.ComponentModel.DataAnnotations; 
using System.ComponentModel; 

namespace Something 

{ 
    [MetadataType(typeof(MetaMyClass))] 
    public partial class MyClass 
    { 
      //You can just leave this empty if you have nothing additional to add to the class 

    } 

    public class MetaMyClass 
    { 
     [DisplayName("Street Address")] 
     public string StreetAddress { get; set; } 
    } 
} 
+0

是的,但'MyClass'已經存在,我不能使用'[DisplayName(「街道地址」)]'。有一種方法可以向它添加註釋。 –

1

你的意思是註釋你的域對象或你的視圖模型對象?

使用System.ComponentModel.DataAnnotations驗證特性(從ValidationAttribute獲得任何你自己的,你可以在模型的點驗證綁定到您的視圖模型的屬性值結合。

斯科特·格思裏有detailed blog post about Model validation with data annotation validation attributes

編輯:你到你的類型已經存在另一個海報評論說,您可以將MetadataTypeAttribute添加到現有的類型,表示另一種類型的持有的VA。解鎖邏輯應用於您現有類型的屬性。

+0

我在看這個:http://stackoverflow.com/questions/1882338/can-i-add-mvc-2-dataannotation-attributes-to-existing-properties/1882428#1882428我不能把'[MetadataTypeAttribute] '在原始模型上,因爲它不知道視圖模型。或者是另一種方式? –

+0

viewmodels背後的想法是,它們旨在將數據傳遞給(或從)您的視圖到您的控制器。它們不一定與你的域對象有一個「代碼」關聯(就像關聯它們的屬性,繼承等一樣)。在控制器內部,您可能會執行視圖模型和域對象之間的值映射。您*不能*使用視圖模型,只是將域對象傳遞給視圖,但由於模型驗證如何工作,在執行此操作時需要注意某些問題。 –

+0

看看Brad Wilson的模型驗證文章 - http://bradwilson.typepad.com/blog/2010/01/input-validation-vs-model-validation-in-aspnet-mvc.html。他分別介紹了MVC 1和MVC 2之間從輸入驗證到模型驗證的轉變,但他所說的有關模型驗證的內容仍然適用於MVC 2和MVC 3. –

1

您可以爲您的數據註釋創建一個「夥伴」類屬性

[MetadataType(typeof(ResourceMetadata))] 
public partial class Resource 
{ 
    public object Value { get; set; } 
} 

public class ResourceMetadata 
{ 
    // The metadata class can define hints 

    [UIHint("ResourceValue")] 
    public object Value { get; set; } 
} 
+0

愉快的downvote是歡迎的 –