I want a user to be able to query GET /api/mycontroller?enums=ABC
without using commas for the enums parameter. I know I can pass a comma separated parameter but using it without commas returns 'ABC' is not a valid value for type MyEnum
. In my database, this field is stored as combination of characters without a comma. Is there a custom model binding attribute I can use and add it to the EnumVal
property in MyRequest
?
public enum MyEnum
{
A=1,
B=2,
C=4
}
public class MyRequest
{
public MyEnum EnumVal {get; set;}
}
[HttpGet("mycontroller")]
public async Task<ActionResult> MyController([FromQuery] MyRequest request)
{
//query db for row containing resuest.myEnum string combination...
// ...
}
I've looked into overriding the ValidationAttribute
but it still returns an error response.
I was able to figure it out using a custom model binder
public class MyEnumTypeEntityBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
var modelName = bindingContext.ModelName;
// Try to fetch the value of the argument by name
var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);
if (valueProviderResult == ValueProviderResult.None)
{
return Task.CompletedTask;
}
int len = valueProviderResult.FirstValue.Length;
string query = valueProviderResult.FirstValue;
char[] charlist = query.ToCharArray( );
string enumConversionString = string.Join(",", charlist);
if (!Enum.TryParse(enumConversionString, out MyEnum model))
{
bindingContext.ModelState.TryAddModelError(modelName, string.Format("{0} is not a valid value for type {1}", valueProviderResult.FirstValue, modelName));
return Task.CompletedTask;
}
bindingContext.Result = ModelBindingResult.Success(model);
return Task.CompletedTask;
}
}
and adding the attribute above the MyEnum request prop:
[ModelBinder(BinderType = typeof(MyEnumTypeEntityBinder))]
public MyEnum? Type { get; set; }
public enum MyEnum
{
A=1,
B=2,
C=4
}