Instantiation of a controller in OnActionExecuting (...not throwing a 404) in MVC Azure

340 views Asked by At

The objective is to add a maintenance batch on the same url of the administration of an Azure MVC site. The url should be something like:

https://admin.mysite.com/Batch?pass=HKE671

I decided to override OnActionExecuting and to capture the information I need in the url to trigger the maintenance method. I am not familiar with MVC projects, and this may not sound very conventional...

  protected override void OnActionExecuting(ActionExecutingContext filterContext)
  {
      EmailUtility.SendSupportEmail("DEBUG - On result executing", ""); //I receive this email
      int y = 14;
      if (Request.Url.Query.Length > y)
      {
          string url = Request.Url.Query.Remove(0, y); // I remove ?ReturnUrl=%2f
          if (url.StartsWith("Batch"))
          {
              mySite.Admin.Web.Controllers.TenantController controller = new mySite.Admin.Web.Controllers.TenantController();
              EmailUtility.SendSupportEmail("DEBUG - starts maintenance", ""); // I don't receive this one
              controller.maintenance(HttpUtility.ParseQueryString(url).Get("pass"));
          };
      }
      base.OnActionExecuting(filterContext);
  }

This code works as well as I need on local, the maintenance method is called and does the job. But when deployed on Azure, this modification throws a 404 error. Interestingly, I send two debug emails : I don’t receive the second one "DEBUG - starts maintenance", therefore my 404 error comes from the instantiation of a controller in OnActionExecuting.

First, I would like to understand why is the behavior different between my development machine and Azure?

Then, how can I make it work? Thanks,

EDITED on Jan 4:
I made a little progress, but this issue is still unsolved.
- About the difference between my dev machine and Azure: there are a few redirections on this site: https, 404 and non-existent domain. I assumed it was due to a 404 error. Encapsulating the code with a try/catch didn't sent me any error, so I am guessing that I can suppress the 404 from the hypothesis.
- I tried the code above on OnAuthorization without having more success.
- I noticed that the first email DEBUG - On result executing is in fact sent at the first test only. It is not sent the second time I run my test. This doesn't make any sense to me, because the session should be checked every time.

Conclusion for today: it seems to be more a routing/redirection problem.

2

There are 2 answers

6
enter.net On

Why don't you do:

      protected override void OnActionExecuting(ActionExecutingContext filterContext)
      {    
         try {
            //your code here
         } catch (Exception ex){
            EmailUtility.SendSupportEmail("Execution failed: " + ex.Message , "");
         }
      }

If your code is throwing an exception, this should give you a better understanding on why it is failing.

But more important, a more robust way of checking for the correct URL would be:

if (filterContext.HttpContext.Request.Url.AbsolutePath.EndsWith("Batch")){
}

As far as i can tell your string variable "url" will not ever start with "Batch", because Request.Url.Query only conains the part after the "?" thus making your check always return false. Why this IS working on localhost is hard to tell, but in my opinion it shouldn't.

Actually, to work in all cases your check should be:

if (filterContext.HttpContext.Request.Url.AbsolutePath.ToLower().EndsWith("batch") || filterContext.HttpContext.Request.Url.AbsolutePath.ToLower().EndsWith("batch/")){
}

After your edit: Ok, so what's happening is that you're requesting the action "Batch" in Home Controller, but because you're not authenticated you are redirected to LogOn in Account Controller. You should be seeing a login page, unless there's no associated LogOn view in your Views folder, or no AccountController at all, in both cases an exception is thrown.

Is the Batch method supposed to check for authentication? If not, remove the [Authorize] annotation from this method in HomeController and you should be fine.

You still have to adjust the if-check though, because it actually only evaluates to true on the LogOn page, and false if you actually get to the Batch page.

0
Manor On

Shame on me, the problem was somewhere else!... The code above works well, but the routing of this site rejected an incomplete url. In this case, it had to contain the project name: https://admin.mysite.com/Admin/Batch?pass=HKE671 Then all is back to normal!

So the answer is: the behavior is different on my local computer because the local host of my development machine doesn't route projects of the solution the same way Azure does.

Many thanks for your help!