【发布时间】:2018-03-23 23:42:17
【问题描述】:
我正在使用实体框架来创建我的模型,并且我有一些字段是外键但也可以为空。例如,设备的状态可能未知,所以如果是这种情况,我将其设置为 NULL。如果设备确实有状态,则值为 Dev_Status_ID,它引用 Device_Status 表,因此 Dev_Status_Name 可以显示在网站上。
我一直在测试以确保正确处理创建和编辑期间的空字段,但事实并非如此。当我将设备状态下拉列表保留在默认 String.Empty 值上时,当我单击提交按钮时,网站会突出显示设备状态下拉列表。
设备创建视图:
@model ITInventory.Models.Device
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Device</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@* Asset Tag *@
<div class="form-group">
@Html.LabelFor(model => model.dev_asset_tag, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.dev_asset_tag, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.dev_asset_tag, "", new { @class = "text-danger" })
</div>
</div>
@*......Leaving out a bunch of other fields for readability*@
@*Status*@
<div class="form-group">
@Html.LabelFor(model => model.Device_Status.dev_status_name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(m => m.Device_Status.dev_status_id, (SelectList)ViewBag.dev_status_id, String.Empty, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.dev_status_id, "", new { @class = "text-danger" })
</div>
</div>
@*.......Leaving out a bunch of other fields for readability*@
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
<input type="reset" value="Cancel" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
设备型号:
namespace ITInventory.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
public partial class Device
{
[DisplayName("Device ID")]
public int dev_id { get; set; }
[DisplayName("Asset Tag")]
public string dev_asset_tag { get; set; }
@*.......Leaving out a bunch of other fields for readability*@
[DisplayName("Status ID")]
public Nullable<int> dev_status_id { get; set; }
@*.......Leaving out a bunch of other fields for readability*@
public virtual Device_Status Device_Status { get; set; }
@*.......Leaving out the other public virtual bits for readability*@*@
}
}
状态模型:
namespace ITInventory.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
public partial class Device_Status
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Device_Status()
{
this.Devices = new HashSet<Device>();
}
[DisplayName("Status ID")]
public int dev_status_id { get; set; }
[DisplayName("Status")]
public string dev_status_name { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Device> Devices { get; set; }
}
}
设备控制器:
// GET: Devices/Create
public ActionResult Create()
{
@*.......Leaving out a bunch of other fields for readability*@
ViewBag.dev_status_id = new SelectList(db.Device_Status.OrderBy(x => x.dev_status_name),
"dev_status_id", "dev_status_name");
@*.......Leaving out a bunch of other fields for readability*@
return View();
}
// POST: Devices/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Device device)
{
if (ModelState.IsValid)
{
db.Devices.Add(device);
db.SaveChanges();
return RedirectToAction("Index");
}
@*.......Leaving out a bunch of other fields for readability*@
ViewBag.dev_status_id = new SelectList(db.Device_Status, "dev_status_id", "dev_status_name", null);
@*.......Leaving out a bunch of other fields for readability*@
return View(device);
}
我是 MVC 的新手,所以我觉得我一定遗漏了一些明显的东西,但是我的所有搜索都没有帮助。我的字段设置为 Nullable,我没有字段Required,当我尝试手动对数据库执行插入操作时,它不会抱怨 NULL dev_status_id。我是否试图做一些不允许的事情?
【问题讨论】:
-
首先,您有一个
Device_Status.dev_status_name属性的标签(并且没有关联的控件,因此它不是标签)然后您将下拉列表绑定到属性Device_Status.dev_status_id,,但对dev_status_id进行了关联验证(他们是不一样的)。删除所有这些糟糕的代码。您正在编辑数据,因此请始终使用视图模型 - What is ViewModel in MVC?。您的视图模型将包含属性int? SelectedStatus和IEnumerable<SelectListItem> StatusList。 -
然后参考this Q/A了解如何正确编码
-
并且突出显示下拉列表的原因是您绑定到
int(您的Device_Status.dev_status_id属性)和int必须有一个值 - 它不能是null这是第一个选项的价值。但是您永远不会看到相关的错误消息,因为您为完全不同的属性创建了验证消息。
标签: c# asp.net-mvc validation