Asked by:
Help with error

Question
-
User627490255 posted
Hi all, i have a webapp my brother in law helped me build it (well he did it all..then has largely left me too it), i am new to programming c#, http, css etc. ai have a little sporadic experience with python and vb,net.
anyway, i have an 'object not set to an instance of an object error when submit button is hit.
i have noted where the code resides.
In views/incident/editincident.cshtml @model CareHomeForms.Models.EditIncidentViewModel <!-- The heading title for the page --> <div class="row"> <div class="col-sm-12"> <h1>Report a new incident</h1> </div> </div> <div class="row"> <div class="col-sm-12"> <h2 class="alert">General Details</h2> </div> </div> <div class="row"> <div class="col-sm-12"> <form action="@Url.Action("EditIncident","Incident")" method="post" class="form-horizontal"> @Html.AntiForgeryToken() <div class="form-group"> <label for="IncidentNumber" class=" control-label col-sm-3">Incident Number</label> <div class="col-sm-1"> <input type="text" name="IncidentNumber" id="IncidentNumber" value="@Model.IncidentNumber" readonly class="form-control" data-toggle="popover" data-content="Generated Automaticaly" data-trigger="focus" data-placement="top" /> </div> </div> <div class="form-group"> <div class="col-sm-12"> <button type="submit" name="Submit" class="btn btn-success pull-right">Create Incident</button> </div> </div> <div class="form-group"> <div class="col-sm-12"> <a href="@Url.Action("","")" class="btn btn-default">Cancel & Return To Home Page</a>. </div> </div> </form> In root of controlers folder using CareHomeForms.Models; using CareHomeForms.Services.Data; using CareHomeForms.Services.Data.Models; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; namespace CareHomeForms.Controllers { [Route("incident")] public class IncidentController : Controller { private ICareHomesDb db; public IncidentController(ICareHomesDb db) { this.db = db; } [Route("New")] // The name of the function [HttpGet] [Authorize(Roles = "admin")] public ActionResult NewIncident(EditIncidentViewModel viewModel, string id = null) // what is passed to it in brackets { var newId = id ?? Guid.NewGuid().ToString(); // generate a new guid for the new form return RedirectToAction("EditIncident", new {incidentId = newId}); // this redirects to another function 'editincident' with the viewmodel and new id } [Route("{incidentId}/edit")]//request received for the incident report form [HttpGet] public async Task<ActionResult> EditIncident() //The view name { var employeeResults = await db.GetPeopleAsync(PersonType.Employee); var employees = employeeResults.ToList(); employees.Insert(0, new Person()); var residentsResults = await db.GetPeopleAsync(PersonType.Resident); var residents = residentsResults.ToList(); residents.Insert(0, new Person()); var viewModel = new EditIncidentViewModel { IncidentNumber = "1234", Staff = ToIdentifiedPerson(employees), Residents = ToIdentifiedPerson(residents) }; return View(viewModel); } //// This action will respond to a POST request from a form being submitted [Route("{incidentId}/edit")] [HttpPost] //do something when a form has been sent (posted) back [ValidateAntiForgeryToken] public async Task<ActionResult> FormSubmitted(EditIncidentViewModel viewModel, string returnUrl = null) { bool isUpdate = true; var incident = await db.GetIncidentFormByIdAsync(viewModel.Incident.Id); if (incident == null) { incident = viewModel.Incident; incident.Version = 1; incident.IsDraft = false; } else { isUpdate = false; } incident.LastUpdated = DateTime.UtcNow; incident.Author = "5E5D44AF-2B72-4F7D-AC95-F99530E2752D"; await db.SaveIncident(incident, isUpdate); return RedirectToAction("FormSubmitted", new { viewModel.Incident.Id, returnUrl }); } In root of models folder using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using CareHomeForms.Models; using CareHomeForms.Services.Data.Models.FormModels; namespace CareHomeForms.Models { public class EditIncidentViewModel { public List<IdentifiedPerson> Staff { get; set; } public Incident Incident { get; set; } public List<IdentifiedPerson> Residents { get; set; } public string IncidentNumber { get; set; } public string IncidentId { get; internal set; } public string Id { get; internal set; } public string ReportingStaffId { get; set; } public bool IsUpdate { get; set; } } }
Any help with this error appreciated:-)
Error – NullReferenceException: Object reference not set to an instance of an object. • CareHomeForms.Controllers.IncidentController.FormSubmitted(EditIncidentViewModel viewModel, string returnUrl) in IncidentController.cs + 67. var incident = await db.GetIncidentFormByIdAsync(viewModel.Incident.Id);
cheers
steve
Wednesday, September 18, 2019 6:57 AM
All replies
-
User197322208 posted
Technical:
Is normal that this line gives error in POST
var incident = await db.GetIncidentFormByIdAsync(viewModel.Incident.Id);
because , in the view, there are not posting any field that is Incident.Id
What should be this id taken from ?
It is, by any chance,
<input type="text" name="IncidentNumber"
Wednesday, September 18, 2019 2:43 PM -
User627490255 posted
Good point....I am pretty much copying and pasting from a very similar form, and trying to figure out how it all clicks together. I will post the view from that and maybe you could help me understand why that one works and this doesn't?
@model CareHomeForms.Models.EditDocumentViewModel @{ ViewData["Title"] = "Document Editor"; } @section HeadScripts { <link rel="stylesheet" href="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.css"> <script src="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.js"></script> } <div class="row"> <div class="col-sm-12"> <h2>@(Model.IsUpdate ? "Edit Document" : "New Document")</h2> </div> </div> <div class="row"> <div class="col-sm-12"> <form class="form-horizontal" action="@Url.Action("EditDocument", new { returnUrl = Model.ReturnUrl })" method="post"> @Html.AntiForgeryToken() <input type="hidden" name="Document.Id" value="@Model.Document.Id" /> <input type="hidden" name="Document.DocumentType" value="@Model.Document.DocumentType" /> <div class="form-group"> <input type="text" value="@Model.Document.Title" placeholder="Title" name="Document.Title" class="form-control" /> </div> <div class="form-group"> <textarea class="form-control" rows="40" name="Document.DocumentText" id="txtDocument">@Model.Document.DocumentText</textarea> </div> <div class="form-group"> <a href="@Model.ReturnUrl" class="btn btn-danger">Cancel</a> <button type="submit" class="btn btn-success pull-right">Save</button> </div> </form> </div> </div> <section Scripts> <script> var editor = new SimpleMDE({ element: document.getElementById("txtDocument") }); </script> </section>
Wednesday, September 18, 2019 5:48 PM -
User-17257777 posted
Hi greenblood,
<input type="text" name="IncidentNumber" id="IncidentNumber"
The first form only has one input(name="IncidentNumber") that will be sent to the controller, so the "Incident " in "EditIncidentViewModel" will be null.
var incident = await db.GetIncidentFormByIdAsync(viewModel.Incident.Id);
And you want to get the "id" from a null Object, it will certainly give the error.
Best Regards,
Jiadong Meng
Friday, September 20, 2019 8:52 AM -
User627490255 posted
Hi, Thanks for the help.
But there is a hidden field for incident.id -
<input type="hidden" name="Incident.Id" value="@Model.Incident.Id" />
When run with a break, there's no object being passed back to the controller.
Friday, September 20, 2019 1:14 PM -
User197322208 posted
But there is a hidden field for incident.id -
<input type="hidden" name="Incident.Id" value="@Model.Incident.Id" />
I do not see in the original post
<form class="form-horizontal" action="@Url.Action("EditDocument", new { returnUrl = Model.ReturnUrl })" method="post"> @Html.AntiForgeryToken() <input type="hidden" name="Document.Id" value="@Model.Document.Id" /> <input type="hidden" name="Document.DocumentType" value="@Model.Document.DocumentType" /> <div class="form-group"> <input type="text" value="@Model.Document.Title" placeholder="Title" name="Document.Title" class="form-control" /> </div> <div class="form-group"> <textarea class="form-control" rows="40" name="Document.DocumentText" id="txtDocument">@Model.Document.DocumentText</textarea> </div> <div class="form-group"> <a href="@Model.ReturnUrl" class="btn btn-danger">Cancel</a> <button type="submit" class="btn btn-success pull-right">Save</button> </div> </form>
Friday, September 20, 2019 2:22 PM -
User627490255 posted
Ah no, that's the second post I made, with the code I'm copying for reference. That mvc combo works fine.
heres the post function for that mvc.
[Route("{documentId}/edit")] //data recieved from webpage {documentid}/edit [HttpPost] [ValidateAntiForgeryToken] [Authorize(Roles = "admin")] //only admin level can edit public async Task<ActionResult> EditDocument(EditDocumentViewModel viewModel, string returnUrl = null) //function name EditDocument { returnUrl = GetReturnUrl(returnUrl); bool isUpdate = false; var document = await db.GetDocumentByIdAsync(viewModel.Document.Id); //see if there is a document in the db with this id if (document == null) { document = viewModel.Document; //if not, create new document document.Version = 1; //give it a version 1 number document.IsDraft = false; } else //if there is a document with this id, { document.DocumentText = viewModel.Document.DocumentText; //update document details and mark as updated document.Title = viewModel.Document.Title; isUpdate = true; } document.LastUpdated = DateTime.UtcNow; document.Author = User.FindFirst(ClaimTypes.NameIdentifier).Value;//"5E5D44AF-2B72-4F7D-AC95-F99530E2752D"; assign author as the logged in person await db.SaveDocument(document, isUpdate); //save the document to the db return RedirectToAction("ShowDocument", new { viewModel.Document.Id, returnUrl }); }
and the model-
using CareHomeForms.Services.Data.Models; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using CareHomeForms.Services.Data.Models.DocumentModels; namespace CareHomeForms.Models { public class EditDocumentViewModel { public Document Document { get; set; } public bool IsUpdate { get; set; } public string ReturnUrl { get; set; } public string PersonId { get; set; } } }
for some reason, all works fine with document but not with incident, but both are the same.
Friday, September 20, 2019 3:31 PM -
User197322208 posted
Please post again the View and the Code that is having error.
Tuesday, September 24, 2019 3:56 PM -
User1120430333 posted
I did what was in the link and made a couple of adjustments in code below.
https://www.code-sample.com/2014/08/base-controller-in-mvc-5.html
using System; using System.Web; using System.Web.Mvc; using System.Web.Routing; using log4net; namespace MVC.Controllers { public abstract partial class BaseController : Controller { private ILog _logger; protected BaseController() { _logger = LogManager.GetLogger(typeof(BaseController)); } protected override void OnException(ExceptionContext filterContext) { AppException appException = new AppException(Convert.ToString(filterContext.Exception)) { Type = filterContext.GetType().ToString(), StackTrace = filterContext.Exception.StackTrace, Source = filterContext.Exception.Source, InnerException = Convert.ToString(filterContext.Exception.InnerException) }; _logger.Error(appException.ToString()); Server.ClearError(); RedirectToControllers("Home", "Error"); } private void RedirectToControllers(string control, string action) { var routeData = new RouteData(); routeData.Values["controller"] = control; routeData.Values["action"] = action; IController controller = new HomeController(); ((IController) controller).Execute(new RequestContext( new HttpContextWrapper(System.Web.HttpContext.Current), routeData)); } } }
Tuesday, September 24, 2019 8:15 PM -
User627490255 posted
Turns out the problem was related to the 'internal' statement on the id in the view model.
Thanks chaps for the help
SteveTuesday, September 24, 2019 9:46 PM