Using with FastEndpoints
MarkLFT opened this issue · 2 comments
I like the idea of SmartEnums, but I am unable to find a straightforward way to make them work with FastEndpoints. Although the projects builds, when I try to pass a Dto that contains a SmartEnum, an error is thrown with regards to being unable to deserialise the Dto, and the error points to the SmartEnum.
Has anyone found a simple or straightforward way to do this?
I have noticed on both this and the FastEndPoints Githubs that there are several posts regarding this combination causing issues, but none seem to provide a clean solution.
@ardalis I notice you seem to favour FastEndpoints, so perhaps you have a project or something you could share on how to use them together. Thanks
We are using SmartEnum with FastEndpoints
we have an enum for sort order
public sealed class SortOrder : SmartEnum<SortOrder, string>
{
public static readonly SortOrder Asc = new(nameof(Asc), nameof(Asc));
public static readonly SortOrder Desc = new(nameof(Desc), nameof(Desc));
/// <summary>Gets an item associated with the specified value. Parses SmartEnum when used as query params</summary>
/// <see href="https://github.com/ardalis/SmartEnum/issues/410#issuecomment-1686057067">this issue</see>
/// <param name="value">The value of the item to get.</param>
/// <param name="result">
/// When this method returns, contains the item associated with the specified value, if the value is found;
/// otherwise, <c>null</c>. This parameter is passed uninitialized.</param>
/// <returns>
/// <c>true</c> if the <see cref="SortOrder" /> contains an item with the specified name; otherwise, <c>false</c>.
/// </returns>
public static bool TryParse(string value, out SortOrder result)
{
return TryFromValue(value, out result);
}
private SortOrder(string name, string value) : base(name, value)
{
}
}
register the converters for your smart enums
app.UseFastEndpoints(x =>
{
x.Errors.UseProblemDetails();
x.Endpoints.Configurator = ep =>
{
ep.PreProcessor<CurrentUserInjector>(Order.Before);
};
...
x.Serializer.Options.Converters.Add(new SmartEnumValueConverter<SortOrder, string>());
...
x.Serializer.Options.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
});
Decorate the property in your request (it might work without JsonConverter if it is in the body of POST/PUT)
public class BaseSortPaginatedRequest
{
[QueryParam]
[JsonConverter(typeof(SmartEnumNameConverter<SortOrder, string>))]
public SortOrder? SortOrder { get; set; }
}
Decorate with [JsonConverter(typeof(SmartEnumNameConverter<SortOrder, string>))]
the responses as well.
@idormenco Thanks for the feedback. I came across this also. I have added a pull request to update the documents to show this is needed for System.Text.Json also, and not just with Newtonsoft which is what the documentation implies.