0

Upon my post ActionResult Edit, I am receiving an error. System.Web.Mvc.WebViewPage<TModel>.Model.get returned null

My controller:

[HttpPost]
    public ActionResult Edit(editRequestViewModel _editRequestViewModel, int id)
    {
        try
        {
            if (ModelState.IsValid)
            {
                using (var db = new HelpDeskContext())
                {

                    db.Entry(_editRequestViewModel.userRequest).State = System.Data.Entity.EntityState.Modified;
                    db.SaveChanges();

                    return RedirectToAction("Digest",new { id = _editRequestViewModel.userRequest.ID });
                }
            }

            else
                return View();
        }
        catch (Exception ex)
        {
            return View("Error", new HandleErrorInfo(ex, "Change", "Browse"));
        }
    }

My View includes this for the models field to bind:

  @Html.DropDownListFor(model => model.userRequest.forApplication, Model.Applications, "Select Application", new { @class = "form-control" })

My Model has the field as nullable int?:

public int? forApplication { get; set; }

It seems to update the other fields in the model with this field just fine on POST. When the request is first created and saved to the DB, it saves fine in that field when its null. It seems to me that nullable should be OK as a value when its posting (Edit ActionResult)?

EDIT: This is my GET Method that populates the View Model which is passed in to the POST.

public ActionResult Edit(int id)
    {
        try
        {
            if (ModelState.IsValid)
            {
                using (var db = new HelpDeskContext())
                {
                    var query = (from m in db.Requests
                                 where m.ID == id
                                 select new editRequestViewModel()
                                 {
                                     Applications = (from r in db.Applications
                                                     select new SelectListItem(){
                                                         Text = r.Name,
                                                         Value = r.ID.ToString()
                                                        }).ToList(),
                                     closeReasons = (from r in db.CloseReasons
                                                     select new SelectListItem()
                                                     {
                                                         Text = r.Name,
                                                         Value = r.ID.ToString()
                                                     }).ToList(),
                                     userRequest = m

                                 }).FirstOrDefault();
                    return View(query);
                }
            }

            else
                return View();
        }
        catch (Exception ex)
        {
            return View("Error", new HandleErrorInfo(ex, "Change", "Browse"));
        }
    }

And my View has @model HelpDeskSolution.ViewModels.editRequestViewModel

EDIT 2: ViewModel and Model

  namespace HelpDeskSolution.Models
 {
  public class Request
   {
    [DatabaseGenerated(DatabaseGeneratedOption.Identity), Key()]
    public int ID { get; set; }
    [Required]
    [StringLength(99, MinimumLength = 3)]
    public string Title { get; set; }
    [StringLength(1000, MinimumLength = 1)]
    [Required]
    public string Description { get; set; }
    [Required]          
    [Display(Name = "Submit Date")]
    public DateTime SubmitDate { get; set; }
    public DateTime? CloseDate { get; set; }
    [Required]
    [StringLength(30)]
    public string Author { get; set; }
    [Required]
    [StringLength(30)]
    public string AuthDept { get; set; }
    [StringLength(30)]
    [Display(Prompt = "Text at top of Epicor Screen...(Optional)")]
    public string Module { get; set; }
    public int Urgency { get; set; }
    [StringLength(30)]
    public string Type { get; set; }
    public int Status { get; set; }
    [StringLength(30)]
    [Display(Name = "Request For")]
    public string RequestFor { get; set; }
    [Required]
    public bool Closed { get; set; }
    [StringLength(30)]
    [Display(Name = "Assign To")]
    public string AssignedTo { get; set; }
    [Display(Name = "Application")]
    public int? forApplication { get; set; }
    public int? closeReason { get; set; }
    public string ClosedBy { get; set; }
    [Display(Name = "ID")]
    public int? duplicateOf { get; set; }

    }
    }

Model:

 namespace HelpDeskSolution.ViewModels
    {
public class editRequestViewModel
{
    public Request userRequest { get; set; }
    public List<SelectListItem> Applications { get; set; }
    public List<SelectListItem> closeReasons { get; set; }

 }
 }
Night Channels
  • 152
  • 2
  • 11
  • Possible duplicate of [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Sir Rufo Nov 20 '17 at 22:15
  • `Model.Applications` will be `null` because you have not populated that property before you return the view –  Nov 20 '17 at 22:17
  • @StephenMuecke I am populating that list on the GET actionresult of Edit. It is then passed to the view via a ViewModel in which the drop down is populated and working. – Night Channels Nov 20 '17 at 22:21
  • What about `userRequest` property ? Are you populating that ? – Shyju Nov 20 '17 at 22:22
  • Yes, but your not repopulating it in the POST method in the case where you return the view (refer [this Q/A](https://stackoverflow.com/questions/34366305/the-viewdata-item-that-has-the-key-xxx-is-of-type-system-int32-but-must-be-o)). You have not shown your model so its not clear what you issue is, but the fact your using `db.Entry(_editRequestViewModel.userRequest)` means your view model contains a data model - view models should not contain data models –  Nov 20 '17 at 22:24
  • Edit: Showing GET actionresult now. – Night Channels Nov 20 '17 at 22:25
  • Note also you do not need `if (ModelState.IsValid)` in your GET method (it can never be invalid in your case) –  Nov 20 '17 at 22:25
  • Edit: Added ViewModel and Model – Night Channels Nov 20 '17 at 22:33
  • A view model should not contain data models. It should contain your 2 `IEnumerable` properties, plus properties of `Request` that you need in the view. In the POST method you get the instance of `Request` from the db based on the ID property, and map its property values from the view model, then save the data model. - [What is ViewModel in MVC?](https://stackoverflow.com/questions/11064316/what-is-viewmodel-in-mvc) –  Nov 20 '17 at 22:39
  • And if `ModelState` is invalid, you need to repopulate the SelectLists and return the model - `return View(yourViewModel);` –  Nov 20 '17 at 22:40

1 Answers1

1

Ended up solving this with the direction of @StephenMuecke. The reason I was getting the exception is because upon the return View() in the else portion of the post action, it was attempting to return the view without Applications list, as Stephen said. However that led me to realize that there was first a problem with the Model State, hence why it was even going to the else in the first place. I had another field that was being passed null when it wasnt a nullable type.

I simply changed the type to int? and added a migration and the Action result is A'Okay now.

Night Channels
  • 152
  • 2
  • 11