Reputation: 71
I've encountered this problem, and I couldn't figure it out. I'm using ASP.NET Core 2 and Ajax.
This is what the JavaScript debugger says:
XML Parsing Error: no root element found Location: http://localhost:52617/api/favorites/ Line Number 1, Column 1:
This is my JavaScript code:
$(".js-toggle-fav").click(function (e) {
function sendPost() {
console.log("inside post send");
var button = $(e.target);
$.ajax({
type: 'POST',
url: "http://localhost:52617/api/Favorites/",
data: {"EventId": @Model.Event.EventId},
contentType: "application/json; charset=utf-8"
});
}
$.getJSON("http://localhost:52617/api/favorites/@Model.Event.EventId", function (data) {
if (data == null) {
console.log("fav is null");
sendPost();
fav.addClass(toggling);
fav.text("unfav");
}
else {
console.log("fav is NOT null");
sendPost();
fav.removeClass(toggling);
fav.text("fav");
}
);
});
And my API:
[HttpPost]
public async Task<IActionResult> PostFavorite([FromBody] FavoriteDto favorite)
{
if (!ModelState.IsValid)
{
Console.WriteLine(ModelState.ValidationState.ToString());
return BadRequest(ModelState);
}
var uid = _userManager.GetUserId(HttpContext.User);
var fav = await _context.Favourites.SingleOrDefaultAsync(x => x.EventId == favorite.EventId && x.UserId == uid);
if (fav == null)
{
_context.Favourites.Add(new Favorite { EventId = favorite.EventId, UserId=uid });
}
else
{
_context.Favourites.Remove(fav);
}
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateException)
{
if (FavoriteExists(favorite.EventId))
{
return new StatusCodeResult(StatusCodes.Status409Conflict);
}
else
{
throw;
}
}
return Ok(favorite);
}
When I do this with Postman or any restclient, everything works like a charm! With Ajax, that's not the case.
NOTES:
- In the same
.cshtml
file, there's more jQuery and JavaScript code which does something like this, and it's just working! All the solutions I've checked on the internet didn't work, unfortunately.- The Get methods (for returning List, or single element are working!)
Upvotes: 1
Views: 6973
Reputation: 6922
To add to the other answers, this error can also happen if jQuery ajax gets an empty string response where it expects valid JSON, or no content at all.
Check the value of the data
in the done
callback, if it's an empty string ""
rather than undefined
, you'll have to fix your server to return status code 204 (No Content)
instead of an 200 (OK)
with no content.
In WebAPI2 this would mean returning StatusCode(HttpStatusCode.NoContent)
instead of Ok()
.
Upvotes: 2
Reputation: 383
I encountered this error during a DELETE
call to an ASP.Net Core 2.1 Web API. I removed the [FromBody]
from the model that was expected from the DELETE
call, such as
public async Task<IActionResult> Delete(MyModel body)
{
// Just an example
await DoSomeWork(body);
return StatusCode(200);
}
but that did not solve the problem. However, after I returned some content with StatusCode
, in this example just a simple string, the error was gone. So the following code should avoid the error in Firefox:
public async Task<IActionResult> Delete(MyModel body)
{
// Just an example
await DoSomeWork(body);
return StatusCode(200, "Deletion Successfull");
}
Upvotes: 2
Reputation: 980
The problem is coming from
data: {"EventId": @Model.Event.EventId},
Instead of passing it in directly, use JSON.Stringify
var payload = {EventId: @Model.Event.EventId};
$.ajax({
type: 'POST',
url: "http://localhost:52617/api/Favorites/",
data: JSON.stringify(payload),
contentType: "application/json; charset=utf-8"
});
I'm assuming your FavoriteDto class looks something like this
public class FavoriteDto
{
public int EventId { get; set; }
}
The reason why you were getting an xml error is that the controller action
public async Task<IActionResult> PostFavorite([FromBody] FavoriteDto favorite)
could not parse 'favorite' so it was never initialised and was null. You then return ok(null) which caused a parsing error on your client side ajax when it recieved the response back from your server.
Upvotes: 2