我在尝试让我的 UserID 和 DeviceID(两个独立模型的一部分(显示在我的一个索引视图上时遇到了很多麻烦。我正在构建一个网站,该网站允许通过创建用户(AKA 患者(来添加可与该用户关联的设备。 我是通过种子设备列表的下拉列表来执行此操作的。 虽然下拉列表显示设备,但它不会使用所选设备更新索引。
我的目标是使设备ID和名称正确显示在我的用户(AKA患者(索引视图上。此外,当我创建和编辑用户时,我希望下拉列表更新患者(用户(索引视图上的用户信息。
患者控制器.cs
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using FaceToFace.Model;
using System.Collections;
using System.ComponentModel.DataAnnotations;
namespace FaceToFaceWebsite.Controllers
{
public class PatientController : Controller
{
private F2FData db = new F2FData();
//
// GET: /Patient/
public ActionResult Index()
{
return View(db.Users.ToList());
}
//
// GET: /Patient/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
User user = db.Users.Find(id);
if (user == null)
{
return HttpNotFound();
}
return View(user);
}
// GET: /Patient/Create
public ActionResult Create()
{
ViewBag.DeviceID = new SelectList(db.Devices, "DeviceID", "Name");
return View();
}
//
// POST: /Patient/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "UserID,CodeName,UseBriefInstructions")] User user, Device device)
{
if (ModelState.IsValid)
{
//db.Devices = user.Device.DeviceID;
db.Users.Add(user);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.DeviceID = new SelectList(db.Devices, "DeviceID", "Name", user.Device.DeviceID);
return View(user);
}
//
// GET: /Patient/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
User user = db.Users.Find(id);
if (user == null)
{
return HttpNotFound();
}
//removed user.Device.DeviceID
ViewBag.DeviceID = new SelectList(db.Devices, "DeviceID", "Name");
return View(user);
}
//
// POST: /Patient/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "UserID,CodeName,UseBriefInstructions")] User user)
{
if (ModelState.IsValid)
{
db.Entry(user).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.DeviceID = new SelectList(db.Devices, "DeviceID", "Name", user.Device.DeviceID);
return View(user);
}
//
// GET: /Patient/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
User user = db.Users.Find(id);
if (user == null)
{
return HttpNotFound();
}
return View(user);
}
//
// POST: /Patient/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
User user = db.Users.Find(id);
db.Users.Remove(user);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
}
用户.cs(型号(
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FaceToFace.Model
{
public class User
{
public int UserID { get; set; }
public string CodeName { get; set; }
public bool UseBriefInstructions { get; set; }
public Device Device { get; set; }
}
}
设备.cs(型号(
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FaceToFace.Model
{
public class Device
{
public int DeviceID { get; set; }
public string Name { get; set; }
}
}
Views/Patient/Index.cshtml
@model IEnumerable<FaceToFace.Model.User>
@{
ViewBag.Title = "Index";
}
<h2>Your Patients</h2>
Showing @Model.Count() users
<p>
@Html.ActionLink("Add New User", "Create")
</p>
<table>
<tr>
<th>
@Html.DisplayNameFor(model => model.UserID)
</th>
<th>
@Html.DisplayNameFor(model => model.CodeName)
</th>
<th>
@*@Html.DisplayNameFor(model => model.Device.Name)*@Device
</th>
<th>
@Html.DisplayNameFor(model => model.Device.DeviceID)
</th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.UserID)
</td>
<td>
@Html.DisplayFor(modelItem => item.CodeName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Device.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Device.DeviceID)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id = item.UserID }) |
@Html.ActionLink("Details", "Details", new { id = item.UserID }) |
@Html.ActionLink("Delete", "Delete", new { id = item.UserID })
</td>
</tr>
}
</table>
Views/Patient/Create.cshtml
@model FaceToFace.Model.User
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
<legend>User</legend>
<div class="editor-label">
@Html.LabelFor(model => model.CodeName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.CodeName)
@Html.ValidationMessageFor(model => model.CodeName)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Device.Name, "Device")
</div>
<div class="editor-field">
@Html.DropDownList("DeviceID", String.Empty)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.UseBriefInstructions)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.UseBriefInstructions)
@Html.ValidationMessageFor(model => model.UseBriefInstructions)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
Views/Patient/Edit.cshtml
@model FaceToFace.Model.User
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
<legend>User</legend>
@Html.HiddenFor(model => model.UserID)
<div class="editor-label">
@Html.LabelFor(model => model.CodeName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.CodeName)
@Html.ValidationMessageFor(model => model.CodeName)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Device.Name, "Device")
</div>
<div class="editor-field">
@Html.DropDownList("DeviceID", String.Empty)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.UseBriefInstructions)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.UseBriefInstructions)
@Html.ValidationMessageFor(model => model.UseBriefInstructions)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
感谢您抽出宝贵时间阅读本文,我是 MVC 的新手,所以我感谢您能提供的任何帮助。
更新
在Jason的帮助下,我开始构建视图模型。 我在视图模型中使用的模型位于我与解决方案一起加入的另一个项目中。
用户设备视图模型.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.WebPages.Html;
using FaceToFace.Model;
namespace FaceToFaceWebsite.Models
{
public class UserDeviceViewModel
{
public UserDeviceViewModel()
{
User = new User();
Users = new List<User>();
Devices = new List<SelectListItem>();
}
public User UseBriefInstructions { get; set; }
public Device Device { get; set; }
public User User { get; set; }
public User CodeName { get; set; }
public IList<SelectListItem> Devices { get; set; }
public IList<User> Users { get; set; }
}
}
患者控制器.cs
namespace FaceToFaceWebsite.Controllers
{
public class PatientController : Controller
{
private F2FData db = new F2FData();
//
// GET: /Patient/
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(UserDeviceViewModel viewModelDevice)
{
var viewModel = new UserDeviceViewModel();
viewModel.Devices.Add(new SelectListItem() { Text = "MAU110-10", Value = "1" });
viewModel.Devices.Add(new SelectListItem() { Text = "MAU110-100", Value = "2" });
viewModel.Devices.Add(new SelectListItem() { Text = "MAU110-101", Value = "3" });
viewModel.Devices.Add(new SelectListItem() { Text = "MAU110-102", Value = "4" });
viewModel.Devices.Add(new SelectListItem() { Text = "MAU110-103", Value = "5" });
viewModel.Users.AddRange(db.Users.ToList());
return View(viewModel);
}
Views/Patient/Create.cshtml
@model FaceToFace.Model.User
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
<legend>User</legend>
<div class="editor-label">
@Html.LabelFor(model => model.CodeName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.CodeName)
@Html.ValidationMessageFor(model => model.CodeName)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Device.Name, "Device")
</div>
<div class="editor-field">
@Html.DropDownListFor(model => model.User.Device.DeviceID, Model.Devices)
<input type="submit" value="Save" />
</div>
<div class="editor-label">
@Html.LabelFor(model => model.UseBriefInstructions)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.UseBriefInstructions)
@Html.ValidationMessageFor(model => model.UseBriefInstructions)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
我将省略编辑以避免进一步的垃圾邮件,但是我现在收到多个错误。 我相信我已经修复了一些。对于下拉菜单,我收到此错误:
'System.Web.Mvc.HtmlHelper' 不包含 'DropDownListFor' 的定义,最好的扩展方法重载 'System.Web.Mvc.Html.SelectExtensions.DropDownListFor(System.Web.Mvc.HtmlHelper, System.Linq.Expressions.Expression>, System.Collections.Generic.IEnumerable(' 有一些无效的参数
对于患者控制器中的viewModel.Devices.Add
,我得到:
'System.Collections.Generic.ICollection.Add(System.Web.WebPages.Html.SelectListItem('的最佳重载方法匹配有一些无效参数
以及:
参数 1:无法从"System.Web.Mvc.SelectListItem"转换为"System.Web.WebPages.Html.SelectListItem">
最后,在下面,我收到来自AddRange的错误:
"System.Collections.Generic.IList"不包含"AddRange">的定义,并且找不到接受类型为"System.Collections.Generic.IList"的第一个参数的扩展方法"AddRange"(您是否缺少使用指令或程序集引用?(
任何帮助使其工作将不胜感激。再次,对不起垃圾邮件!
看起来您没有为视图提供可供选择的设备选择。
不过,总的来说,我建议您在这里使用视图模型方法。
用户
public class User
{
public User()
{
Device = new Device();
}
public int UserID { get; set; }
public string CodeName { get; set; }
public bool UseBriefInstructions { get; set; }
public Device Device { get; set; }
}
装置
public class Device
{
public int DeviceID { get; set; }
public string Name { get; set; }
}
然后有一个视图模型类:
public class CreatePatientViewModel
{
public CreatePatientViewModel()
{
User = new User();
Devices = new List<SelectListItem>();
}
public User User { get; set; }
public IList<SelectListItem> Devices { get; set; }
}
在控制器中,您将像这样使用视图模式 -
public ActionResult Index()
{
var viewModel = new CreatePatientViewModel();
viewModel.Devices.Add(new SelectListItem() { Text = "Device 1", Value = "1" });
viewModel.Devices.Add(new SelectListItem() { Text = "Device 2", Value = "2" });
return View(viewModel);
}
然后,可以使用 .Devices
属性填充视图中的下拉列表,例如
@model StackOverflowMvc.Controllers.CreatePatientViewModel
@using (Html.BeginForm())
{
@Html.DropDownListFor(model => model.User.Device.DeviceID, Model.Devices)
<input type="submit" value="Save" />
}
提交数据时:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(CreatePatientViewModel viewModel)
{
// Do whatever you want with the data.
// viewModel.User.Device.DeviceId will be given the value selected from the dropdown.
return View(viewModel);
}
不要为[Bind(Include = "UserID,Code....
的东西而烦恼,它只会让事情变得混乱。该CreatePatientViewModel
可用于从提交的表单中获取值,例如
@Html.InputFor(model => model.User.Code)
在视图中,如果上面的文本框输入了一个值,则在进行POST
时,CreatePatientViewModel.User.Code
将传递该值,因为它与所使用的值model.User.Code
匹配。
希望以上对您有所帮助。
编辑:
在控制器的Index
操作方法中,可以执行以下操作:
public ActionResult Index()
{
var viewModel = new CreatePatientViewModel();
viewModel.Devices.Add(new SelectListItem() { Text = "Device 1", Value = "1" });
viewModel.Devices.Add(new SelectListItem() { Text = "Device 2", Value = "2" });
viewModel.Users.AddRange(db.Users.ToList());
return View(viewModel);
}
更改CreatePatientViewModel
以包含Users
属性:
public class CreatePatientViewModel
{
public CreatePatientViewModel()
{
User = new User();
Users = new List<User>();
Devices = new List<SelectListItem>();
}
public User User { get; set; }
public IList<SelectListItem> Devices { get; set; }
public IList<User> Users { get; set; }
}
请注意,我假设您的数据库。用户列表是User
对象的列表,如果不是,则只需将其更改为应有的任何类型即可。