Object reference not set to an instance of an object

Crystofer Arteaga Galvan 21 Reputation points
2022-05-17T21:18:43.64+00:00

I am creating an application, from my database I create most of the models, except one, Captura, that model contains the attributes of 3 models, inside the captura controller I defined in the index method the query to obtain the content of the tables (SQL ) and cast it with the ViewBag property to the view, Here is a screenshot of my controller

public YMM_ScrapSystemContext _context;  
        public CapturaController(YMM_ScrapSystemContext context)  
        {  
            _context = context;  
        }  
        public IActionResult Index()  
        {  
            ViewBag.Modelos = _context.Modelos.ToList();  
            ViewBag.Estaciones = _context.Estacions.ToList();  
            ViewBag.Correcciones = _context.Correccions.ToList();  
            return View();  
        }  

Now a part of my view:

@{  
    ViewData["Title"] = "Index";  
    var modeloslist = (List<Modelo>)ViewBag.Modelos;  
    var estacioneslist = (List<Estacion>)ViewBag.Estaciones;  
    var correcioneslist = (List<Correccion>)ViewBag.Correcciones;  
    var lblnow = DateTime.Now;  
}  
@model YMMScrapSystem.Models.Captura;  
<h1 style="color: #ff8000;">Captura</h1>  
@using(var Form = Html.BeginForm())  
{  
  <div class = "container">  
    <div class="row justify-content-around">  
        <div class="col-6"></div>  
        <div class="col-6"><label name= "nowvariable">@lblnow.ToString()</label></div>  
    </div>  
 </div>  
 <br />  
<div class="container">  
    <div class="row">  
        <div class="col-md-6">  
            <label class="text-primary">Modelo</label>  
            <div class="list-group">  
                <select id="getmodelo" class="custom-select" name="modelovariable">  
                    <option selected></option>  
                   @foreach(var item in modeloslist)  
                    {  
                         <option value=@item.Idmodelo>@Html.DisplayFor(x => item.Modelo1)</option>  
                    }  
                </select>  
            </div>  
        </div>  

The first time I run the project, the view loads fine, when I submit the data with a submit button, it returns the error "NullReferenceException: Object reference not set to an instance of an object." and mark the line where the @foreach is located, I can't find where the error is, and why only when sending the data, Finally, I show how I try to retrieve the form data, cap is an object of my capture class

 public ActionResult Index(Captura cap)  
    {  
        int elemento = cap.Idmodelo;  
        return View();  
    }  

202922-scrap.png

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,158 questions
ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,253 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,239 questions
0 comments No comments
{count} votes

Accepted answer
  1. Michael Taylor 48,046 Reputation points
    2022-05-17T21:29:42.523+00:00

    Here's a running theory of what is happening but since you didn't post all the code I'm only guessing.

    1) You do a GET request to Index which fills ViewBag and then renders the HTML. This works.
    2) You do a POST request to Index when the user clicks the submit button. This calls your Index action attributed with HttpPost which then updates the backend as you'd expect.
    3) You return from this action using return View()
    4) Your app blows up.

    The issue is that on a POST the only data sent back to the server is the data inside the <form> element, if any. This is generally converted to a model passed to your action. When you then return View() it is going to try to access ViewBag but there is no data there because you never added anything. ViewBag is per request so on the post it has been wiped.

    You need to modify all actions that ultimately will render this view to have all of them set up ViewBag just like you're doing in your initial GET Index action. This is one reason why using ViewBag is not really recommended.

    //Your Index action called when the user "submits" their data
    [HttpPost]
    public IActionResult Index( MyModel model )
    {
        //Do back end work
        ...
    
        //Have to set ViewBag back up
        ViewBag.Modelos = _context.Modelos.ToList();
        ViewBag.Estaciones = _context.Estacions.ToList();
        ViewBag.Correcciones = _context.Correccions.ToList();
        return View();
    }
    

    This is also why it is generally recommended that you instead follow the PRG pattern (Post-Redirect-Get). This solves the problem you're seeing but also the infamous browser refresh problem. In this pattern the user POSTs (submits) to the server to update data. The server responds with a redirect request to the browser after saving the data (can be back to the same action), the browser then does a GET request which pulls the updated data.

    //Your Index action called when the user "submits" their data
    [HttpPost]
    public IActionResult Index( MyModel model )
    {
        //Do back end work
        ...
    
        return RedirectToAction(nameof(Index));
    }
    

    Note that in the case of errors where you want to display the same view again (so the user sees any model errors) then you still need to restore ViewBag otherwise you're back in the same boat.

    1 person found this answer helpful.
    0 comments No comments

0 additional answers

Sort by: Most helpful