Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Peter Laurie 8 posts 27 karma points
    Jun 28, 2013 @ 00:20
    Peter Laurie
    0

    Umbraco 6.1.1 - Controller or class that will run code on all content pages/Document types?

    Hi,

    Any help with this would be most welcome.

    Basically I am trying to implemt a maintence page that will run no matter where you enter the site. The following code worked fine on our previous version of the website in Umbraco 4.8 using THE CODE BEHIND on the master template:

    // Website disabled via "Global Website Settings"?
                umbraco.presentation.nodeFactory.Node node = new umbraco.presentation.nodeFactory.Node(1056);
      if (node.Id == 0)
     {
     throw new Exception("Maintenance node does not exist.");
     }
    f (Convert.ToBoolean(int.Parse(node.GetProperty("settingsDisableWebsite").Value)))
      {
     bool isAllowed = false; // Default - no access to ALL users
     string[] allowedIPs = null;
     if (!string.IsNullOrEmpty(node.GetProperty("settingsAllowedComputers").Value))
     {
     allowedIPs = node.GetProperty("settingsAllowedComputers").Value.Split(',');
      foreach (string IP in allowedIPs)
     {
     if (IP.Trim() == Request.UserHostAddress)
     {
    // If users IP is in the allowed list, set isAllowed and break from loop
     isAllowed = true;
     break;
      }
     }
     }
     // No! You can't come in - Redirect to maintenance page
     if (!isAllowed)
     {
     Response.Clear();
     Response.Status = "302 Moved Temporarily";
     Response.AddHeader("Location", "/maintenance/");
     Response.End();
     }

    I have managged to get this code to eork fine, if I add it to the HomeController in App_Code

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using Umbraco.Web.Models;
    using Umbraco.Web.Mvc;

    namespace WWW.Controllers
    {
    public class HomeController : RenderMvcController
     {
    //This renders for all requests to the Home Document Type, no matter what template is already assigned 

    public override ActionResult Index(RenderModel model)
    {

    // THE CODE I SHOWED CODE ABOVE GOES HERE

                return base.Index(model);

    }

    }

    }

    It seems that I would have to create a controller for ALL document types to get this to run nomatter where a person accesses the website.

    Please can someone shed some light on how to run the above code so that I do not have to repeat it countless times for all types of document types in our website.

    I have tried creating a global.ascx.cs file in App_Code and used 
    protected override void OnApplicationStarting(object sender, EventArgs e) { } etc.

    Solving this would help me run other code on all tyrpes of doc types in the website, and I am sure a solution will help many others.

    Thank you in advance.

    Peter

  • Lars-Erik Aabech 349 posts 1100 karma points MVP 7x c-trib
    Jun 28, 2013 @ 16:01
    Lars-Erik Aabech
    0

    If I'm not mistaken, you want a custom page when you're doing maintainance on the site?

    In that case, I'd do it with application.beginrequest in a httpmodule instead.
    If you can access web.config, I'd also move the "maintainance" boolean to an appsetting.

    Or even better, if you have control over IIS, add application_offline.htm as a default document and put a static html file with that name in your root when you're doing maintainance. (rename it to .bak when not)
    Visual Studio publishing does that by default when you publish a site by the way.

    HTH,
    Lars-Erik

  • Peter Laurie 8 posts 27 karma points
    Jul 02, 2013 @ 19:48
    Peter Laurie
    0

    HI Lars-Erik,

    Thank you for your reply.

    We had the original working fine in Umbraco 4.8, where the code I posted earlier enabled us to switch the site into maintenace mode just from the umbraco cms, and also decide, from ip addresses, who can still view the site to work on updates etc.

    This is what I want to have working the same in Umbraco 6, but at time version 6 is proving to be very difficult to work with wjhen changing from version 4.

    If any one can shed some light on creating a controller which will run on all views, if possble, then please let me know.

     

    Kind regards,

     

    Pete

  • Andy Butland 422 posts 2334 karma points MVP 4x hq c-trib
    Jul 03, 2013 @ 16:53
    Andy Butland
    0

    I think you'll probably want to look at putting the logic in an MVC action filter Pete.  You can then register this as a global filter in global.asax.cs that will run across all controller requests like this:

    GlobalFilters.Filters.Add(new MyActionFilterAttribute());

    I've not tried this on Umbraco so there maybe some more to work out there - but have used in standard MVC sites a fair bit, and it seems to work well when you want to run some logic on all requests.

    Andy

  • Lars-Erik Aabech 349 posts 1100 karma points MVP 7x c-trib
    Jul 04, 2013 @ 11:25
    Lars-Erik Aabech
    0

    Sorry for getting back a bit late, but you're actually very much in luck.

    Umbraco 6 has a pretty nice new "pipeline" where you can add an extension for finding content for a URL.

    What I suggest is described in Stephan's slides from CG13 here:
    http://www.zpqrtbnk.net/TheUmbraco6RequestPipeline.pdf
    Specifically from page 56 and onwards.

    - Create an IContentFinder where you check your application setting, request IP etc. and point Umbraco to the one specific "maintainance node".

    I don't think you'll need a controller if you do this, but Umbraco also has a nice new feature that attempts to run a controller with the same name as the document type of the current node. So if your maintainance document type is called "Maintainance", Umbraco will search for a SurfaceController called MaintainanceController and attempt to run the Index action.

    Lars-Erik

  • firepol 125 posts 173 karma points
    Jul 10, 2013 @ 11:06
    firepol
    0

    Hi. It would be cool to have the original question answered (as I'm looking exactly for the same thing). I think I'm answerting it, read on ;)

    In The Umbraco MVC Documentation Custom controllers (Hijacking Umbraco Routes) it's described how to add a default controller.
    See chapter: Change the default controller. Attention: the solution works only for umbraco 6.10 and above. I tried to use it in a umbraco 6.0.5 website I have, and I couldn't do it, so I need to upgrade it :(

    So this in theory should answer Peter's question. E.g. if he has 20 document types, he obviously doesn't want to create 20 controllers, he wants a default one to do the job.

    In my case (a recent umbraco 6.1.1 I've done) I have 3 document types in my website and each one has its own controller and view. I followed the instructions in the above documentation and put in my global.asax.cs file the code as described in the docu. I also created a MyCustomUmbracoController as follows:

    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using Umbraco.Core.Models;
    using Umbraco.Web.Models;
    
    namespace MyWebsite.Controllers
    {
        public class MyCustomUmbracoController : Umbraco.Web.Mvc.RenderMvcController
        {
            public override ActionResult Index(RenderModel model)
            {
                string test = "";
    
                //Do some stuff here, then return the base method
                return base.Index(model);
            }
        }
    }
    

    I've put a breakpoint in front of the string test line. That breakpoint is never hit. Why? I found the answer: read on ;)

    If I modify one (for Document Type "Page" in my case) of my other 3 controllers, which looks like this:

    public class PageController : Umbraco.Web.Mvc.RenderMvcController

    to this:

    public class PageController : MyCustomUmbracoController

    then the breakpoint is obviously hit, because the class extends MyCustomUmbracoController...

    I went on with my tests, and created a new Document Type called "Test". I created a Template (and deleted the file that umbraco created under masterpages) and created the View Test.cshtml containing some hello world text... this time I didn't create a controller for this new document type. I browsed my Test page (document type "Test") and the breakpoint of MyCustomUmbracoController was hit. Cool!

    So I understand that the default controller is used only if no specific controller for the document type exists, which makes sense.

    I was curios to know if it was possible to "hijack" all existing controllers, with the MyCustomUmbracoController, without modifying each controller by making it inherit from MyCustomUmbracoController as mentioned above... but maybe I was asking too much (or missing something). If you know an easier solution here, glad to see it.

    My conclusion: it seems that it's possible to create a default controller without the need to create one for each document type. Just proceed as described. In case you create controllers for some document types, just don't forget to make them inherit from the default one. That's it.

    Cheers

  • Lars-Erik Aabech 349 posts 1100 karma points MVP 7x c-trib
    Jul 10, 2013 @ 11:12
    Lars-Erik Aabech
    0

    As far as I understood, Peter wants to show one specific page if some criterias are met (application setting + client ip).
    In that case, creating an IContentFinder that overrides the content Umbraco is going to show would be a nice solution. That content is of a specific document type, hence he only needs one controller. That controller will also only fire if the criterias are met.

    It's nice to know though, that you can have a default controller. I'll look into that someday, thanks for the research! :)

     

  • firepol 125 posts 173 karma points
    Jul 10, 2013 @ 12:58
    firepol
    0

    @Lars: Well my post was for people who "use the search function" and search e.g. "default controller" ;) So they find here the answer exactly for that search (I searched that and finished here, first result).

    I've had a look at the PDF docu you shared... it's also quite interesting! I'll give it a look as well ;)

  • Peter Laurie 8 posts 27 karma points
    Jul 23, 2013 @ 12:21
    Peter Laurie
    0

    @Lars

    Thank you so much for your reply to my original question, you are spot on with what I am asking, and I will take a look at implementing it on my site devlopment later.

    Thank you all for your contributions,

    Kind regards,

    Peter

Please Sign in or register to post replies

Write your reply to:

Draft