需要 ASP.NET MVC 创建视图页面才能将用户提供的信息更改为外键值



我正在努力创建一个访问 SQL 管理服务器中的表的网站。用户需要能够使用我的网站查看、编辑、删除和创建新条目。正在使用的表称为 DeviceUnderTest,它包含以下列:DeviceUnderTest (pk)、DeviceUnderTest (nk)、Notes (nk)、FaultApplication (fk)、Firmware (fk)、Hardware (fk)、Power (fk)、Location (fk)、PreEventTime(nk)、HandleRate (nk)。到目前为止,我已经创建了连接到主 DeviceUnderTest 表以及外键列引用的其他表的模型。我已经创建了控制器,以及索引,详细信息,删除和创建视图页面。我的索引视图是一个表,我想出了如何从它们引用的表中将所有外键值替换为它们对应的表。我无法弄清楚的一件事是创建页面。用户将以 fk 列引用的值的形式输入信息,而不是外键值本身。我不知道如何将用户输入更改回正确的外键值,以便可以将该条目正确添加到sql服务器以及我的站点中的表中。如果有人有任何建议,我们将不胜感激。

控制器代码:

// GET: Circuit/Create
public ActionResult Create()
{
return View();
}
// POST: Circuit/Create
[HttpPost]
public ActionResult Create(DeviceUnderTest device)
{
try
{

dbModel.DeviceUnderTests.Add(device);
dbModel.SaveChanges();
// TODO: Add insert logic here
return RedirectToAction("Index");
}
catch
{
return View();
}
}

创建视图代码:

@model Template_Website.Models.DeviceUnderTest
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm()) 
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>DeviceUnderTest</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.pkDeviceUnderTest, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.pkDeviceUnderTest, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.pkDeviceUnderTest, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.nkDeviceUnderTest, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.nkDeviceUnderTest, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.nkDeviceUnderTest, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.nkNotes, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.nkNotes, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.nkNotes, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.FaultApplication.nkFaultApplication, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.FaultApplication.nkFaultApplication, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.FaultApplication.nkFaultApplication, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Firmware.nkFirmware, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Firmware.nkFirmware, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Firmware.nkFirmware, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Hardware.nkHardware, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Hardware.nkHardware, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Hardware.nkHardware, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.fkPower, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.fkPower, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.fkPower, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Location.nkLocation, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Location.nkLocation, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Location, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.nkPreEventTime, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.nkPreEventTime, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.nkPreEventTime, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.nkHandleRating, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.nkHandleRating, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.nkHandleRating, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<<button type="submit" class="btn btn-default " value="Create" onclick="return confirm('Are you sure?')">Create</button>
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>

索引视图代码:

@model IEnumerable<Template_Website.Models.DeviceUnderTest>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2> 


<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
</th>
<th>
</th>
<th>
</th>
<th>
</th>
<th>
@Html.DisplayNameFor(model => model.pkDeviceUnderTest)
</th>
<th>
@Html.DisplayNameFor(model => model.nkDeviceUnderTest)
</th>
<th>
@Html.DisplayNameFor(model => model.nkNotes)
</th>
<th>
@Html.DisplayNameFor(model => model.FaultApplication.nkFaultApplication)
</th>
<th>
@Html.DisplayNameFor(model => model.Firmware.nkFirmware)
</th>
<th>
@Html.DisplayNameFor(model => model.Hardware.nkHardware)
</th>
<th>
@Html.DisplayNameFor(model => model.fkPower)
</th>
<th>
@Html.DisplayNameFor(model => model.Location.nkLocation)
</th>
<th>
@Html.DisplayNameFor(model => model.nkPreEventTime)
</th>
<th>
@Html.DisplayNameFor(model => model.nkHandleRating)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.CheckBoxFor(modelItem => item.Selected)
</td>
<td>
<input type="button" value="Edit" class="btn btn-default" onclick="@("window.location.href='" + @Url.Action("Edit", "Circuit", new { id = item.pkDeviceUnderTest } ) + "'");" />
</td>
<td>
<input type="button" value="Details" class="btn btn-default" onclick="@("window.location.href='" + @Url.Action("Details", "Circuit", new { id = item.pkDeviceUnderTest }) + "'");" />
</td>
<td>
<input type="button" value="Delete" class="btn btn-danger" onclick="@("window.location.href='" + @Url.Action("Delete", "Circuit", new { id = item.pkDeviceUnderTest }) + "'");" />
</td>
<td>
@Html.DisplayFor(modelItem => item.pkDeviceUnderTest)
</td>
<td>
@Html.DisplayFor(modelItem => item.nkDeviceUnderTest)
</td>
<td>
@Html.DisplayFor(modelItem => item.nkNotes)
</td>
<td>
@Html.DisplayFor(modelItem => item.FaultApplication.nkFaultApplication)
</td>
<td>
@Html.DisplayFor(modelItem => item.Firmware.nkFirmware)
</td>
<td>
@Html.DisplayFor(modelItem => item.Hardware.nkHardware)
</td>
<td>
@Html.DisplayFor(modelItem => item.fkPower)
</td>
<td>
@Html.DisplayFor(modelItem => item.Location.nkLocation)
</td>
<td>
@Html.DisplayFor(modelItem => item.nkPreEventTime)
</td>
<td>
@Html.DisplayFor(modelItem => item.nkHandleRating)
</td>
</tr>
}
</table>

设备测试型号代码:


namespace Template_Website.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
public partial class DeviceUnderTest
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public DeviceUnderTest()
{
this.TestRecords = new HashSet<TestRecord>();
}
public bool Selected { get; set; }
[Required]    
public int pkDeviceUnderTest { get; set; }
[Required]
public string nkDeviceUnderTest { get; set; }
[Required]
public string nkNotes { get; set; }
public Nullable<int> fkFaultApplication { get; set; }
public Nullable<int> fkFirmware { get; set; }
public Nullable<int> fkHardware { get; set; }
public Nullable<int> fkPower { get; set; }
public Nullable<int> fkLocation { get; set; }
public Nullable<int> nkPreEventTime { get; set; }
public Nullable<int> nkHandleRating { get; set; }
public virtual FaultApplication FaultApplication { get; set; }
public virtual Firmware Firmware { get; set; }
public virtual Hardware Hardware { get; set; }
public virtual Location Location { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<TestRecord> TestRecords { get; set; }
}
public class DeviceUnderTestModel
{
public List<DeviceUnderTest> device { get; set; }
}
}

硬件型号代码:


namespace Template_Website.Models
{
using System;
using System.Collections.Generic;
public partial class Hardware
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Hardware()
{
this.DeviceUnderTests = new HashSet<DeviceUnderTest>();
}
public int pkHardware { get; set; }
public string nkHardware { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<DeviceUnderTest> DeviceUnderTests { get; set; }
}
}

用户将以 fk 列引用的值的形式输入信息,而不是外键值本身。

为什么要避免使用外键值? 我注意到您正在使用EditorFor但是您不能简单地使用DropdownFor甚至JavaScript驱动的自动完成小部件吗?这样,您的用户将输入所需的文本,但值将在后台映射。

有关如何使用DropdownFor的示例,请参阅 MSDN 文档:https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions/working-with-the-dropdownlist-box-and-jquery/examining-how-aspnet-mvc-scaffolds-the-dropdownlist-helper

对于使用自动完成的示例,这里有一个很好的答案,它使用 jQuery UI:MVC5 中的自动完成下拉列表?

使用第一个示例进行DropdownFor并将其应用于代码,其中一个模型属性将继续看起来相同:

public Nullable<int> fkFaultApplication { get; set; }

同时,您还创建了一个 ViewBag 项目以包含映射文本和值的SelectList

ViewBag.FaultApplicationId = new SelectList(db.FaultApplications, "FaultAppId", "Name");

最后,您可以在视图中使用这些属性,如下所示:

@Html.DropDownList("FaultApplicationId", String.Empty)

请注意,第二个参数String.Empty"是未选择任何项目时要显示的文本"。

就像user1477388说的那样,您可以为每个项目使用下拉列表。这样,视图将显示文本,但发回的值是 id。

例如使用硬件。 我使用的是视图模型,因此我们不会向视图显示数据库模型。 VM 在特定视图中具有所需的属性。 在这种情况下,我们有被测设备的东西,一个选择列表和一个硬件ID。

public class DeviceUnderTestViewModel
{    
public int pkDeviceUnderTest { get; set; }
[Required]
public string nkDeviceUnderTest { get; set; }
[Required]
public string nkNotes { get; set; }
public int HardwareId { get; set; } //pkHardware
public IEnumerable<SelectListItem> HardwareSelectList { get; set; } //dropdown of Hardware
}

在控制器中,填充选择列表并附加到视图模型:

public ActionResult Index()
{
DeviceUnderTestViewModel vm = new DeviceUnderTestViewModel();
vm.HardwareSelectList = db.Hardware.ToList().Select(d => new SelectListItem()
{
Text = d.nkHardware,
Value = d.pkHardware.ToString()
});
// populate all the other dropdowns
return View();
}

在视图中,我们呈现选择列表:

<div class="form-group">
@Html.LabelFor(model => model.HardwareId)
@Html.DropDownListFor(model => model.HardwareIdId, Model.HardwareSelectList, "Select Hardware...", new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.HardwareIdId, "", new { @class = "text-danger" })
</div>

DropDownListFor 首先获取要设置的值,在这里我们将硬件 ID 设置为将保存到 DeviceUnderTest 作为 pkHardware,然后我们有下拉列表的硬项填充列表,第三个是可选的字符串占位符,最后我添加一个用于格式化的引导类。

然后将模型返回到控制器并保存:

public ActionResult SaveDevice(DeviceUnderTestViewModel model)
{
using (var db = new dbContext())
{
DeviceUnderTest device = new DeviceUnderTest()
{
pkHardware = model.HardwareId,
// continue with other items
};
db.Entry<device>.State = EntiyState.Added;
db.SaveChanges();
}
return View();
}

相关内容

最新更新