Search code examples
asp.net-coreasp.net-core-mvcrazor-pages

ASP.NET Core 7.0 Razor Pages - Get POST request body


I've just started using ASP.NET Core 7.0 Razor Pages. I've previously been using Node.js with Express to setup endpoints on my website. I want to do the same thing in ASP.NET but I can't find any examples on how to do this in Razor Pages, no matter where I look.

So here's what I want to do.

I want to set up and endpoint at /test. If I send a HTTP POST request to that URL (e.g. by using Postman), I want to capture the request body and process it on the backend.

For example if I was in Node.js and sent in two params in the body of the request (username & password), I would do this to read the data:

app.post('/test', (req, res) => {
   const { username, password } = req.body;
   console.log('username is: ', username);
   console.log('password is: ', password);
});

I want to accomplish exactly the same thing but in ASP.NET Core. So what have I done so far? First I created a new Razor page inside my Pages folder. I named it Test.cshtml. Inside that file I removed everything except @model TestModel because I do not want this to be a page on the site that people can visit, it should only be used for POST requests - nothing else.

Then inside its C# file (Test.cshtml.cs) I have this:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace MyWebsite.Pages
{
    public class TestModel : PageModel
    {
        public void OnGet()
        {
        }

        public void OnPost()
        {
            Console.WriteLine("Received a post request.");
        }
    }
}

The first thing I'm trying to do is see if I can capture that I've sent a POST request. For now I'm ignoring what data (body) I've sent. I just want to see something that says "I received your post request."

So I'm going inside Postman, and I send a post request at the URL. But nothing shows up in the console. Is this not how you capture a POST request? And how would I capture its body?

This is not from any form on the page. This is just an endpoint (/test) which should be handling various kinds of POST requests. And then I should be able to process the data, e.g. insert it to a database or something.


Solution

  • For a simple Post endpoint you need something like this:

    public class IndexModel : PageModel
    {
        public IActionResult OnPost()
        {
            return Content("Hello world!");
        }
    }
    

    But if you call this from Postman it will return 400 because it's missing the anti forgery token, but it will work if you add a button or a form inside your razor page.

    If you are just exploring and testing stuff, you can replace this line in your Program.cs:

    builder.Services.AddRazorPages();
    

    with this:

    builder.Services.AddRazorPages(o =>
    {
        o.Conventions.ConfigureFilter(new IgnoreAntiforgeryTokenAttribute());
    });
    

    And it will work via Postman too. More info about Cross-Site Request Forgery.

    If you want to access the body of the request the best approach is creating a class with the schema of the request like this:

    public IActionResult OnPost([FromBody] Request request)
    {
        return Content("Hello world!");
    }
    
    public class Request
    {
        public string Username { get; set; }
        public string Password { get; set; }
    }
    

    You can call this endpoint with a request like this:

    curl --location 'http://localhost:5057/' \
    --header 'Content-Type: application/json' \
    --data '{
        "username": "MyUser",
        "Password": "MyPass"
    }'