视图模型:
Public Class UserViewModel
<Display(Name:="Roles List")> _
Public ReadOnly Property AllRoles As IEnumerable(Of SelectListItem)
Get
Dim dbContext As New AuthUserContext
Dim roleQuery = (From r In dbContext.AuthRoleSet Select r Where r.isActive = True)
Dim roles As IEnumerable(Of AuthRole) = roleQuery.ToList()
Return roles.Select(Function(o) New SelectListItem() With {.Text = o.RoleName, .Value = o.AuthRoleID})
End Get
End Property
Public Property User As New AuthUser
End Class
我的AuthUser课程:
Public Class AuthUser
'Properties
Public Property AuthUserID() As Integer
<Required()> _
<Display(Name:="User Name")> _
Public Property UserName() As String
<Required()> _
<Display(Name:="Current Roles")> _
Public Overridable Property AuthRoles As ICollection(Of AuthRole)
End Class
Public Class AuthRole
Public Property AuthRoleID() As Integer
<Required()> _
<Display(Name:="Role Name")> _
Public Property RoleName() As String
<Required()> _
<Display(Name:="Is Active")> _
Public Property isActive() As Boolean
Public Overridable Property AuthUser As ICollection(Of AuthUser)
End Class
我的控制器:
Function CreateUser() As ActionResult
Dim model As New UserViewModel
Return View(model)
End Function
我的帖子控制器:
Function CreateUser(ByVal authuser As UserViewModel) As ActionResult
If ModelState.IsValid Then
db.AuthUserSet.Add(authuser.User)
db.SaveChanges()
Return RedirectToAction("Index")
End If
Return View(authuser)
End Function
我的观点:
@Using Html.BeginForm()
@Html.ValidationSummary(True)
@Html.AntiForgeryToken()
@<fieldset>
<legend>AuthUser</legend>
<div class="editor-label">
@Html.LabelFor(Function(model) model.User.UserName)
</div>
<div class="editor-field">
@Html.TextBoxFor(Function(model) model.User.UserName)
@Html.ValidationMessageFor(Function(model) model.User.UserName)
</div>
<div class="editor-label">
@Html.LabelFor(Function(model) model.User.AuthRoles)
</div>
<div class="editor-field">
@Html.DropDownListFor(Function(model) model.User.AuthRoles, Model.AllRoles, "-- Select Role--")
@Html.ValidationMessageFor(Function(model) model.User.AuthRoles)
</div>
@*Have to fill this is for ModelState validation - via jQuery*@
@Html.HiddenFor(Function(model) model.User.AuthRoles)
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
End Using
好吧,我在这里做的就是将我所有可用的角色都读到我的ViewModel中。我想将它们列为下拉列表,并使用从那里选择的AuthRoleID来确定在我的模型中分配哪个角色。
我的AuthRoles属性在我的帖子中总是空的。我的观点全部正确显示。
我在这里使用EF6,Code First。
答案 0 :(得分:1)
我还不能发表评论,但我的第一个问题是DropDownList?您正在尝试将ICollection(Of AuthRole)绑定到int类型的选定值,您将只能选择一个值,而不是列表。您需要一个不同的控件,如ListBox。但是要选择一个角色:
添加属性SelectedRole ...
Public Class UserViewModel
<Display(Name:="Roles List")> _
Public ReadOnly Property AllRoles As IEnumerable(Of SelectListItem)
Get
Dim dbContext As New AuthUserContext
Dim roleQuery = (From r In dbContext.AuthRoleSet Select r Where r.isActive = True)
Dim roles As IEnumerable(Of AuthRole) = roleQuery.ToList()
Return roles.Select(Function(o) New SelectListItem() With {.Text = o.RoleName, .Value = o.AuthRoleID})
End Get
End Property
Public Property SelectedRole As Integer //for the drop down list to bind selected value to//
Public Property UserName As String //all you need for the view model
Public Property UserId as String //hidden value in the view when you come to edit the user and post it back to the controller
End Class
在您的视图中,将下拉列表更改为:
<div class="editor-field">
@Html.DropDownListFor(Function(model) model.SelectedRole, Model.AllRoles, "-- Select Role--")
@Html.ValidationMessageFor(Function(model) model.SelectedRole)
</div>
在视图中添加此隐藏字段:
@Html.HiddenFor(Function(model) model.Id)
您的创建获取方法:
Function CreateUser() As ActionResult
Dim model As New UserViewModel
Return View(model)
End Function
您的编辑获取方法
Function EditUser(id as string) As ActionResult
//logic to test if Id is empty if not fetch user from dB as variable user
//Dim user as New AuthUser... etc
Dim model As New UserViewModel
model.SelectedRole = user.AuthRole // assuming one role as you are using DropDownList - you would need to use a different Editor to multi select roles and thus change the logic to get a list of roles
model.UserName = user.UserName
model.Id = user.Id
Return View(model)
End Function
然后您的创建帖子控制器可以设置角色
Function CreateUser(ByVal model As UserViewModel) As ActionResult
If ModelState.IsValid Then
//logic to update role from authUser.SelectedRole
Dim authuser As New AuthUser
//update properties of authuser from the model
authuser.UserName = model.UserName // etc.
//
db.AuthUserSet.Add(authuser.User)
db.SaveChanges()
Return RedirectToAction("Index")
End If
//something went wrong
Return View(model)
End Function
for Edit Post方法:
Function EditUser(ByVal model As UserViewModel) As ActionResult
If ModelState.IsValid Then
//logic to update role from authUser.SelectedRole
//Fetch user from the dB using the hidden field model.Id
//update properties of fetched user from the model
authuser.UserName = model.UserName // etc.
//
db.SaveChanges()
Return RedirectToAction("Index")
End If
//something went wrong
Return View(model)
End Function
我没有对上述内容进行测试,习惯了c#,但希望你能得到这个想法。
根据评论对ViewModel添加进行了编辑。您可以为Create和Edit创建一个单独的视图,从而分离ViewModels - 但实质上是确保ViewModel完全不知道实体的良好实践,反之亦然
答案 1 :(得分:0)
您的AuthRoles
属性需要类型为AuthRole
的对象,而您要回发Integer
列表。换句话说,您无法直接发回此集合属性。相反,您需要另一个属性,例如:
Public Property SelectedAuthRoles As List(Of Integer)
然后,使用它从数据库中查找AuthRoles
这些ID,最后将AuthRole
添加到AuthRoles
属性。
(我的VB非常缺乏,因为我几乎完全使用C#,所以如果上面的属性不太正确,我会道歉。尽管如此,它应该足以至少传达这个想法。)