skip to Main Content

I’m trying to send JSON data from JavaScript to my C# code in an ASP.NET Razor Pages project, but I keep getting a "400 Bad Request" error. The goal is to parse and handle the data in the C# backend. Below is my JavaScript and C# code:

JavaScript code:

const data = [
    {
        "customer_name": "Abdullah Al Mahmud",
        "mobile": 7654,
        "bookName": "Physics 1st paper",
        "unit_price": 250,
        "quantity": 1,
        "discount": 0,
        "total": 250
    },
    {
        "customer_name": "Abdullah Al Mahmud",
        "mobile": 7654,
        "bookName": "Physics 1st paper",
        "unit_price": 250,
        "quantity": 6,
        "discount": 0,
        "total": 1500
    }
];

$.ajax({
    url: '/Index',
    type: 'POST',
    contentType: 'application/json',
    data: JSON.stringify({ data }), 
    success: function(result) {
        console.log(result);
    }
});

C# code:

public class IndexModel : PageModel
{
    [BindProperty]
    public List<OrderData> Orders { get; set; }

    public async Task<IActionResult> OnPostAsync()
    {
        using (var reader = new System.IO.StreamReader(Request.Body))
        {
            var body = await reader.ReadToEndAsync();
            Orders = JsonConvert.DeserializeObject<List<OrderData>>(body);
            foreach (var order in Orders)
            {
                System.Diagnostics.Debug.WriteLine($"Customer: {order.CustomerName}, Book: {order.BookName}, Total: {order.Total}");
            }
        }

        return new JsonResult(new { message = "Data received successfully", orders = Orders });
    }
}

public class OrderData
{
    [JsonProperty("customer_name")]
    public string CustomerName { get; set; }

    [JsonProperty("mobile")]
    public int Mobile { get; set; }

    [JsonProperty("bookName")]
    public string BookName { get; set; }

    [JsonProperty("unit_price")]
    public decimal UnitPrice { get; set; }

    [JsonProperty("quantity")]
    public int Quantity { get; set; }

    [JsonProperty("discount")]
    public decimal Discount { get; set; }

    [JsonProperty("total")]
    public decimal Total { get; set; }
}

In the browser’s network tab, I can see that the request is being sent, but the server responds with a 400 Bad Request.
What I’ve tried:

  1. I’ve made sure the JavaScript is sending the data as JSON.
  2. I tried reading the request body in C# and deserializing it using JsonConvert.DeserializeObject.
  3. I added contentType: ‘application/json’ in the AJAX request.

Potential Issue: I suspect the issue could be related to the way I’m sending the data. In JavaScript, I’m wrapping the array of objects in an object with a data key, but maybe that’s causing issues with how the backend expects the format.

Question:

  • What am I missing here that might be causing the 400 Bad Request?
  • Should I structure the JavaScript request differently or adjust my C# code to handle the incoming data properly?
    Any help would be appreciated!

3

Answers


  1. You’re sending an object with a data key, but the C# code expects a list directly. Update your JavaScript to send the array without wrapping it.

    $.ajax({
        url: '/Index',
        type: 'POST',
        contentType: 'application/json',
        data: JSON.stringify(data),  // No wrapping object
        success: function(result) {
            console.log(result);
        }
    });
    

    You also need to change your method.

    public async Task<IActionResult> OnPostAsync([FromBody] List<OrderData> orders)
        {
            Orders = orders;
    
            foreach (var order in Orders)
            {
                System.Diagnostics.Debug.WriteLine($"Customer: {order.CustomerName}, Book: {order.BookName}, Total: {order.Total}");
            }
    
            return new JsonResult(new { message = "Data received successfully", orders = Orders });
        }
    
    Login or Signup to reply.
  2. I think changing the ajax.data must fix your problem.

    try this :

    $.ajax({
        url: '/Index',
        type: 'POST',
        contentType: 'application/json',
        data: JSON.stringify(data), // just serialize your data object 
        success: function(result) {
            console.log(result);
        }
    });
    

    also you can use

    data: data,
    

    in your ajax options.

    good luck 😉

    Login or Signup to reply.
  3. Generally, the most common cause for a 400 Bad Request status code as below:

    1. Missing/Invalid Anti Forgery Token.
    2. Invalid request data.

    Razor Pages are automatically protected from XSRF/CSRF, so first, please check your razor page, whether it uses the <form> tag helper or not, by default, the following markup in a Razor file automatically generates antiforgery tokens:

    <form method="post">
        <!-- ... -->
    </form>
    

    So, if using the above code in your page, when you submit the Ajax request, you need to add the RequestVerificationToken in the header, like this:

                $.ajax({
                    url: '/OrderIndex',
                    type: 'POST',
                    headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },
                    contentType: 'application/json',
                    data: JSON.stringify(data),  // No wrapping object
                    success: function (result) {
                        console.log(result);
                    }
                });
            })
    

    Or, you can disable the AntiforgeryToken validation, like this:

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

    Second, as Vivek Nuna said, there is no need to wrapping the object and you need a List<OrderData> parameter to receive the pass data.

    Besides, since you are using the JsonProperty to change the names of properties when they are serialized to JSON. I think you want to use Newtonsoft.Json, instead of System.Text.Json (by default, Asp.net core application will use this package). In this scenario, you need to install the Microsoft.AspNetCore.Mvc.NewtonsoftJson package in your application, and configure the serialize service in the Program.cs like this:

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

    Finally, the worked sample code as below:

    Program.cs: disable AntiforgeryToken and configure NewtonsoftJson.

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

    Index.cshtml

    @page
    @model RazorWebApplication3.Pages.OrderIndexModel
    @* <form method="post">
    </form> *@
    <input type="button" id="btnclick" value="Click Me" />
    
    @section Scripts{
        <script>
            $(function () {
                const data = [
                    {
                        "customer_name": "Abdullah Al Mahmud",
                        "mobile": 7654,
                        "bookName": "Physics 1st paper",
                        "unit_price": 250,
                        "quantity": 1,
                        "discount": 0,
                        "total": 250
                    },
                    {
                        "customer_name": "Abdullah Al Mahmud",
                        "mobile": 7654,
                        "bookName": "Physics 1st paper",
                        "unit_price": 250,
                        "quantity": 6,
                        "discount": 0,
                        "total": 1500
                    }
                ];
                $("#btnclick").click(function () {
                    // alert("Heelo");
                    $.ajax({
                        url: '/OrderIndex',
                        type: 'POST',
                        //headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },  //required <form method='post'> or Html.AntiForgeryToken()
                        contentType: 'application/json',
                        data: JSON.stringify(data), // No wrapping object
                        success: function (result) {
                            console.log(result);
                        }
                    });
                })
            });
        </script>
    }
    

    Index.cshtml.cs

    public class OrderIndexModel : PageModel
    {
        [BindProperty]
        public List<OrderData> Orders { get; set; }
    
        public void OnGet()
        {
        }
        //[IgnoreAntiforgeryToken(Order = 1001)]
        public async Task<IActionResult> OnPostAsync([FromBody] List<OrderData> orders)
        {
    
            //using (var reader = new System.IO.StreamReader(Request.Body))
            //{
            //    var body = await reader.ReadToEndAsync();
            //    Orders = JsonConvert.DeserializeObject<List<OrderData>>(body);
            foreach (var order in orders)
            {
                System.Diagnostics.Debug.WriteLine($"Customer: {order.CustomerName}, Book: {order.BookName}, Total: {order.Total}");
            }
            //}
    
            return new JsonResult(new { message = "Data received successfully", orders = Orders });
        }
    }
    

    The result as below:

    test result

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search