ardalis / ardalis/SmartEnum

SmartEnum not deserialized as path parameter

Open
#339 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
C#
Stars
2.4k
Forks
184
PR merge metrics
No merged PRs in 30d

Description

I have a controller that uses SmartEnum as a path parameter:
```
[HttpGet]
[Route("{clientApiIdentifier}/FilterListSmart/{columnId}")]
public async Task> GetFilterListSmart(
[FromRoute] string clientApiIdentifier,
[FromRoute] FormsReportColumnsSmart columnId)
```
When I call my controller it doesn't deserialize the value for columnId. columnId is always "Unknown".
example call:
```{{ReportingApiUrl}}/Forms/{{clientId}}/FilterListSmart/CandidateId```

I tried a test case calling deseriallize on a string and ```"AssignedTo"``` works but ```AssignedTo``` doesn't. Am I missing something? or is this an issue?

Initially I got errors from MVC binding for abstract class and parameterless constructor needed. I ended up with this class:
```
[JsonConverter(typeof(SmartEnumValueConverter))]
public class FormsReportColumnsSmart : SmartEnum
{
public static readonly FormsReportColumnsSmart CandidateId = new CandidateIdCol();
public static readonly FormsReportColumnsSmart FormattedName = new FormattedNameCol();
public static readonly FormsReportColumnsSmart UserApiIdentifier = new UserApiIdentifierCol();
public static readonly FormsReportColumnsSmart ProcessFlowName = new ProcessFlowNameCol();
public static readonly FormsReportColumnsSmart FormName = new FormNameCol();
public static readonly FormsReportColumnsSmart FormType = new FormTypeCol();
public static readonly FormsReportColumnsSmart FormStatus = new FormStatusCol();
public static readonly FormsReportColumnsSmart FormStatusSort = new FormStatusSortCol();
public static readonly FormsReportColumnsSmart FormDueDate = new FormDueDateCol();
public static readonly FormsReportColumnsSmart CompletionDate = new CompletionDateCol();
public static readonly FormsReportColumnsSmart FormStatusIdentifier = new FormStatusIdentifierCol();
public static readonly FormsReportColumnsSmart AssignedTo = new AssignedToCol();
public static readonly FormsReportColumnsSmart AssignedToId = new AssignedToIdCol();
public static readonly FormsReportColumnsSmart RowId = new RowIdCol();
public static readonly FormsReportColumnsSmart Unknown = new UnknownIdCol();
private FormsReportColumnsSmart(string name, int value) : base(name, value)
{
}
public FormsReportColumnsSmart() : base(nameof(Unknown), 1)
{
}
public FormsReportColumnsSmart(string name) : base(name, 1)
{
}
private sealed class UnknownIdCol : FormsReportColumnsSmart
{
public UnknownIdCol() : base(nameof(Unknown), 1)
{
}
}

private sealed class CandidateIdCol : FormsReportColumnsSmart
{
public CandidateIdCol() : base(nameof(CandidateId), 1)
{
}
}
private sealed class FormattedNameCol : FormsReportColumnsSmart
{
public FormattedNameCol() : base(nameof(FormattedName), 2)
{
}
}
private sealed class UserApiIdentifierCol : FormsReportColumnsSmart
{
public UserApiIdentifierCol() : base(nameof(UserApiIdentifier), 3)
{
}
}
private sealed class ProcessFlowNameCol : FormsReportColumnsSmart
{
public ProcessFlowNameCol() : base(nameof(ProcessFlowName), 4)
{
}
}
private sealed class FormNameCol : FormsReportColumnsSmart
{
public FormNameCol() : base(nameof(FormName), 5)
{
}
}
private sealed class FormTypeCol : FormsReportColumnsSmart
{
public FormTypeCol() : base(nameof(FormType), 6)
{
}
}
private sealed class FormStatusCol : FormsReportColumnsSmart
{
public FormStatusCol() : base(nameof(FormStatus), 7)
{
}
}
private sealed class FormStatusSortCol : FormsReportColumnsSmart
{ public FormStatusSortCol() : base(nameof(FormStatusSort), 8)
{
}
}
private sealed class FormDueDateCol : FormsReportColumnsSmart
{
public FormDueDateCol() : base(nameof(FormDueDate), 9)
{
}
}
private sealed class CompletionDateCol : FormsReportColumnsSmart
{
public CompletionDateCol() : base(nameof(CompletionDate), 10)
{
}
}
private sealed class FormStatusIdentifierCol : FormsReportColumnsSmart
{
public FormStatusIdentifierCol() : base(nameof(FormStatusIdentifier), 11)
{
}
}
private sealed class AssignedToCol : FormsReportColumnsSmart
{
public AssignedToCol() : base(nameof(AssignedTo), 12)
{
}
}
private sealed class AssignedToIdCol : FormsReportColumnsSmart
{
public AssignedToIdCol() : base(nameof(AssignedToId), 13)
{
}
}
private sealed class RowIdCol : FormsReportColumnsSmart
{
public RowIdCol() : base(nameof(RowId), 14)
{
}
}

}
```

Contributor guide

Open the contributing guide

Research direction

Start with SmartEnumValueConverter and the FormsReportColumnsSmart type shown in the issue, then trace how the ASP.NET controller binds the {columnId} route value. Reproduce the CandidateId request and compare it with deserialization of quoted and unquoted values. Done means the CandidateId path value binds to FormsReportColumnsSmart.CandidateId instead of Unknown, with a regression test covering route binding.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
api, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.