Search code examples
c#asp.net-coreasp.net-core-mvc

ASP.NET Core MVC | how to pass a value between controller methods


When adding a new entry into the db, I would like to grab an ID value to be entered from a previous page. I have no problem passing the ID from initial page into the controller create method which displays the view of the submission form. But I am not sure how I can access it after the form is submitted.

I have tried using TempData, ViewData and ViewBag, but I don't see the value when trying to retrieve it in the second method.

    [HttpGet]
    public IActionResult Create(int? id){

         // I see the value here
    
            Debug.WriteLine(id);
            TempData["carid"] = id;
            Debug.WriteLine(TempData["carid"]);  
    
            return View(); // displays new entry form 
        }
        
        // called after the new entry form is submitted 
        [HttpPost]  
        public async Task<IActionResult> Create(RecordsViewModel addRecord)
        {
    
          // NO value here
    
            var carId = TempData["carid"]; 
            Debug.WriteLine(carId);   
    
    
            var record = new Records()
            {
                ID = carId, // value here is null 
                Date = addRecord.Date,
                Name = addRecord.Name,
                Cost = addRecord.Cost,
            };
    
            await carRep.Records.AddAsync(record);
            await carRep.SaveChangesAsync();
            return RedirectToAction("Create");
    
        }

Any guidance is greatly appreciated, thanks!


Solution

  • I have tried using TempData, ViewData and ViewBag, but I don't see the value when trying to retrieve it in the second method.

    Well, reason you were not able to retrieve the value is all are not persistant data container. Once the action been redirected, data no longer would be either in Tempdata, viewdata or viewbag these are one time only.

    In order to keep the data from one action to another action even after the page redirection you can use session which is data persistant or can keep the data as long as you want.

    You can do as following:

    Set Value:

    [HttpGet]
     public IActionResult Create(int? id)
     {
    
         // I see the value here
    
         Debug.WriteLine(id);
         //TempData["carid"] = id;
         //Just for testing
         HttpContext.Session.SetInt32("carid", (int)id!);
     
         return View(); // displays new entry form 
     }
    

    Get Value:

    [HttpPost]
    public async Task<IActionResult> Create(RecordsViewModel addRecord)
    {
    
        // NO value here
    
        //Just for testing
        var carId = HttpContext.Session.GetInt32("carid");
    
       // var carId = TempData["carid"];
        Debug.WriteLine(carId);
    
    
        //var record = new Records()
        //{
        //    ID = carId, // value here is null 
        //    Date = addRecord.Date,
        //    Name = addRecord.Name,
        //    Cost = addRecord.Cost,
        //};
    
        //await carRep.Records.AddAsync(record);
        //await carRep.SaveChangesAsync();
        return RedirectToAction("Create");
    
    }
    

    Note: In order to test the scenario I have commented few of your code. Just use it as you need.

    Program.cs:

    builder.Services.AddSession(options =>
    {
        options.Cookie.Name = "YourCookieName";
        options.IdleTimeout = TimeSpan.FromMinutes(2);
        options.Cookie.HttpOnly = true;
        options.Cookie.IsEssential = true;
    });
    

    Middleware Order:

    app.UseRouting();
    app.UseSession();
    app.UseAuthorization();
    

    Output:

    enter image description here

    enter image description here

    Note: Please refer to this official document for more implementation sample.