I am currently working on building an API-powered back-end using .Net Core with Windows Authentication. Attempting to POST data to this backend results in a 400 error :
"'noticeNumber=Hello%2C%20world!' is an invalid JSON literal. Expected the literal 'null'. Path: $ | LineNumber: 0 | BytePositionInLine: 1."
The API is currently set up to receive an object containing data on a receipt. One of the properties of this object is an ID for notices generated in other apps. This, and all other properties, are nullable :
// Receipts Controller.
[ApiController]
[Route("receipts")]
public class ReceiptsController : Controller
{
[HttpPost("post_insertReceipt")]
public Task<IActionResult> InsertReceipt(ReceiptForm receipt) {
try {/* ... */}
catch { /* ... */ }
}
}
//Receipt Form VM
public class ReceiptForm
{
public string? NoticeNumber { get; set; }
/*... */
}
The Javascript & jQuery used to call the API look like this :
var data2 = {
noticeNumber: "Hello, world!"
}
$.ajax({
url: "https://localhost:portNumber/receipts/post_insertReceipt",
type: "POST",
xhrFields: {
withCredentials: true
},
contentType: "application/json",
data: data2,
success: function(data) { /* Display success alert */ },
error: function(xhr) { /* display error alert */ }
})
As far as I understand, the syntax for the data object is correct, but something clearly disagrees. I have attempted to post null as data, only to get an error for for having posted any data.
So then, why is the expected literal 'null'? What determines the expected literal, why, and how do I fix this issue?
@DavidG's comment on the main post reveals my mistake. APIs communicate with objects that have been serialized into JSON strings.
My prior experience with non-API-based MVC had led me to to conclude that I could just pass the Javascript object into the $.ajax's data field as can be done - that is not the case.
Data must be parsed into a serialized JSON string with JSON.Stringify() in order to be processed by the API properly.
$.ajax({
url: "https://localhost:portNumber/receipts/post_insertReceipt",
type: "POST",
xhrFields: {
withCredentials: true
},
contentType: "application/json",
data: JSON.stringify(data2),
success: function(data) { /* Display success alert */ },
error: function(xhr) { /* display error alert */ }
})