Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling string enum OnRead #510

Closed
ShiiniiDev opened this issue Jan 14, 2025 · 6 comments
Closed

Handling string enum OnRead #510

ShiiniiDev opened this issue Jan 14, 2025 · 6 comments
Labels
status:waiting-for-author-feedback Issue that we've responded but needs author feedback to close type:question An issue that's a question

Comments

@ShiiniiDev
Copy link

ShiiniiDev commented Jan 14, 2025

Using Kiota I got generated

// I've cleaned pragma
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
public enum MyEnum
{
    [EnumMember(Value = "A")]
    A,
    [EnumMember(Value = "B")]
    B,
}

On writing it works well, it will be written "myEnum": "A"
On reading, it fails

// System.Text.Json.Serialization.Converters.EnumConverter

if ((_converterOptions & EnumConverterOptions.AllowStrings) == 0)
{
    ThrowHelper.ThrowJsonException();
    return default;
}

The _converterOptions is set to AllowInteger, so it throws

Here my Http setup

var httpClient = new HttpClient(handler)
{
    BaseAddress = new Uri(_api.ConnectionString),
};

var requestAdapter =
    new DefaultRequestAdapter(
        new BaseBearerTokenAuthenticationProvider(new MyTokenProvider()),
        httpClient: httpClient);

ApiClient = new KiotaApiClient(requestAdapter)

I dont know if I'm able to inject/use a specific json serializer like JsonNet, or custom something.. I didnt find anything relevant to help me.
Or if I've missed a step/a detail

@github-project-automation github-project-automation bot moved this to Needs Triage 🔍 in Kiota Jan 14, 2025
@baywet
Copy link
Member

baywet commented Jan 14, 2025

Hi @ShiiniiDev
Thank you for using kiota and for reaching out.

This is one of the very few design assumptions that kiota has had since its genesis. Enums are serialized as strings (or array of strings depending on the scenario)

Do you have the ability to turn on string serialization for enums in your API?

@baywet baywet added status:waiting-for-author-feedback Issue that we've responded but needs author feedback to close type:question An issue that's a question labels Jan 14, 2025
@baywet baywet moved this from Needs Triage 🔍 to Waits for author 🔁 in Kiota Jan 14, 2025
@ShiiniiDev
Copy link
Author

Hey @baywet

Do you have the ability to turn on string serialization for enums in your API?

On my API point of view I've this setup

.AddNewtonsoftJson(options =>
{
    options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
    options.SerializerSettings.MissingMemberHandling = MissingMemberHandling.Error;
    options.SerializerSettings.Converters.Add(new StringEnumConverter());
    options.SerializerSettings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
});

Which will respond, as I expect

"myEnum": "A"

To provide more context the DTO looks like

// I've cleaned pragma
public partial class MyDto : global::Models.MyBaseDto {
     public global::Models.MyEnum? MyEnum { get; set; }
}

But when Kiota receives the message "myEnum": "A" by the API the json serializer wants to read an integer instead of a string.
So I wonder if there is any way to inject in Kiota Json.Net or StringEnumConverter or I don't know..

Thanks for your time

@microsoft-github-policy-service microsoft-github-policy-service bot added Needs: Attention 👋 and removed status:waiting-for-author-feedback Issue that we've responded but needs author feedback to close labels Jan 14, 2025
@baywet
Copy link
Member

baywet commented Jan 14, 2025

Thank you for the additional information.

Can you please share the OpenAPI description section for the enum?
As well as the GetFieldDeserializers method body for the class that has the enum property.

@baywet baywet added status:waiting-for-author-feedback Issue that we've responded but needs author feedback to close and removed Needs: Attention 👋 labels Jan 14, 2025
@ShiiniiDev
Copy link
Author

Can you please share the OpenAPI description section for the enum?

// in my DTO
"myEnum": {
  "$ref": "#/components/schemas/MyEnum"
}

// omitted

"MyEnum": {
  "enum": [
    "A",
    "B"
  ],
  "type": "string"
}

As well as the GetFieldDeserializers method body for the class that has the enum property.

public override IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
    return new Dictionary<string, Action<IParseNode>>(base.GetFieldDeserializers())
    {
        { "myEnum", n => { MyEnum = n.GetEnumValue<global::Models.MyEnum>(); } },
    };
}

Hoping it will help

@microsoft-github-policy-service microsoft-github-policy-service bot added Needs: Attention 👋 and removed status:waiting-for-author-feedback Issue that we've responded but needs author feedback to close labels Jan 14, 2025
@baywet
Copy link
Member

baywet commented Jan 14, 2025

Thank you for the additional information.

Yes, that effectively maps to a GetStringValue from System.Text.Json

var rawValue = _jsonNode.GetString();

So what I believe is happening is that API actually returns numerical values for some reason.

Can you double check the returned payload from the API please?

@baywet baywet added status:waiting-for-author-feedback Issue that we've responded but needs author feedback to close and removed Needs: Attention 👋 labels Jan 14, 2025
@ShiiniiDev
Copy link
Author

@baywet Thanks for this message you pointed it out my mistake, because JsonParseNode wasnt called in my case.

I wanted to get the API error message, in order to throw/fail the test in proper way

So I was using Text.Json instead of Json.Net

MyResponseHandler : IResponseHandler {

public async Task<ModelType?> HandleResponseAsync<NativeResponseType, ModelType>(NativeResponseType response,
        Dictionary<string, ParsableFactory<IParsable>>? errorMappings)
    {
         // omitted code
          return await httpResponseMessage.Content.ReadFromJsonAsync<ModelType>(); // Not good for my enum...
    }
}

@github-project-automation github-project-automation bot moved this from Waits for author 🔁 to Done ✔️ in Kiota Jan 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status:waiting-for-author-feedback Issue that we've responded but needs author feedback to close type:question An issue that's a question
Projects
Status: Done ✔️
Development

No branches or pull requests

2 participants