Search code examples
c#asp.net-coreblazor-server-side.net-5

API result not deserializing as expected


I am building a blazor web app that is talking to a .NET 5 API.

I am getting deserialization errors and i believe the reason is because the object being returned is not exactly like the object I have defined.

class is as follows:

public class Location
{
    [Key]
    public Guid Id { get; set; }

    [Required]
    public Guid WorkspaceID { get; set; }

    [Required]
    public string Name { get; set; }

    public string ImagePath { get; set; }

    public ICollection<Floor> Floors { get; set; }
}

API:

 [HttpGet]
        public IActionResult GetAllLocations()
        {
            return Ok(_locationManagementRepository.GetAllLoacations());
        }

Data Access method:

public async Task<IEnumerable<Location>> GetAllLoacations()
        {
            var locations = new [] {
                new Location{Id = Guid.NewGuid(), Name = "Location 1", WorkspaceID = Guid.NewGuid(),Floors = null, ImagePath = null},
                new Location{Id = Guid.NewGuid(), Name = "Location 2", WorkspaceID = Guid.NewGuid(),Floors = null, ImagePath = null},
                new Location{Id = Guid.NewGuid(), Name = "Location 3", WorkspaceID = Guid.NewGuid(),Floors = null, ImagePath = null}
            };
            return await Task.FromResult(locations);
        }

Blazor service that queries API:

 public async Task<IEnumerable<Location>> GetAllLocations()
        {
            _httpClient.SetBearerToken(await _tokenManager.RetrieveAccessTokenAsync());

            return await JsonSerializer.DeserializeAsync<List<Location>>
                (await _httpClient.GetStreamAsync($"api/location"),
                new JsonSerializerOptions() { PropertyNameCaseInsensitive = true });
        }

the JSON returned to this methos is as follows:

{"result":[{"id":"e029e1cb-3ea2-4b2c-acae-5e693d2ece46","workspaceID":"985f2695-f36e-4481-9b7c-b1e00bbb4ac3","name":"Location 1","imagePath":null,"floors":null},{"id":"c4ccb92b-9cc8-4e08-bba3-22f61c1fe7e5","workspaceID":"67d05f55-5bd4-4e8f-93b3-b3daa9155535","name":"Location 2","imagePath":null,"floors":null},{"id":"a42073da-239d-428e-a318-d3dc7cfd221b","workspaceID":"d3a14500-ddcd-486f-a96e-5c86373c092d","name":"Location 3","imagePath":null,"floors":null}],"id":2,"exception":null,"status":5,"isCanceled":false,"isCompleted":true,"isCompletedSuccessfully":true,"creationOptions":0,"asyncState":null,"isFaulted":false}

The error I get is:

JsonException: The JSON value could not be converted to System.Collections.Generic.List

What is the correct way to go about handing this to deserialize the data so I can pass it onto my Blazor component? Do I need to create a view model that has a single result property defined as a List or am I missing something in my API/Blazor application that will make this just work!


Solution

  • I managed to get to the bottom of it, the problem was at the API Level, I was returning an IAction result instead of a Task once I changed the method return type everything started working!

    Old:

    [HttpGet]
            public IActionResult GetAllLocations()
            {
                return Ok(_locationManagementRepository.GetAllLoacations());
            }
    

    New:

    [HttpGet]
            public Task<IActionResult> GetAllLocations()
            {
                return Ok(_locationManagementRepository.GetAllLoacations());
            }