英文:
Why is binding to a ViewModel Not Working here?
问题
我有一个ViewModel,包含两个模型 - UserSystemPermissions
和 SystemModel
。我想从视图中传递两个数据,并将其绑定到上述的ViewModel。
//UserSystemPermissionsViewModel
using NuGet.ProjectModel;
using SPLWeb.Models;
using SPLWeb.ViewModels;
using SPLWeb.Models.DB;
namespace SPLWeb.ViewModels
{
public class UserSystemPermissionsViewModel
{
public UserSystemPermission? UserSystemPermission { get; set; }
public SystemModel? SystemModel { get; set; }
}
}
两个模型:
// SystemModel
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace SPLWeb.Models.DB
{
public partial class SystemModel
{
[Key]
public int SystemId { get; set; }
public string? SystemName { get; set; }
public string? Description { get; set; }
public bool DisabledBit { get; set; }
public string? ChangedBy { get; set; }
public DateTime? ChangedDate { get; set; }
public virtual ICollection<FacilitySystem> FacilitySystems { get; set; } = new List<FacilitySystem>();
public virtual ICollection<SystemJob> SystemJobs { get; set; } = new List<SystemJob>();
public virtual ICollection<SystemUser>? SystemUsers { get; set; }
public virtual ICollection<SystemPermission> SystemPermissions { get; set; } = new List<SystemPermission>();
}
}
// UserSystemPermission
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace SPLWeb.Models.DB
{
public partial class UserSystemPermission
{
[Key]
public int UserSystemPermissionId { get; set; }
public int? UserId { get; set; }
public int? SystemPermissionId { get; set; }
public string? Notes { get; set; }
public bool Active { get; set; }
public string? AddedByUser { get; set; }
public string? DeactivatedBy { get; set; }
public string? ReactivatedBy { get; set; }
public DateTime? LastModifiedDate { get; set; }
public virtual SystemPermission? SystemPermission { get; set; }
public virtual User? User { get; set; }
}
}
传递数据的视图:
@model SPLWeb.ViewModels.UserSystemPermissionsViewModel
@{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>UserSystemPermission</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="PresentSystemPermissionSelect">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label for="UserSystemPermission.UserId" class="control-label"></label>
<select for="UserSystemPermission.UserId" class ="form-control" required="required" asp-items="ViewBag.UserList"></select>
</div>
<div class="form-group">
<label for="SystemModel.SystemId" class="control-label"></label>
<select for="SystemModel.SystemId" class ="form-control" required="required" asp-items="ViewBag.SystemList"></select>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
最后,在控制器中尝试传递数据:
public async Task<IActionResult> PresentSystemPermissionSelect([Bind("UserSystemPermission.UserId", "SystemModel.SystemId")] UserSystemPermissionsViewModel userSystemPermissionsViewModel)
{
// 传递选定系统的权限列表到下一个屏幕,允许用户选择权限
var userSystemPermissionContext = _context.UserSystemPermissions
.Include(u => u.SystemPermission)
.Include(u => u.SystemPermission.SystemModel)
.Include(u => u.User);
// 获取所选系统的权限列表
var systemPermisionList = (from s in _context.SystemPermissions
orderby s.Description
where s.SystemId == userSystemPermissionsViewModel.SystemModel.SystemId
select s).ToList();
ViewData["UserList"] = new SelectList(_context.Users.OrderBy(s => s.NameLast).OrderBy(s => s.NameFirst), "UserId", "FullName", userSystemPermissionsViewModel.UserSystemPermission.UserId);
ViewData["SystemList"] = new SelectList(_context.SystemModels.OrderBy(e => e.SystemName), "SystemId", "SystemName", userSystemPermissionsViewModel.SystemModel.SystemId);
ViewData["SystemPermissionList"] = new SelectList(_context.SystemPermissions.OrderBy(e => e.Description), "SystemPermissionId", "Description");
return View("SystemPermissionSelect", systemPermisionList);
}
英文:
I have a ViewModel with two Models - UserSystemPermissions
and SystemModel
I want to pass two pieces of data from a view and bind it to the afforementioned ViewModel.
UserSystemPermissions.SystemID
SystemModel.SystemID
I can see the data coming over with Edge Network Tools in a browser window but the data is not binding to the ViewModel.
Here is the ViewModel, two models, controller, and view in question.
//UserSystemPermissionsViewModel
using NuGet.ProjectModel;
using SPLWeb.Models;
using SPLWeb.ViewModels;
using SPLWeb.Models.DB;
namespace SPLWeb.ViewModels
{
public class UserSystemPermissionsViewModel
{
public UserSystemPermission? UserSystemPermission { get; set; }
public SystemModel? SystemModel { get; set; }
}
}
...and the two models
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace SPLWeb.Models.DB;
public partial class SystemModel
{
[Key]
public int SystemId { get; set; }
public string? SystemName { get; set; }
public string? Description { get; set; }
public bool DisabledBit { get; set; }
public string? ChangedBy { get; set; }
public DateTime? ChangedDate { get; set; }
public virtual ICollection<FacilitySystem> FacilitySystems { get; set; } = new List<FacilitySystem>();
//public virtual ICollection<JobSystemPermission> JobSystemPermissions { get; set; } = new List<JobSystemPermission>();
public virtual ICollection<SystemJob> SystemJobs { get; set; } = new List<SystemJob>();
//public virtual ICollection<User> Users { get; set; } = new List<User>();
public virtual ICollection<SystemUser>? SystemUsers { get; set; }
//public virtual UserSystemPermission UserSystemPermission { get; set; }
public virtual ICollection<SystemPermission> SystemPermissions { get; set; } = new List<SystemPermission>();
//public virtual ICollection<UserSystemPermission> UserSystemPermissions { get; set; } = new List<UserSystemPermission>();
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace SPLWeb.Models.DB;
public partial class UserSystemPermission
{
[Key]
public int UserSystemPermissionId { get; set; }
public int? UserId { get; set; }
public int? SystemPermissionId { get; set; }
public string? Notes { get; set; }
public bool Active { get; set; }
public string? AddedByUser { get; set; }
public string? DeactivatedBy { get; set; }
public string? ReactivatedBy { get; set; }
public DateTime? LastModifiedDate { get; set; }
public virtual SystemPermission? SystemPermission { get; set; }
public virtual User? User { get; set; }
// public virtual SystemModel? SystemModel { get; set; }
//public virtual SystemUser? SystemUser { get; set; }
}
View that is passing the data
@model SPLWeb.ViewModels.UserSystemPermissionsViewModel
@{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>UserSystemPermission</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="PresentSystemPermissionSelect" >
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label for="UserSystemPermission.UserId" class="control-label"></label>
<select for="UserSystemPermission.UserId" class ="form-control" required="required" asp-items="ViewBag.UserList"></select>
@*<input asp-for="User.FullName" disabled class="form-control" />*@
</div>
<div class="form-group">
<label for="SystemModel.SystemId" class="control-label"></label>
<select for="SystemModel.SystemId" class ="form-control" required="required" asp-items="ViewBag.SystemList"></select>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
And, finally, the controll task that I am passing the data too (or trying to
public async Task<IActionResult> PresentSystemPermissionSelect([Bind("UserSystemPermission.UserId", "SystemModel.SystemId")] UserSystemPermissionsViewModel userSystemPermissionsViewModel)
{
// pass a list of permissions for the selected systems to the next screen which will allow
// the user to select a permission
var userSystemPermissionContext = _context.UserSystemPermissions
.Include(u => u.SystemPermission)
.Include(u => u.SystemPermission.SystemModel)
.Include(u => u.User);
// Get a list of permissions for the chosen system
var systemPermisionList = (from s in _context.SystemPermissions
orderby s.Description
where s.SystemId == userSystemPermissionsViewModel.SystemModel.SystemId
select s).ToList();
ViewData["UserList"] = new SelectList(_context.Users.OrderBy(s => s.NameLast).OrderBy(s => s.NameFirst), "UserId", "FullName", userSystemPermissionsViewModel.UserSystemPermission.UserId);
ViewData["SystemList"] = new SelectList(_context.SystemModels.OrderBy(e => e.SystemName), "SystemId", "SystemName", userSystemPermissionsViewModel.SystemModel.SystemId);
ViewData["SystemPermissionList"] = new SelectList(_context.SystemPermissions.OrderBy(e => e.Description), "SystemPermissionId", "Description");
return View("SystemPermissionSelect", systemPermisionList);
}
I have tried "newing up" the ViewModel before using it, in which case, I have a ViewModel with two models but no data. If I don't create a ViewModel first I simply have two NULL models inside the ViewModel after the binding in the ActionResult header.
I have scoured the Internet - including SO and cannot seem to get this working.
I considered not using the ASP tag helpers and just passing in two pieces of data to the controller but I prefer to manage the lists with <select asp-for ...>
tag because I've had much better results than just @Html.DropDown
...
As mentioned earlier, I can see the data coming across the network in Edge Network Tools but the data is simply not binding.
答案1
得分: 1
如果您想将两个数据传递给控制器并使用<select asp-for ...>
标记,
尝试删除[Bind("UserSystemPermission.UserId", "SystemModel.SystemId")]
并按以下方式进行一些更改:
[HttpPost]
public async Task<IActionResult> PresentSystemPermissionSelect(int? UserId, int? SystemId)
{
...//进行您的操作
return View();
}
在Create.cshtml中,使用name
属性进行绑定:
<select name="UserId" class="form-control" required="required" asp-items="ViewBag.UserList"></select>
<select name="SystemId" class="form-control" required="required" asp-items="ViewBag.SystemList"></select>
英文:
> I considered not using the ASP tag helpers and just passing in two
> pieces of data to the controller but I prefer to manage the lists with
> <select asp-for ...> tag
If you want to pass two pieces of data to the controller and with <select asp-for ...> tag
Try to remove [Bind("UserSystemPermission.UserId", "SystemModel.SystemId")]
and make some change as below :
[HttpPost]
public async Task<IActionResult> PresentSystemPermissionSelect(int? UserId, int? SystemId)
{
...//do your staff
return View();
}
In Create.cshtml , use name
attribute to bind:
<select name="UserId" class="form-control" required="required" asp-items="ViewBag.UserList"></select>
<select name="SystemId" class="form-control" required="required" asp-items="ViewBag.SystemList"></select>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论