Copied to clipboard

Flag this post as spam?

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

  • Bob Banks 16 posts 36 karma points
    Jun 14, 2013 @ 16:56
    Bob Banks

    Render a full page from SurfaceController

    I'm working on a site that contains a collection of print journal microsites.  Each journal microsite has it's own UI. In addition to custom pages within each microsite, each one will contain a fixed set of pages dealing with login, registration, subscription, etc.  They look the same for every journal but they should be rendered within the context of the journal (header, navigation, etc).

    I'd like these pages not to exist in Umbraco content tree since they'd have to be duplicated for every journal. Effectively, I'd like to render a "default" Umbraco page from the current journal (defined by hostname) along with a custom model.

    I've tried using a SurfaceController with a custom route.  Can't figure out if it's possible to render a full page from a SurfaceController.  Here's what I've tried.  When the view renders, a simple Umbraco.Field() call fails with a NullReferenceException.  Even stranger, trying to inspect CurrentPage never returns.  Just keeps spinning.

                var page = Umbraco.TypedContent(rootId);
                var model = new RenderModel(page, CultureInfo.CurrentCulture);
                return View("Register", model);

    I could use a RenderMvcController but then I need to have pages exist inside the content tree.

    Any recommendations? 

  • Charles Afford 1163 posts 1709 karma points
    Jun 15, 2013 @ 17:10
    Charles Afford

    Where abouts is the post being made from?  a View or Partial.  If it is from a partial i think you need to return partial view rather than View.  Charlie :)

  • Bob Banks 16 posts 36 karma points
    Jun 17, 2013 @ 16:14
    Bob Banks

    I'm not even concerned with an HTTP post at this point.  I'm just looking for a way to render a fixed Umbraco content item with a custom route.  

  • David Brendel 792 posts 2970 karma points MVP 3x c-trib
    Jun 17, 2013 @ 16:47
    David Brendel

    If you want to use the RenderModel i would suggest to use the RenderMVCController because it uses it by default. Also it should be used if you want to do your stuff when the node gets rendered.

    But in general it's no problem to call Umbraco.TypedContent(id) to get a node in a surface controller. I'm currently doing this some times in a small project. The only difference is that i call the methods of my surface by @Html.Action() in my views and also returning custom models.

    How do you call the surface methods?

    If you want to add completly new routes you have to add them to the routestable. Maybe this will help you with this:

  • Bob Banks 16 posts 36 karma points
    Jun 17, 2013 @ 16:58
    Bob Banks

    Yeah, I didn't want to use RenderMvcController because I don't want these pages in the content tree since they are going to exist for every journal. I've setup a "default page".  All of these profiles pages will render this default page with a different template.  As you can see in the code block above (which is for a register form), I retrieve the default page, create a RenderModel and then render the "Register" template. In the case of a subscription page, I'd render the same content item but with a "Subscribe" template.  

    I've routed to the SurfaceController actions without a problem.  I can retrieve an Umbraco content node as well.   The problem comes when I render the content item with a template.  Any references to CurrentPage timeout and the Umbraco helpers fail.  I believe it's because the UmbracoContext isn't initialized since I'm not routing through the UmbracoModule.  

  • David Brendel 792 posts 2970 karma points MVP 3x c-trib
    Jun 17, 2013 @ 17:11
    David Brendel

    You use the SurfaceController so you route "through" Umbraco.

    How does your template look like? Do you use the @inherits Umbraco.Web.Mvc.UmbracoTemplatePage? That thing gets you access to the Umbraco helper and some other stuff.

  • Bob Banks 16 posts 36 karma points
    Jun 17, 2013 @ 17:38
    Bob Banks

    No, I've created routes directly to the surface controllers.  I don't want to use the default routes for SurfaceController since they aren't friendly at all (/umbraco/surface/{controllername}/{action}/{id}).  Not to mention there isn't a separate content node for each of these pages.  

    I had access to the Umbraco helpers like Umbraco.Field but the call to it fails with a NullReferenceException.  My navigation also failed as all references to CurrentPage timed out.

    At this point, I've given up and created a document type named "Profile".  It requires that I have a content item for each of these pages in every journal.  Each page will use a different template and I'll take advantage of the template action methods in RenderMvcController.  

  • mmaty 109 posts 281 karma points
    Jun 18, 2013 @ 09:07

    Well... maybe you don't think about the adequate strategy for the task you want to accomplish.

    As far as I understand, you have several trees in your content section, one for each journal. Additionally you have a separate tree for registration, login etc.

      Journal 1
        Subpage 1.1
      Journal 2
        Subpage 2.1
      Journal 3
        Subpage 3.1
        Failed Login
        Forgotten Password


    In your template all you have to do is to determine the return url, and determine, in which tree the return url resides (node.AncestorOrSelf(1) gives you the root of such a tree). Now, if you have that information you are able to render different links to different css files. That way you can use ordinary Umbraco pages for registration and login and make them look different for each microsite. 

    You have to create the links to the registration pages using a partial in order to determine the return url. But that is a a really easy task.

  • Steve Temple 63 posts 324 karma points MVP 3x c-trib
    Jun 18, 2013 @ 11:09
    Steve Temple

    Hi, We've done something similar and we used a custom route so it didn't run through Umbraco at all, we just wrote it like a ASP.NET MVC standard controller:

    Using the umbraco API we were still able to grab content out of Umbraco for the nav etc

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Jun 18, 2013 @ 12:04
    Jeroen Breuer

    A few things have changed in 6.1. Don't know if they are helpful in this case, but it might be good to know about: Change the default controller.

    In 6.0.7 and 6.1.2 it will be possible to use a surface controller for route hijacking:




  • Bob Banks 16 posts 36 karma points
    Jun 18, 2013 @ 15:02
    Bob Banks

    Steve, that's exactly what I'm trying to do.  Could you share a bit of your controller and view code?  

    Thanks Jeroen.  I'll look into that.  

  • Steve Temple 63 posts 324 karma points MVP 3x c-trib
    Jun 18, 2013 @ 15:37
    Steve Temple

    I'm super busy today I'll try and get you an example after work


Please Sign in or register to post replies

Write your reply to: