5

I am creating an ASP.NET Core Web API.

I want a post body like:

{
"Name": "XYX",
"Status":"Waiting"
}

Status is an Enum:

public enum Status
{
    [Description("Waiting")]
    Waiting = 1,
    [Description("Occuring")]
    Occuring = 2,
    [Description("Stopping")]
    Stopping = 3,
}

What should I do so I that I don't get the error:

The JSON value could not be converted to PostgreSql.Enums.StatusEnum. Path:

P.S.: Tried what's mentioned here but it didn't work for me.

Mansi
  • 313
  • 1
  • 5
  • 10
  • 1
    Try using `System.Text.Json` attributes: [JsonStringEnumConverter](https://learn.microsoft.com/en-us/dotnet/api/system.text.json.serialization.jsonstringenumconverter?view=netcore-3.1) and [JsonConverterAttribute](https://learn.microsoft.com/en-us/dotnet/api/system.text.json.serialization.jsonconverterattribute?view=netcore-3.1) – Guru Stron May 05 '20 at 10:49
  • Aslo please add your model/json parsing code. – Guru Stron May 05 '20 at 10:50
  • 1
    Does this answer your question? [Convert a string to an enum in C#](https://stackoverflow.com/questions/16100/convert-a-string-to-an-enum-in-c-sharp) – Crowcoder May 05 '20 at 11:06
  • @GuruStron I tried `[JsonConverter(typeof(JsonStringEnumConverter))]` and it worked well for me. – Mansi May 05 '20 at 11:17
  • Will add as an answer. – Guru Stron May 05 '20 at 11:17

5 Answers5

9

ASP.NET in .NET Core 3.0 removed the JSON.NET(Newtonsoft.Json) dependency (it is used in the link you've provided), so try using System.Text.Json's attributes: JsonStringEnumConverter and JsonConverterAttribute.

UPD Was not able to reproduce the issue you mentioned in the comment:

class MyClass
{    
    [JsonConverter(typeof(JsonStringEnumConverter))]
    public Status MyProperty { get; set; }

    [JsonConverter(typeof(JsonStringEnumConverter))]
    public Status MyProperty1 { get; set; }
}

var serialized = JsonSerializer.Serialize(new MyClass
{
    MyProperty = Status.Waiting,
    MyProperty1 = Status.Occuring
}); // results in string containing {"MyProperty":"Waiting","MyProperty1":"Occuring"}

var result = JsonSerializer.Deserialize<MyClass>(serialized); // all properties set

Also please note that name of the Status value is used for serialization/deserialization not the value of Description attribute.

Guru Stron
  • 102,774
  • 10
  • 95
  • 132
  • 1
    I see that it worked in the case mentioned in my question, but strangely isn't working for another similar parameter I'm trying to add. What could be the reason? – Mansi May 05 '20 at 12:26
  • **EDIT:** For `Description("Waiting")] Waiting = 1,` the post body is taking "waiting" for one param and 1 for another, why is that? – Mansi May 05 '20 at 12:33
  • 1
    @Mansi It is not enough information, please add the class and json. – Guru Stron May 05 '20 at 12:45
3

You can create an enum as follows:

[JsonConverter(typeof(StringEnumConverter))]
public enum Status : byte
{
    Waiting = 1,
    Occuring = 2,
    Stopping = 3
}

& pass string value in POST body

Sagar Vaja
  • 164
  • 3
1

For record (which in C# is a class or struct that provides special syntax and behavior for working with data models) and it's fields it is necessary to add [property: JsonConverter(typeof(JsonStringEnumConverter))] like below in the code:

internal record ShipmentBookingStatusModel
(
    int ShipmentId
    , string OtmShipmentId
    , [property: JsonConverter(typeof(JsonStringEnumConverter))] OtmBookingStatusEnum BookingStatus
){ }
Jerzy Gebler
  • 929
  • 9
  • 13
0

Is there a reason your post body is being passed the description as opposed to the enum value? If this is enum is part of the API scheme/definition then anything that consumes should know about it too therefore the API could be called with the integer value like:

{
"Name": "XYX",
"Status":1
}

I know its not an exact solution to what you asked but it's an alternative and may be worth thinking about?

jjharrison
  • 841
  • 4
  • 19
  • 33
0

You can add following code in your Statup.cs/Program.cs to set it globally for the project.

builder.Services.AddControllers().AddJsonOptions(x =>{
// serialize enums as strings in api responses (e.g. Role)
x.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());});
Himal Patel
  • 387
  • 4
  • 19