Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Controller invoking another controller C# WebApi

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()

like image 642
Eric Rohlfs Avatar asked Sep 17 '13 12:09

Eric Rohlfs


People also ask

Can a controller call another controller?

Yes, you can call a method of another controller. The controller is also a simple class. Only things are that its inheriting Controller Class. You can create an object of the controller, but it will not work for Routing if you want to redirect to another page.

How do I run an action method from another controller?

var ctrl= new MyController(); ctrl. ControllerContext = ControllerContext; //call action return ctrl. Action();


1 Answers

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.

like image 118
Sebastian K Avatar answered Oct 05 '22 07:10

Sebastian K