Search code examples
c#asp.net-web-apiasp.net-web-api-routing

Route to different actions based on json value


I would like to route requests to different actions based on the value of a particular json parameter.

For example, given the following json data:

{
  type: "type1",
  type1data: "type1value"
}

and

{
  type: "type2",
  type2data: "type2value"
}

I'd like to be able to have 2 different actions on my ApiController:

void CreateType1(string type1data) 
{ 
  // ... 
}

void CreateType2(string type2data) 
{ 
  //... 
}

How can something like this be done?

Update:

I'd like the same URL if possible. Something like /objects/create.


Solution

  • I'd much rather use a custom ApiControllerActionSelector.

    public class MyActionSelector : ApiControllerActionSelector
    {
        public override HttpActionDescriptor SelectAction(
                                    HttpControllerContext context)
        {
            HttpMessageContent requestContent = new HttpMessageContent(
                                                               context.Request);
            var json = requestContent.HttpRequestMessage.Content
                                    .ReadAsStringAsync().Result;
            string type = (string)JObject.Parse(json)["type"];
    
            var actionMethod = context.ControllerDescriptor.ControllerType
                .GetMethods(BindingFlags.Instance | BindingFlags.Public)
                .FirstOrDefault(m => m.Name == "Create" + type);
    
            if (actionMethod != null)
            {
                return new ReflectedHttpActionDescriptor(
                                   context.ControllerDescriptor, actionMethod);
            }
    
            return base.SelectAction(context);
        }
    }
    

    Here is the model. I gave it a weird name of Abc.

    public class Abc
    {
        public string Type { get; set; }
        public string Type1Data { get; set; }
    }
    

    Here is the action method.

    public void Createtype1(Abc a)
    {
    
    }
    

    Finally, plug-in the action selector.

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
    
            config.Services.Replace(typeof(IHttpActionSelector),
                                        new MyActionSelector());
        }
    }
    

    If you now POST to http://localhost:port/api/yourapicontroller, depending on the value in type field in JSON, the action method Create* will be selected.