12

Given a controller Proxy and an action of GetInformation. I want to be able to call the method GetInformation of the Users controller. Both the WebAPI controllers are in the same project but direct calls like

var controller = new UsersController();
return controller.GetInformation(request);

Doesn't work.

The signature is:

public HttpResponseMessage GetInformation(InformationRequest request)

I do not want to do a full redirect response as I do not want the UserController route exposed externally. This needs to be an internal only call.

abatishchev
  • 98,240
  • 88
  • 296
  • 433
VulgarBinary
  • 3,520
  • 4
  • 20
  • 54
  • 4
    Why directly calling doesn't work? Are you getting an error? Though it feels like it would be better if you had some inner layer that you could call instead of calling another controller.. – juunas Oct 19 '16 at 20:16
  • Instead of calling controller, you can use RedirectToRoute (or) move the functionality of GetInformation to a service and invoke that service. – sam Oct 19 '16 at 21:03
  • @sam - RedirectToRoute returns an ActionResponse and exposes the redirection to the client. This is not ok (and also in the question statement). – VulgarBinary Oct 19 '16 at 23:58
  • @juunas - It throws a null reference exception in building the HttpResponseMessage no matter what the HttpResponseMessage is. I posted the work around in my answer below, it was missing some core pieces needed in constructing the controller method. Apparently these are injected by WebAPI (MVC) engine, without them HttpResponses cannot be generated. – VulgarBinary Oct 20 '16 at 00:00

3 Answers3

8

For those wanting to solve this API to API method in different controllers, we have found a solution that works. The initial attempt was close, just missing a few things.

var controller = new UserAccountController
{
   Request = new HttpRequestMessage(HttpMethod.Post, Request.RequestUri.AbsoluteUri.Replace("/current/route", "/route/to_call"))
};
controller.Request.Properties[HttpPropertyKeys.HttpConfigurationKey] = new HttpConfiguration();
return controller.GetInformation(request);

In doing this it allows construction of the target controller and direct invocation of the method desired. The biggest complexity here is the Uri adjustment.

VulgarBinary
  • 3,520
  • 4
  • 20
  • 54
  • 1
    maybe you can create a helper class/method with the common part of this logica and see if you can move the uri replacements to a config file and use those values in the helper – Mauricio Gracia Gutierrez Oct 20 '16 at 15:13
3

You should do something like this in your UsersController

public HttpResponseMessage GetInformation(InformationRequest request)
{
    HttpResponseMessage resp ;

    resp = UserBusinessLogic.GetInformation(request) ;

    return resp ;
}

and from your ProxyController you can resuse that "UserBusinessLogic" method to obtain the same information using the same code snippet.

Mauricio Gracia Gutierrez
  • 10,288
  • 6
  • 68
  • 99
  • 2
    Yes, that's the "ideal" way to solve this. However, the volume of things we have to do this to it is not realistic to change the logic in all controllers to handle this approach. You provided an architectural shift which sure, if I was looking for how to build it from the ground up is perfect (and also something I would have not posted on Stack). Unfortunately, this is not a viable option. – VulgarBinary Oct 19 '16 at 23:50
0

Another way can be:

IQueryable<Users> GetInformation()

without using the IHttpActionResult return type. Your method will still remain an Http GET method and then call it in the same way as you call any class method.

Sumit Roy
  • 413
  • 2
  • 9
  • 23