I am using Entity Framework to create my models and I have some fields which are foreign keys but also nullable. For instance, the Status of a Device may not be known, so if that is the case, I have it set to NULL. If the Device does have a status, then the value is the Dev_Status_ID which references the Device_Status table so the Dev_Status_Name can be displayed on the website.
I have been testing to ensure that empty fields during create and edit are being handled properly, but they are not. When I leave the Device Status drop down list on the default String.Empty value, the website highlights the Device Status drop down list when I click the Submit button.
Device Create View:
@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>
Device Model:
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*@*@
}
}
Status Model:
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; }
}
}
Device Controller:
// 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);
}
I'm new to MVC, so I feel I must be missing something obvious, but all my searches haven't helped. My field is set to Nullable, I don't have the field Required, and when I try to do an Insert on the database manually, it doesn't complain about a NULL dev_status_id. Am I trying to do something that isn't allowed?