使用下拉列表向多个表中添加新数据
本文关键字:新数据 添加 数据 下拉列表 | 更新日期: 2023-09-27 18:04:22
我想使用MVC4实现允许用户向数据库添加新项目的功能。
我已经成功地将项目添加到单个表中,但是现在我需要显示来自多个表的数据,然后将添加/选择的数据填充到这些表中。
我有这3张表
- ID
ThreatHasSecurityEvent
- ThreatID
- SecurityEventID
SecrutiyEvents
- ID
ViewModel
public class ThreatWithSecurityEvents
{
public Threat Threat { get; set; }
public SecurityEvent SecurityEvent { get; set; }
public List<int> SecurityEventIds { get; set; }
public ThreatWithSecurityEvents()
{
SecurityEventIds = new List<int>();
}
}
<<p> 得到控制器/strong> [HttpGet]
public ActionResult AddNewThreat()
{
ThreatWithSecurityEvents ViewModel = new ThreatWithSecurityEvents();
var SecurityEvents = _DBContext.SecurityEvents.Select(x => new SelectListItem()
{
Text = x.Description,
Value = x.ID.ToString()
});
ViewBag.SecurityEventDropdown = SecurityEvents;
return View(ViewModel);
}
<<p> 视图/strong> @model RiskAssesmentApplication.Models.ThreatWithSecurityEvents
@{
ViewBag.Title = "AddNewThreat";
//Layout = "~/Views/Shared/MasterLayout.cshtml";
}
<div style="font-family: Calibri">
<h2>AddNewThreat</h2>
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
<legend>Threat</legend>
@using (Html.BeginForm("Add New Threat", "Threats"))
{
Html.HiddenFor(model => model.SecurityEventIds);
<div class="editor-label">
@Html.LabelFor(model => @Model.Threat.Description, "Threat Description")
</div>
<div class="editor-field">
@Html.EditorFor(model => @Model.Threat.Description)
@Html.ValidationMessageFor(model => @Model.Threat.Description)
</div>
<div class="editor-label">
@Html.LabelFor(model => @Model.SecurityEvent.Description, "Associated Security Event")
</div>
<div class="editor-field">
@Html.DropDownListFor(x => x.SecurityEventIds, ViewBag.SecurityEventDropdown as IEnumerable<SelectListItem>)
</div>
<p>
<input type="submit" value="Add New" />
</p>
}
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
</div>
我不确定如何在存储库中实现Post Action方法和保存方法。之前我可以注入一个新的威胁对象并将其发送到编辑视图,如下所示:
上一个获取方法- AddNewThreat
[HttpGet]
public ActionResult AddNewThreat()
{
return View("EditThreat", new Threat());
}
,然后我将使用EditThreat Action方法来返回
上一页动作- AddNewThreat
[HttpPost]
public ActionResult EditThreat(Threat Threat)
{
if (ModelState.IsValid)
{
repository.SaveThreat(Threat);
TempData["message"] = string.Format("{0} new description has been saved", Threat.Description);
return RedirectToAction("GetThreat", new { ThreatID = Threat.ID });
}
else
{
// something is incorrect!
return View(Threat);
}
}
以前的保存方法- SaveThreat From Repository
public void SaveThreat(Threat Threat)
{
if (Threat.ID == 0)
{
_context.Threats.Add(Threat);
}
else
{
Threat dbEntry = _context.Threats.Find(Threat.ID);
if (dbEntry != null)
{
dbEntry.Description = Threat.Description;
}
}
_context.SaveChanges();
}
到目前为止我就知道这么多。
我希望用户能够输入一个新的威胁描述,然后从一个下拉列表中选择一个安全事件或多个事件,这些事件将与新的威胁相关联。
我意识到我将不得不更改控制器中的post - back操作方法和存储库中的Save方法,但我无法弄清楚如何将新的威胁描述和现有的安全事件保存回数据库。我已经搜索过了,但还没有找到/理解任何东西。
任何建议/帮助都会很好。
谢谢
你的视图模型应该是
public class NewThreatVM
{
public string Description { get; set; } // add validation attributes as required
public List<int> SelectedSecurityEvents { get; set; }
public SelectList SecurityEventList { get; set; } // or IEnumerable<SelectListItem>
}
旁注:Threat.ID
属性在创建视图中是不需要的,但是如果你想用它来编辑现有的Threat
,添加属性int? ID
并在POST方法中使用if (model.ID.HasValue)
来确定它是新的还是现有的Threat
和简化视图
@model yourAssembly.NewThreatVM
@Html.BeginForm())
{
@Html.TextBoxFor(m => m.Description)
@Html.ListBoxFor(m => m.SelectedSecurityEvents, Model.SecurityEventList)
<input type="Submit" value="Create" />
}
旁注:您的视图不应该包含安全事件ID的隐藏输入(您不能将输入绑定到复杂的对象或集合)
则控制器
public ActionResult Create()
{
NewThreatVM model = new NewThreatVM model();
ConfigureViewModel(model);
return View(model);
}
[HttpPost]
public ActionResult Create(NewThreatVM model)
{
if (!ModelState.IsValid)
{
ConfigureViewModel(model);
return View(model);
}
// Initialize new data model and map properties from view model
Threat threat = new Threat() { Description = model.Description };
// Save it (which will set its ID property)
_context.Threats.Add(Threat);
_context.SaveChanges();
// Save each selected security event
foreach (int selectedEvent in model.SelectedSecurityEvents)
{
ThreatHasSecurityEvent securityEvent = new ThreatHasSecurityEvent()
{
ThreatID = threat.ID,
SecurityEventID = selectedEvent
};
_context.ThreatHasSecurityEvents.Add(securityEvent);
}
_context.SaveChanges();
return RedirectToAction("GetThreat", new { ThreatID = threat.ID });
}
private void ConfigureViewModel(NewThreatVM model)
{
var securityEvents = _context.SecurityEvents;
model.SecurityEventList = new SelectList(securityEvents, "ID", "Description");
}
我认为最简单的方法是将表单"划分"为独立的步骤。
你有2个实体:Threats, securityyeventid
威胁有一个securityeevents集合
- 创建表单添加/编辑威胁(url: Threats/add | Threats/edit/ThreatId)
- 创建一个表单来添加/删除现有威胁的事件(url: Threats/AddEvent/ThreatIdHere
使用自定义ViewModels代替原来的类来发送数据给控制器。例子:
public class AddThreatViewModel
{
public string Description { get; set; }
//since it's a add view model, we dont need a ThreatId here
}
[HttpPost]
public ActionResult AddThreat(AddThreatViewModel model)
{
//convert the view model to Threat, add to database
}
public class AddThreatEvent
{
public int ThreatId { get; set; }
public int SecrutiyEventId { get; set; }
}
[HttpPost]
public ActionResult AddThreatEvent(AddThreatEventmodel)
{
//add threat event into existing threat
}