Asp.net mvc 2 关于ASP.NET MVC 2自定义视图模型的问题
在我的项目中,我有我的Linq到SQL dbml文件,每个DB表有一个存储库层,每个存储库有一个服务层 在我的服务中,我有一些用于验证的元数据,并且我扩展了每个(表)类以向对象添加一些自定义信息(您将在下面的代码中看到这一点) 我的问题是,我是否应该考虑为每个(表)类建立一个自定义的VIEW模式,而不是在服务层使用扩展类?< /P> 下面是我现在拥有的一个例子 存储库Asp.net mvc 2 关于ASP.NET MVC 2自定义视图模型的问题,asp.net-mvc-2,viewmodel,service-layer,Asp.net Mvc 2,Viewmodel,Service Layer,在我的项目中,我有我的Linq到SQL dbml文件,每个DB表有一个存储库层,每个存储库有一个服务层 在我的服务中,我有一些用于验证的元数据,并且我扩展了每个(表)类以向对象添加一些自定义信息(您将在下面的代码中看到这一点) 我的问题是,我是否应该考虑为每个(表)类建立一个自定义的VIEW模式,而不是在服务层使用扩展类?< /P> 下面是我现在拥有的一个例子 存储库 Namespace Domain #Region "Interface" Public Interface IUse
Namespace Domain
#Region "Interface"
Public Interface IUserRepository
Sub AddUser(ByVal openid As OpenID)
Function GetUsers() As IQueryable(Of User)
Sub UpdateUser(ByVal user As User)
Sub SubmitChanges()
End Interface
#End Region
#Region "Repository"
Public Class UserRepository : Implements IUserRepository
Private dc As MyDatabaseDataContext
Public Sub New()
dc = New MyDatabaseDataContext
End Sub
Public Sub AddUser(ByVal openid As OpenID) Implements IUserRepository.AddUser
Dim user As New User
user.MemberSince = DateTime.Now
openid.User = user
dc.OpenIDs.InsertOnSubmit(openid)
End Sub
Public Function GetUsers() As IQueryable(Of User) Implements IUserRepository.GetUsers
Dim users = (From u In dc.Users
Select u)
Return users.AsQueryable
End Function
Public Sub UpdateUser(ByVal user As User) Implements IUserRepository.UpdateUser
Dim _user = (From u In dc.Users
Where u.ID = user.ID
Select u).Single
With _user
.About = user.About
.BirthDate = user.BirthDate
.Email = user.Email
.isClosed = user.isClosed
.isProfileComplete = user.isProfileComplete
.RegionID = user.RegionID
.Reputation = user.Reputation
.UserName = user.UserName
.WebSite = user.WebSite
End With
End Sub
Public Sub SubmitChanges() Implements IUserRepository.SubmitChanges
dc.SubmitChanges()
End Sub
End Class
#End Region
End Namespace
服务
Imports System.ComponentModel.DataAnnotations
Namespace Domain
#Region "Validation"
<MetadataType(GetType(UserMetaData))> _
Partial Public Class User
Public Property UserRegion As String
Public Property LastSeen As DateTime
Public ReadOnly Property Slug(ByVal user As User) As String
Get
Return Replace(user.UserName, " ", "-")
End Get
End Property
End Class
''' <summary>
''' Validation for all User data.
''' </summary>
''' <remarks>All validation is done at the Service Layer</remarks>
Public Class UserMetaData
<DisplayName("name")> _
<Required(ErrorMessage:="Username is required.")> _
<StringLength(30, ErrorMessage:="Username cannot exceed 30 characters.")> _
<RegularExpression("^\w{3,30}$", ErrorMessage:="Not a valid username.")> _
Public Property UserName As String
<DisplayName("email")> _
<StringLength(50, ErrorMessage:="Email Address cannot exceed 50 characters.")> _
<RegularExpression("^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})$", ErrorMessage:="Not a valid email address.")> _
Public Property Email As String
<DisplayName("website")> _
<StringLength(256, ErrorMessage:="Web Address cannot exceed 256 characters.")> _
<RegularExpression("^http(s?)\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(/\S*)?$", ErrorMessage:="Not a valid website address.")> _
Public Property WebSite As String
<DisplayName("about")> _
<StringLength(2000, ErrorMessage:="Profile cannot exceed 2000 characters.")> _
Public Property About As String
<DisplayName("region")> _
<Required(ErrorMessage:="Region is required.")> _
Public Property UserRegion As Integer
<DisplayName("birthdate")> _
<DisplayFormat(ApplyFormatInEditMode:=True, ConvertEmptyStringToNull:=True, DataFormatString:="{0:MM/dd/yyyy}")> _
Public Property BirthDate As DateTime
End Class
#End Region
#Region "Interface"
Public Interface IUserService
Sub AddUser(ByVal claimedidentifier As String, ByVal notes As String)
Function GetAllUsers() As IList(Of User)
Function GetUserByID(ByVal id As Integer) As User
Sub UpdateUser(ByVal user As User)
Sub SubmitChanges()
End Interface
#End Region
#Region "Service"
Public Class UserService : Implements IUserService
Private _UserRepository As IUserRepository
Public Sub New(ByVal UserRepository As IUserRepository)
_UserRepository = UserRepository
End Sub
Public Sub AddUser(ByVal claimedidentifier As String, ByVal notes As String) Implements IUserService.AddUser
Dim openid As New OpenID
openid.ClaimedIdentifier = claimedidentifier
openid.UserNotes = notes
_UserRepository.AddUser(openid)
End Sub
Public Function GetAllUsers() As System.Collections.Generic.IList(Of User) Implements IUserService.GetAllUsers
Return _UserRepository.GetUsers().Where(Function(u) (Not u.isClosed)).ToList
End Function
Public Function GetUserByID(ByVal id As Integer) As User Implements IUserService.GetUserByID
Return _UserRepository.GetUsers().Where(Function(u) (Not u.isClosed And u.ID = id)).SingleOrDefault
End Function
Public Sub UpdateUser(ByVal user As User) Implements IUserService.UpdateUser
_UserRepository.UpdateUser(user)
End Sub
Public Sub SubmitChanges() Implements IUserService.SubmitChanges
_UserRepository.SubmitChanges()
End Sub
End Class
#End Region
End Namespace
现在我遇到的一件事是,每当我需要使用Slug时,都需要将user对象发送到Slug属性
Dim user As Domain.User = UserService.GetUserByID(id)
user.Slug = user.Slug(user) ''# this seems like a bit of a pain in the ass
Return View(user)
因此,对于我来说,为每个(表)类创建一个自定义ViewModal并简单地执行以下操作是否更好
Dim user As Domain.UserViewModal = New Domain.UserViewModal(UserService.GetUserByID(id))
''# The UserViewModal will automatically do all the work to create the
''# Slug as well as other pertinent information
Return View(user)
在我看来,分离是件好事,但仍然需要大量的时间来构建。只是想知道权衡的好处,或者是否有更好的方法来完成同样的事情?您可能会发现您的模型类并不总是与视图1:1对应。仅出于这个原因,创建ViewModel对象并使用它们与视图交互是有意义的,因为ViewModel对象可以是各种模型信息的组合 这样做的另一个好处是确保viewmodel对象特别适合用户界面,并且可能包含屏幕特定列表或其他与普通模型对象无关的属性。这允许您反过来实现好处,因为您的viewmodel对象不需要被任何东西弄乱/膨胀,除了它们在生活中的用途。(Linq到SQL对象必须跟踪状态,并完成与UI完全无关的大量工作。) 虽然分离是一种很好的做法,但正如你所说,它可能是一种“屁股痛”。为了使在类实例之间传输信息变得更容易,请查看哪种方法可以很好地实现这一点,并允许您消除无数行繁琐但必要的代码
快乐编码 很抱歉这个冗长的问题。谢谢你的见解。插入和编辑视图是否也使用ViewModal?是的,我几乎在所有情况下都使用viewmodel。我通常没有专门用于插入或编辑的视图,但当我这样做时,通常至少有一个下拉列表,我希望通过将列表作为ViewModel的属性传递给视图来填充该列表,以便在视图中填充dd。(在大多数情况下,我更喜欢使用我的ViewModel对象而不是ViewData[]
Dim user As Domain.UserViewModal = New Domain.UserViewModal(UserService.GetUserByID(id))
''# The UserViewModal will automatically do all the work to create the
''# Slug as well as other pertinent information
Return View(user)