22

When I debug the code in VS, the cities list, which I am returning have 3 objects in it along with the properties. When I call this endpoint I am receiving a response of 3 list items of empty objects.

How to resolve this issue?

Model Class:

public class City
{
    public string CityName;
    public string AssociatedCities; 
    public string Province;
    public int Status;

    public City(string cityName, string associatedCities, string province, int status)
    {
        this.CityName = cityName;
        this.AssociatedCities = associatedCities;
        this.Province = province;
        this.Status = status;
    }
}

Endpoint:

[HttpGet]
[Route("cities")]
public ActionResult<IEnumerable<City>> GetCities()
{
    return Ok(Cities);
}

This is how I am calling the endpoint

getCities() {
  this.http.get<City[]>('/api/wizard/cities')
  .subscribe(result => {
    console.log(result);
    this.cities = result;
  }, error => console.error('Something went wrong : ' + error));
}

The response I get: Reponse Result

The response that is needed:

[
  {
    "SearchCity": "Toronto",
    "AssociatedCities": "Ajax, Whitby, Toronto, Mississauga, Brampton",
    "Province": "ON",
    "Status": 1
  },
  {
    "SearchCity": "Vancouver",
    "AssociatedCities": "Vancouver, Vancouver City",
    "Province": "BC",
    "Status": 1
  }
]

I have tried this already: Fresh ASP.NET Core API returns empty JSON objects

6
  • 3
    Please add your definition of Cities. Commented Jan 13, 2020 at 10:47
  • do you have public City() constructor? Please add default constructor and try one more time public City() {} Commented Jan 13, 2020 at 10:49
  • Thanks will update it now. Commented Jan 13, 2020 at 10:49
  • 14
    The JSON serialiser doesn't support fields - use properties. i.e. public string CityName { get; set; } etc. Commented Jan 13, 2020 at 10:51
  • 1
    Thanks @KirkLarkin worked for me. Newbie here that' why made the mistake. Thanks again. Commented Jan 13, 2020 at 10:56

3 Answers 3

21

System.Text.Json currently does not support serialization/deserialization of fields and non-parameter-less, non-default constructors.

Your example model uses both fields and a non-default constructor. If you need to use a custom constructor for some reason, you would need to implement your own JsonConverter<T> to support that. This doc might be helpful for that: https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-migrate-from-newtonsoft-how-to#deserialize-to-immutable-classes-and-structs

Only public properties with public getters/setters are supported along with the default, parameter-less constructor (what is referred to as Plain_old_CLR_object (POCO)). Note: If you are only serializing (i.e. writing), the setters generally don't have to be public.

Properties are different from fields (and contain getters/setters).

Here is the fix:

public class City
{
    public string CityName { get; set; }
    public string AssociatedCities { get; set; }
    public string Province { get; set; }
    public int Status { get; set; }
}
Sign up to request clarification or add additional context in comments.

Comments

14

In my case, I just added this in my ConfigureServices method in Startup.cs (I am using Dot Net 5.0)

services.AddControllers().AddNewtonsoftJson();

3 Comments

It works for me. I've to add package: Microsoft.AspNetCore.Mvc.NewtonsoftJson
I am using .net 6, same issue, and there is no Startup.cs, also no ConfigureServices method in the entire REST server project...
@JayImerman or for anyone having this issue .... get this nuget package Microsoft.AspNetCore.Mvc.NewtonsoftJson (choose your ,net supported version) andservices.AddControllers().AddNewtonsoftJson(); in your program file
6

Based on the fact that all your action does is return Cities, which presumably is a property or field defined on your controller, I'm going to take a shot in the dark and assume that you're setting that in another request and expecting it to still be there in this request. That's not how it works. The controller is instantiated and disposed with each request, so anything set to it during the lifetime of a request will not survive. As a result, Cities has nothing in this request, so you get an empty response.

If you need a list of cities in the action, then you should query those in that action. Also, for what it's worth, System.Text.Json does not currently support serializing fields, as others have mentioned in the comments, but you may still use JSON.NET instead, which does. See: https://learn.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-3.1&tabs=visual-studio#jsonnet-support

1 Comment

Thanks for your valuable time. The cities were setting up in the same request. As suggested by @krik Larkin and you as well i simply changed fields to properties like public string cityname to public string cityname {get; set;} and it worked.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.