Azure mobile services: call a controller method from another one

Senza-titolo-2 copy

Controllers should be controllers, just an interface to some business function, anyway I was in hurry and the fastest way to achieve what I aimed was to call a TableController method from a custom controller. This is not a good practice, but sometimes may be be useful.

Actually I don’t really know what happens behind the scenes ’cause of how azure works (too much layers of abstractions and too much reflection), however I found empirically this way to use a controller from another one.

First I created an instance of the table controller I wanted to use:

var myTableController = new MyTableController();

Instantiate the controller class unfortunately is not enough since many important things are in the Initialize method which is protected and can’t be called outside its class. In order to solve this without changing the base class signature and keeping the override, I made a new method in the TableController which only exposes the protected one, so:

[HttpPut]
public void InitializePub(HttpControllerContext controllerContext)
{
       Initialize(controllerContext);
}

The [HttpPut} Attribute is a really dirty and unsafe way to avoid that this method clashes with the one that should be called on Post requests, since by default all methods are mapped on Post and I didn’t used HttpPut.

The next problem is that we’re missing some information. At this point we will get a null argument exception, since the member Service will be null. In order to fix that in the fastest way I just built a new one in the custom controller Initialize as follow:

var Service = new Microsoft.WindowsAzure.Mobile.Service.ApiServices(this.Configuration);
var myCustomController = new myCustomController();
myCustomController.Service = Service;

At this point everything should work, the custom controller:

    public class MyCustomController : ApiController
    {
        MobileServiceContext context;
        MyTableController myTableController;

        protected override void Initialize(HttpControllerContext controllerContext)
        {
            base.Initialize(controllerContext);
            this.context = new MobileServiceContext();
            
            var Service = new Microsoft.WindowsAzure.Mobile.Service.ApiServices(this.Configuration);

            myTableController = new MyTableController Controller();
            myTableController.Services = Service;
            myTableController.InitializePub(controllerContext);
        }
 
    // ...
    }

And the table controller:

   public class MyTableController : TableController
    {
        DbSet Users;
        MobileServiceContext context;
        protected override void Initialize(HttpControllerContext controllerContext)
        {
            // ... 
        }

        [HttpPut]
        public void InitializePub(HttpControllerContext controllerContext)
        {
            Initialize(controllerContext);
        }
    }

As said at the beginning: this is not a good practice. It’s just a things find out while being in hurry, take as it is.

Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedIn

You may also like...

2 Responses

  1. Aaron says:

    Have you tried this since the deprecation of Microsoft.WindowsAzure.Mobile.Service.ApiServices? I am trying to hack an example together myself using this as a rough guidline but keep getting a null reference exception due to the tablecontroller not coming back with anything (despite there being data)

Leave a Reply

Your email address will not be published. Required fields are marked *