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()
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.
var ctrl= new MyController(); ctrl. ControllerContext = ControllerContext; //call action return ctrl. Action();
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With