Question

I'm replacing some old webservice code with WebApi, and I've got a situation where the code used to do something like this:

If Request.QueryString("value") = 1 Then
    {do first action}
Else
    {do second action}
End If

Each action is totally different, and each has an independent set of other query string parameters.

In my new version, I'm modelling this as:

Public Function FirstAction(model as FirstActionModel) As HttpResponseMessage

and

Public Function SecondAction(model as SecondActionModel) As HttpResponseMessage

The catch is that the incoming request is going to just call /api/actions?actiontype=1&params... or /api/actions?actiontype=2&params... and the params are different.

I want to be able to route a request with actiontype=1 to FirstAction, and actiontype=2 to SecondAction. But I can't use routing, because the important value is in the query string, not the path.

How can I do this?

Was it helpful?

Solution

As i've mentioned in comments you can use IHttpActionSelector to achieve this. But instead of implementing interface directly you can inherit from default implementation.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Http.Controllers;

namespace WebApplication1
{
    public class CustomHttpActionSelector : ApiControllerActionSelector 
    {
        public override HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
        {
            var urlParam = HttpUtility.ParseQueryString(controllerContext.Request.RequestUri.Query);
            var actionType = urlParam["actiontype"];
            if (actionType == null)
                return base.SelectAction(controllerContext);

            MethodInfo methodInfo;
            if (actionType.ToString() == "1")
                methodInfo = controllerContext.ControllerDescriptor.ControllerType.GetMethod("Action1");
            else
                methodInfo = controllerContext.ControllerDescriptor.ControllerType.GetMethod("Action2");

            return new ReflectedHttpActionDescriptor(controllerContext.ControllerDescriptor, methodInfo);
        }
    }
}

And to register it you need to add following line to your WebApiConfig.cs file:

config.Services.Replace(typeof(IHttpActionSelector), new CustomHttpActionSelector());

In your controller you than add two methods Action1 and Action2:

    public string Action1(string param)
    {
        return "123";
    }

    public string Action2(string param)
    {
        return "345";
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top