6

I have a controller, it needs to invoke another controller. We WERE doing this work on the client. We want to do this server side for performance reasons.

Request is a POST Request Url = "http://example.com/api/foo/1234567 (pretty standard url with binding for an id)

Request Data

{
  something1:'abc',
  something2:'def',
  copyFromUrl : '/api/bar/7654321'

};

The copyFromUrl could be any other controller in the application. I don't want to hand jam a bunch of if statements up and down the stack to do the binding.

Complicating the issue is most controllers have three different GET signatures. Get(sting id) Get(sting id, string xpath) Get()

10
  • 1
    In the same application you don't need invoke entire http stack. You can call your controller like you call any other class. MyController controller = new Mycontroller(); MyReturnType ret = controller.Get(id); Commented Sep 20, 2013 at 17:49
  • 1
    In my application that would require hundreds of if statements. if url.contains("/api/foo") then( if query.segemnts = 2 ... and so on. The routing engine already has all this logic. Commented Sep 21, 2013 at 19:17
  • May be your application is not designed well? Or may be it is not designed for that. You really should be able to call any controller in a regular .net manner. I feel your app doesn't have good single responsibility Commented Sep 23, 2013 at 13:16
  • I am facing the same issue. @EricRohlfs, were you able to find a good solution for this? Commented May 12, 2014 at 13:19
  • 1
    @T.S. I think the singe responsibility you are referring to is the ability to re-invoke the routing engine to resolve to the appropriate controller constructor and method. This is more about efficiency than bad design. Many frameworks support the ability to issue multiple commands at one time. Why make two http calls when one can do the job. Howto in WebApi is not straight forward. Commented Mar 9, 2015 at 18:22

1 Answer 1

2

One way of doing this, would be to basically short-circuit HttpServer and HttpClient classes. I am using here ASP.NET Web API 2, but hopefully same technique can be used with original Web API.

Here is the minimalistic working sample:

public class BarController : ApiController
{

    // GET http://localhost/api/bar
    [HttpGet]
    public IEnumerable<string> Get()
    {
        return new string[] {"Foo Bar", "Progress Bar"};
    }

    // GET http://localhost/api/bar?bar=Towel Bar
    [HttpGet]
    public IEnumerable<string> GetCustomBar(string bar)
    {
        return new string[] {"Foo Bar", "Progress Bar", bar};
    }

    // POST http://localhost/api/bar?action=/api/bar?bar=Towel Bar
    [HttpPost]
    public HttpResponseMessage StartAction(string action)
    {
        var config = new HttpConfiguration();
        WebApiConfig.Register(config);
        var server = new HttpServer(config);
        var client = new HttpClient(server);
        var response = client.GetAsync("http://localhost/" + action).Result;
        return response;
    }

As you can see here, the first two actions differ in parameters, the third action accepts url (as in code example) that allows it to invoke any other action.

We are basically hosting a server in memory, applying same routes our real server has, and then immediately querying it.

Hard-coded localhost is actually not used run-time, the routes ignore it, but we need valid absolute URL name for the internal validation to pass.

This code is just an illustration, proof-of-concept if you may.

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.