20

I have an ASP.NET Core OData Web API with an endpoint that returns the following:

{
    "@odata.context": "https://localhost:44305/odata/$metadata#OrgUnits",
    "@odata.count": 3,
    "value": [
        {
            "Status": "Active",
            "OperationMode": "Normal",
            "BaseUrl": "https://test.nl/",
            "OrgUnitCode": "TEST",
            "Name": "Test",
            "Address": "Spoorlaan 348",
            "PostalCode": "5038 CC",
            "City": "Tilburg",
            "PhoneNumber": "012 345 6789",
            "ChamberOfCommerceNumber": null,
            "ContactName": null,
            "Website": null,
            "EmailAddress": null,
            "Id": 1,
            "DateCreated": "0001-01-01T00:00:00Z",
            "LastModifiedDate": "0001-01-01T00:00:00Z"
        },

Status and OperationMode are enums:

    public enum OperationMode
    {
        Inherited = 0,
        Normal = 1,
        Test = 2
    }
    public enum Status
    {
        Inherited = 0,
        Active = 1,
        Inactive = 2
    }
    public class OrgUnit : BaseEntity
    {
        public Status Status { get; set; }
        
        public OperationMode OperationMode { get; set; }
        
        public string BaseUrl { get; set; }
        
        public string OrgUnitCode { get; set; }
        
        public string Name { get; set; }
        
        public string Address { get; set; }
        
        public string PostalCode { get; set; }
        
        public string City { get; set; }
        
        public string PhoneNumber { get; set; }
        
        public string ChamberOfCommerceNumber { get; set; }
        
        public string ContactName { get; set; }
        
        public string Website { get; set; }
        
        public string EmailAddress { get; set; }
    }

On my frontend, a Blazor Server application, I deserialize the response body into an OrgUnitsResponse object. This response object will be used to fill a Telerik Grid component.

        public async Task<OrgUnitsResponse> GetOrgUnits(DataSourceRequest request)
        {
            var baseUrl = "https://localhost:44305/odata/OrgUnits?";

            var requestUrl = $"{baseUrl}{request.ToODataString()}";

            var requestMessage = new HttpRequestMessage(HttpMethod.Get, requestUrl);
            requestMessage.Headers.Add("Accept", "application/json");
            var client = HttpClient.CreateClient();
            var response = await client.SendAsync(requestMessage);

            if (response.IsSuccessStatusCode)
            {
                var body = await response.Content.ReadAsStringAsync();
                var oDataResponse = JsonSerializer.Deserialize<OrgUnitsResponse>(body);
                return oDataResponse;
            }
            else
            {
                throw new HttpRequestException(
                    "Request failed. I need better error handling, e.g., returning empty data.");
            }
        }
    public class OrgUnitsResponse
    {
        [System.Text.Json.Serialization.JsonPropertyName("value")]
        public List<OrgUnit> OrgUnits { get; set; }
        
        [System.Text.Json.Serialization.JsonPropertyName("@odata.count")]
        public int Total { get; set; }
    }

Sadly, this doesn't seem to work. I get the following error:

System.Text.Json.JsonException: The JSON value could not be converted to Domain.Enums.Status. Path: $.value[0].Status 

How can I correctly deserialize the JSON string values into enums?

3 Answers 3

47

Already figured out the answer 1 minute after asking this question. Leaving it up there so anyone else experiencing this issue can read this.

The solution is passing a JsonStringEnumConverter as an option to the serializer.

var options = new JsonSerializerOptions();
options.Converters.Add(new JsonStringEnumConverter());
var oDataResponse = JsonSerializer.Deserialize<OrgUnitsResponse>(body, options);

Please also note that when using a JsonSerializerOptionsclass you may also need to specify a JsonSerializerDefaults option:

var options = new JsonSerializerOptions(JsonSerializerDefaults.Web);
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks - this fixed my issue but the odd thing is that some enums don't need it.
19

If you are using DTO classes for transport make sure the enum property has this attribute

[JsonConverter(typeof(JsonStringEnumConverter))]

Comments

0

I hade the same error but with the JsonConverter attached already. In my case I needed to add this to the Json options.

My properties are standard casing. E.g. Address but the returned json was camel cased. E.g. address.

JsonSerializerOptions options = new JsonSerializerOptions
{
    PropertyNameCaseInsensitive = true
};

Comments

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.