Search code examples
c#asp.net-corerazor-pages

Passing data through RedirectToPage


I have an ASP.NET Core Razor Pages visitor management project that I'm working on where I need to pass an instance of a class from one page to another page using the RedirectToPage method.

Process: a visitor first fills out their information on the Create page, the info is posted to the database and then the instance of the visitor is passed to the second page where the data is formatted and screenshotted to post a jpeg to the instance of the visitor in the database.

I've been trying the data pass methods suggested in other posts, but I'm having difficulty translating MVC to Razor Pages. I don't think I can use TempData or ViewData given that I need to both post to a database and add to the specific visitor entry in the database, so I've been looking through Microsoft's docs on the RedirectToPage methods, as well as this post on the different methods.

I think I need to use the PRG Pattern approach with RedirectToPage(string, string, string) that accepts the parameters pageName, pageHandler, and fragment. The part I'm having trouble with is the second page model's code (RegistrationSuccess.cshtml.cs) in calling the visitor instance.

This is the relevant code from Create.cshtml.cs:

 public class CreateModel : PageModel
{
    private readonly VisitorManagementSystem.Data.VisitorManagementSystemContext _context;
    [BindProperty]
    public Visitor Visitor { get; set; }

    public CreateModel(VisitorManagementSystem.Data.VisitorManagementSystemContext context)
    {
       _context = context;
    }

    public IActionResult OnGet()
    {
        return Page();
    }
        
    public async Task<IActionResult> OnPostAsync()
    {
        if (!ModelState.IsValid)
        {
            return Page();
        }
        //....
        _context.Visitor.Add(Visitor);
        await _context.SaveChangesAsync();
        return RedirectToPage("./RegistrationSuccess", "Visitor", new { visitorId  = Visitor.ID.ToString() });
    }
}

RegistrationSuccess.cshtml.cs

public class RegistrationSuccessModel : PageModel
{
    [BindProperty]
    public Visitor Visitor { get; set; }
    private readonly VisitorManagementSystem.Data.VisitorManagementSystemContext _context;
    public RegistrationSuccessModel(VisitorManagementSystem.Data.VisitorManagementSystemContext context)
    {
        _context = context;
    }
    
    //This is where I'm not sure what the correct syntax is to call the instance of the visitor
    public IActionResult OnGet(string visitorId)
    {
        //from the visitorId value, get the object
        Visitor = VisitorManagementSystem.GetVisitor(visitorId);
        return Page();
    }
    public async Task<IActionResult> OnPostAsync()
    {
        return RedirectToPage("/Visitors/RegistrationSuccess");
    }
}

I've tried using the RedirectToPage(string, object) method, but this has two problems: all of the visitor's info is displayed in the URL, which seems insecure; also, I get the error

This site can't be reached ERR_HTTP2_PROTOCOL_ERROR


Solution

  • You should add to the top of your RegistrationSuccess.cshtml.cs razor page

    @page "{visitorId}"
    

    and from the action use RedirectToPage(pageName: string, routeValues: object)

    return RedirectToPage("./RegistrationSuccess", 
                          new { visitorId  = Visitor.ID.ToString() });
    

    and fix the action

    public IActionResult OnGet(string visitorId)
    {
       if (!string.IsNullOrEmpty(visitorId))
          Visitor = _context.Set<Visitor>().FirstOrDefault( i => 
                                             i.VisitorId==visitorId);
       return Page();
    
    }