Question

I using MVC 5.1 and EF 6.1 database first model. I don't like the view that was created by the scaffolding as it uses all the database columns. On the create view I just want the user to input the required fields all other data can be added through editing the details view. I have created the a view model to use other than the .edmx generated one. The view works as expected but when the create action button is click the post operation dies with a "[NullReferenceException: Object reference not set to an instance of an object.]

Here is my view model

     public class DesktopCreateViewModel 
{

    [Required]
    [Display(Name = "Serial Number")]
    [StringLength(30)]
    public string SERIAL_NUMBER { get; set; }

    public int Model_DesktopId { get; set; }
    public int DeviceType_DesktopId { get; set; }

    [Required]
    [StringLength(50)]
    public string MAC1 { get; set; }

    [Display(Name = "Arrival Date")]
    public DateTime ARRIVAL_DATE { get; set; }

    [Timestamp]
    [Display(Name = "Record Updated")]
    public DateTime RECORD_UPDATED { get; set; }

    public int LocationId { get; set; }
    public int Location_CodeId { get; set; }
    public int MemoryId { get; set; }
    public int MonitorId { get; set; }
    public int PlantId { get; set; }
    public int DepartmentId { get; set; }
    public int Operating_SystemId { get; set; }

    [ForeignKey("DeparmentId")]
    public virtual Department Department { get; set; }

    [ForeignKey("DeviceType_DesktopId")]
    public virtual DeviceType_Desktop DeviceType_Desktop { get; set; }

    [ForeignKey("Location_CodeId")]
    public virtual Location_Code Location_Code { get; set; }

    [ForeignKey("LocationId")]
    public virtual Location Location { get; set; }

    [ForeignKey("MemoryId")]
    public virtual Memory Memory { get; set; }

    [ForeignKey("Model_DesktopId")]
    public virtual Model_Desktop Model_Desktop { get; set; }

    [ForeignKey("MonitorId")]
    public virtual Monitor Monitor { get; set; }

    [ForeignKey("Operating_SystemId")]
    public virtual Operating_System Operating_System { get; set; }

    [ForeignKey("PlantId")]
    public virtual Plant Plant { get; set; }


    public IEnumerable<DesktopCreateViewModel> Create_Desktop { get; set; }

    public virtual ICollection<DesktopCreateViewModel> Desktops { get; set; }


Here is the portion of the controller that fails
     [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(ICollection<DesktopCreateViewModel> desktop)
    {
        if (ModelState.IsValid)
        {
            foreach (var item in desktop)
            {
                db.Entry(desktop).State = EntityState.Added;
            }
            db.SaveChanges();
            return RedirectToAction("Index");
        }

         ViewBag.DepartmentId = new SelectList(db.Departments, "Id", "DEPARTMENT1", desktop.DepartmentId);
         ViewBag.DeviceType_DesktopId = new SelectList(db.DeviceType_Desktop, "Id", "DEVICE_TYPE", desktop.DeviceType_DesktopId);
         ViewBag.Location_CodeId = new SelectList(db.Location_Code, "Id", "LOCATION_CODE1", desktop.Location_CodeId);
         ViewBag.LocationId = new SelectList(db.Locations, "Id", "LOCATION1", desktop.LocationId);
         ViewBag.MemoryId = new SelectList(db.Memories, "Id", "MEMORY1", desktop.MemoryId);
         ViewBag.Model_DesktopId = new SelectList(db.Model_Desktop, "Id", "MODEL", desktop.Model_DesktopId);
         ViewBag.MonitorId = new SelectList(db.Monitors, "Id", "MONITOR1", desktop.MonitorId);
         ViewBag.Operating_SystemId = new SelectList(db.Operating_System, "Id", "OS", desktop.Operating_SystemId);
         ViewBag.PlantId = new SelectList(db.Plants, "Id", "PLANT1", desktop.PlantId); 
        return View(desktop);
    }

This is the View

@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Desktop</h4>
        <hr />
        @Html.ValidationSummary(true)

        <div class="form-group">
            @Html.LabelFor(model => model.SERIAL_NUMBER, new { @class = "control-label col-md-4" })
            <div class="col-md-8">
                @Html.EditorFor(model => model.SERIAL_NUMBER)
                @Html.ValidationMessageFor(model => model.SERIAL_NUMBER)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Model_DesktopId, "Model", new { @class = "control-label col-md-4" })
            <div class="col-md-8">
                @Html.DropDownList("Model_DesktopId", String.Empty)
                @Html.ValidationMessageFor(model => model.Model_DesktopId)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.DeviceType_DesktopId, "Device Type", new { @class = "control-label col-md-4" })
            <div class="col-md-8">
                @Html.DropDownList("DeviceType_DesktopId", String.Empty)
                @Html.ValidationMessageFor(model => model.DeviceType_DesktopId)
            </div>
        </div>


        <div class="form-group">
            @Html.LabelFor(model => model.MAC1, new { @class = "control-label col-md-4" })
            <div class="col-md-8">
                @Html.EditorFor(model => model.MAC1)
                @Html.ValidationMessageFor(model => model.MAC1)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.ARRIVAL_DATE, new { @class = "control-label col-md-4" })
            <div class="col-md-8">
                @Html.EditorFor(model => model.ARRIVAL_DATE)
                @Html.ValidationMessageFor(model => model.ARRIVAL_DATE)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.RECORD_UPDATED, new { @class = "control-label col-md-4" })
            <div class="col-md-8">
                @Html.EditorFor(model => model.RECORD_UPDATED)
                @Html.ValidationMessageFor(model => model.RECORD_UPDATED)
            </div>
        </div>


        <div class="form-group">
            @Html.LabelFor(model => model.LocationId, "Location", new { @class = "control-label col-md-4" })
            <div class="col-md-8">
                @Html.DropDownList("LocationId", String.Empty)
                @Html.ValidationMessageFor(model => model.LocationId)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Location_CodeId, "Location Code", new { @class = "control-label col-md-4" })
            <div class="col-md-8">
                @Html.DropDownList("Location_CodeId", String.Empty)
                @Html.ValidationMessageFor(model => model.Location_CodeId)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.MemoryId, "Memory", new { @class = "control-label col-md-4" })
            <div class="col-md-8">
                @Html.DropDownList("MemoryId", String.Empty)
                @Html.ValidationMessageFor(model => model.MemoryId)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.MonitorId, "Monitor", new { @class = "control-label col-md-4" })
            <div class="col-md-8">
                @Html.DropDownList("MonitorId", String.Empty)
                @Html.ValidationMessageFor(model => model.MonitorId)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.PlantId, "Plant", new { @class = "control-label col-md-4" })
            <div class="col-md-8">
                @Html.DropDownList("PlantId", String.Empty)
                @Html.ValidationMessageFor(model => model.PlantId)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.DepartmentId, "Department", new { @class = "control-label col-md-4" })
            <div class="col-md-8">
                @Html.DropDownList("DepartmentId", String.Empty)
                @Html.ValidationMessageFor(model => model.DepartmentId)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Operating_SystemId, "Operating System", new { @class = "control-label col-md-4" })
            <div class="col-md-8">
                @Html.DropDownList("Operating_SystemId", String.Empty)
                @Html.ValidationMessageFor(model => model.Operating_SystemId)
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-8 col-md-4">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}
Était-ce utile?

La solution

The action is expecting a collection of viewmodels (ICollection<DesktopCreateViewModel>), but the view only contains one. Try changing to:

public ActionResult Create(DesktopCreateViewModel desktop)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top