TempData is always 0

Cloudy tech 1 Reputation point
2022-03-04T10:30:44.343+00:00

Background regarding the web application I am writing. I have a razor page that creates a Product (the information is inserted into the database and the database is creating the productId). Afterwards, in the post request, I want to redirect to another page razor that shows all the information about that product.

I was trying to pass the product Id by using the TempData, but for some reason, it's always 0. I want to point out that I am fairly new to MVC and ASP.NET core. I understand I might need to create a controller to pass the data, but I am not sure. Below is my code:

CreateProduct.cshthml.cs:

using Accounts.Data;
using Accounts.Domain;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace Template_Site.Pages
{
    public class CreateProductModel : PageModel
    {
        private readonly IProductRepository _products;
        [TempData]
        public int productId { get; set; }
        [BindProperty]
        public Product Product { get; set; }
        public CreateProductModel(IProductRepository product)
        {
            _products=product;
        }
        public IActionResult OnGet()
        {
            return Page();
        }

    public IActionResult OnPost()
        {
            if (ModelState.IsValid)
            {

                //_products.AddProduct(Product);
                //_products.SaveAll();
               productId = _products.RecentProduct().Id;
                return RedirectToPage("/ProductReDirect", productId);

            }
            return Page();

        }
    }

CreateProduct.cshthml:

@page
@model Template_Site.Pages.CreateProductModel
@{
}
<div class="header">
    <h1>Product Creation</h1>
</div>
<div class="row">
    <form method ="post">
     <div class="column side"></div>
     <div class= "column middle">
         <div class="ForForm">
         <label asp-for=@Model.Product.Name></label>
         <input asp-for=@Model.Product.Name class="form-contorl"/>
         <span class="text-danger" asp-validation-for=@Model.Product.Name></span>
       </div>
         <div class="ForForm">
         <label  asp-for=@Model.Product.Version></label>
         <input  asp-for=@Model.Product.Version class="form-contorl"/>
         <span class="text-danger" asp-validation-for=@Model.Product.Version></span>
         </div>
         <div class="ForForm" >
         <label asp-for=@Model.Product.Amount></label>
         <input asp-for=@Model.Product.Amount class="form-contorl"/>
         <span class="text-danger" asp-validation-for=@Model.Product.Amount></span>
         </div>
       <div>
         <button type="submit" class= "button button3" asp-page="/ProductReDirect" asp-route-productId=@Model.productId>Create</button>
      </div>
      </div>
    <div class="column side"></div>
    </form>
</div>

ProductReDirect.cshtml.cs:

using Accounts.Data;
using Accounts.Domain;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace Template_Site.Pages
{
    public class ProductReDirectModel : PageModel
    {
        private readonly IProductRepository _product;

        public Product Product { get; set; }
        [BindProperty(SupportsGet = true)]
        public int productId { get; set; }
        public ProductReDirectModel(IProductRepository product)
        {
            _product = product;
        }
        public void OnGet()
        {
            productId = (int)TempData["productId"];
            TempData.Keep("productId");
            Product = new Product();
            Product = _product.GetById(productId);
        }
    }
}

ProductReDirect.csthml:

@page
@model Template_Site.Pages.ProductReDirectModel
@{
}
<h2>You created a new product!</h2>

<h2> id: @Model.productId</h2>

code from MVC interview questions and answers.

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,162 questions
ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,254 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,243 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Zhi Lv - MSFT 32,011 Reputation points Microsoft Vendor
    2022-03-07T03:19:25.817+00:00

    Hi @Cloudy tech ,

    I was trying to pass the product Id by using the TempData, but for some reason, it's always 0.
    <button type="submit" class= "button button3" asp-page="/ProductReDirect" asp-route-productId=@Model.productId>Create</button>

    The issue relates the above code, since you have set the asp-page and asp-route-productId attribute, after clicking this button, it will submit the form to the ProductReDirect page (ProductReDirectModel's OnGet method), instead of the CreateProductModel's OnPost method. If you set a break point in the OnPost method, you can see that the break point never hit. More detail information, see asp-page and asp-route-{value}.

    To solve this issue, you can remove the asp-page and asp-route-productId attribute. After modified, the button like this:

    <button type="submit" class= "button button3">Create</button>  
    

    You can also refer this screenshot:

    180485-2.gif


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,
    Dillion

    1 person found this answer helpful.
    0 comments No comments

  2. Michael Taylor 48,046 Reputation points
    2022-03-04T16:32:15.257+00:00

    TempData is rarely needed and is for when you don't want to create a model. In your case you don't need it I believe. Just remove that logic. In your OnPost call you get the ID back from your backend system. You can store that value into a local variable and then just pass it as the data to the redirect call.

    public IActionResult OnPost()
    {
       ...
       var productId = _products.RecentProduct().Id;
       return RedirectToPage("/ProductReDirect", productId);    
    }
    

    You are passing the ID as part of the URL that will get generated so TempData isn't needed. On the redirect page you will just see the data set as part of the model (assuming you bound it properly).

    public class ProductReDirectModel : PageModel
     {
       ...
       [BindProperty(SupportsGet = true)]
       public int productId { get; set; }
    
       public void OnGet()
       {
            //productId should already be set here...
            Product = _product.GetById(productId);
       }
    }
    

    If productId is not set in the call to OnGet then there is a problem with the generated URL. Using the browser tools see what the URL is that is being sent to the browser for the redirect URL. Then make sure that URL lines up with what your page model is using.

    0 comments No comments