Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 421
Matt Houser Avatar asked Jan 13 '23 09:01

Matt Houser


1 Answers

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.

like image 187
Badri Avatar answered Jan 22 '23 18:01

Badri