Search code examples
formsmodel-view-controllerasp.net-core-mvchttp-post

null reference when clicking submit on a form that is filled in with mvc C#


I have a form I created in a view which is supposed to submit to two tables using a view model. When I fill in the fields and click submit, I am getting a null reference exception on the vendormodel and refvendormodel after filling everything in on the form and am unsure of the cause. Any help is greatly appreciated.

My Controller method:

      [HttpPost]
       [Route("Contract/AddVendor")]
       [Route("Contract/AddVendor/{addVendor}")]
    
        public IActionResult AddVendorForm(AddVendorVM addVendor)
        {
            AddVendorVM model = new AddVendorVM();
    
          if(ModelState.IsValid)
{
                model.vendormodel.VENDOR_ID = addVendor.vendormodel.VENDOR_ID;
                model.refvendormodel.VENDOR_ID = addVendor.refvendormodel.VENDOR_ID;
                model.vendormodel.VENDOR_NAME = addVendor.vendormodel.VENDOR_NAME;
                model.refvendormodel.ADDRESS = addVendor.refvendormodel.ADDRESS;
                model.refvendormodel.CITY = addVendor.refvendormodel.CITY;
                model.refvendormodel.STATE = addVendor.refvendormodel.STATE;
                model.refvendormodel.ZIP = addVendor.refvendormodel.ZIP;
                model.refvendormodel.FIRST_NAME = addVendor.refvendormodel.FIRST_NAME;
                model.refvendormodel.LAST_NAME = addVendor.refvendormodel.LAST_NAME;
                model.refvendormodel.PHONE = addVendor.refvendormodel.PHONE;
                
                _context.VENDORs.Add(model.vendortmodel);
                _context.REF_VENDORs.Add(model.refvendormodel);
                _context.SaveChangesAsync();
                return RedirectToAction("Edit");
    }
          
            return View(model);
        }
    
       
       [HttpGet]
        [Route("Contract/AddVendor")]

        public IActionResult AddRespondentForm()
        {
            AddVendorVM model = new AddVendorVM();
            return View(model);

        }

     

My View:

    <div class="col-md-4">
        @using (
        Html.BeginForm("AddVendor", "Contract", FormMethod.Post, new { id = "Form1"}))
        {
            @Html.HiddenFor(m => Model.vendormodel.VENDOR_ID, new { id = "VendorId" })
            @Html.HiddenFor(m => Model.refvendormodel.VENDOR_ID, new { id = "VendorId" })
    
            <label class="control-label">Vendor Name:</label>
            @Html.TextBoxFor(r => r.vendormodel.VENDOR_NAME)
    
    
            <label class="control-label">Address:</label>
            @Html.TextBoxFor(r => r.refvendormodel.ADDRESS)
    
    
    
            <label class="control-label">City:</label>
            @Html.TextBoxFor(r => r.refvendormodel.CITY)
    
    
    
            <label class="control-label">State:</label>
            @Html.TextBoxFor(r => r.refvendormodel.STATE)
    
    
    
            <label class="control-label">Zip Code:</label>
            @Html.TextBoxFor(r => r.refvendormodel.ZIP)
    
    
    
            <label class="control-label">First Name:</label>
            @Html.TextBoxFor(r => r.refvendormodel.FIRST_NAME)
    
    
    
            <label class="control-label">Last Name:</label>
            @Html.TextBoxFor(r => r.refvendormodel.LAST_NAME)
    
    
    
            <label class="control-label">Phone Number:</label>
            @Html.TextBoxFor(r => r.refvendormodel.PHONE)
    
    
            <br />
            <input type="submit" value="Add Vendor" />
        }
    </div>
    
    
    <div>
        <a asp-action="Index">Back to List</a>
        </div>

My model:

        public class AddVendorVM
    
        {
    
    
            public VENDOR vendormodel { get; set; }
            public REF_VENDOR refvendormodel { get; set; }
    
    
        }
    

Solution

  • You need to change your code like below:

     public IActionResult AddVendorForm(AddVendorVM addVendor)
        {
            ModelState.Remove("vendormodel.VENDOR_ID");
            ModelState.Remove("refvendormodel.VENDOR_ID");
            if (ModelState.IsValid)
            {
                VENDOR model1 = addVendor.vendormodel;
                REF_VENDOR model2 = addVendor.refvendormodel;
                _context.VENDORs.Add(model1);
                _context.REF_VENDORs.Add(model2);
                _context.SaveChanges();
                return RedirectToAction("Edit");
            }
    
            return View();         
        }
    

    The code in your view are meaningless, you can delete them:

    @Html.HiddenFor(m => Model.vendormodel.VENDOR_ID, new { id = "VendorId" })
    @Html.HiddenFor(m => Model.refvendormodel.VENDOR_ID, new { id = "VendorId" })
    

    Please notice that if your VENDOR_ID is a primary key of model VENDOR,REF_VENDOR.It will be a required column and automatic increase,so if the VENDOR_ID is 0,the validation will never be true,so you need remove the vendormodel.VENDOR_ID modelstate,then the modelstate will be true.

    And you need to notice that don't use SaveChangesAsync in a synchronous method.That will not work.