0

I have this url: /api/v1/books?status=1

status is an optional query parameter and my API controller looks like this.

class BookController : ApiController
{

   [HttpGet]
   public JsonResult GetBooks(Status status)
   {
         // return statement
   }
}

Status is an enum.

public enum Status
{
    None = 0,
    Available = 1,
    NotAvailable = 2,
    Modified = 3
    Deleted = 4
}

Controller accepts 0,1,2,3,4,5,6,7 values, but rejects 8,9,10,11,... values(returns 400 - Bad Request). For the value 5, the controller takes the enum as Available|Deleted (4+1=5) and for the 7(4+3) it takes Modified|Deleted. I want to reject the values that are not in the enum class. How can I handle this?

2
  • If you need bitwise operations on Enums, you must set each enum value to only use one single bit. Right now you could combine Available | NotAvailable and get 3, but 3 means Modified (I understand that Available | NotAvailable are mutually exclusive, but I am trying to make my point). So your values should be None = 0 (0b), Available = 1 (1b), NotAvailable = 2 (10b), Modified = 4 (100b) and Deleted = 8 (1000b). Now back to your question. Change the signature of the method to public JsonResult GetBooks(short status), then with code reject numeric values that represent invalid enum combinations. Commented Oct 8, 2020 at 18:56
  • @Rena Thank you for your answer. I got the point from your answer. Previously I have used [Flag] attribute on enum. So the controller accepts combinations of the enum. So I simply removed the [Flag] attribute and it worked. Commented Nov 9, 2020 at 11:42

1 Answer 1

1

You could add [Flags] attribute on your model.Then you could get the data like Available|Deleted.And add a custom action filter to reject 8,9,10,11... values:

Model:

[Flags]
public enum Status
{
    None = 0,
    Available = 1,
    NotAvailable = 2,
    Modified = 3,
    Deleted = 4      
}

Custom action filter:

public class ValidateModelAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var url = actionContext.Request.RequestUri.Query;
        var list = url.Split('=');
        if (int.Parse(list[list.Length-1])>7)
        {
            actionContext.Response = actionContext.Request.CreateErrorResponse(
                HttpStatusCode.BadRequest,"the enum is invalid");
        }
    }
}

Register action filter in Global.asax:

public static void RegisterWebApiFilters(System.Web.Http.Filters.HttpFilterCollection filters)
{
    filters.Add(new ValidateModelAttribute());
}
protected void Application_Start()
{
    //other services...
    RegisterWebApiFilters(GlobalConfiguration.Configuration.Filters);
}

Result: enter image description here

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.