Yusuf Y.
Yusuf Y.

Reputation: 71

XML Parsing Error: no root element found in ASP.NET Core 2.0 API

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

Answers (3)

Shahin Dohan
Shahin Dohan

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

mmr
mmr

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 DELETEcall, 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

Umar Karimabadi
Umar Karimabadi

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

Related Questions