Copied to clipboard

Flag this post as spam?

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


  • Lewis Moorcroft 8 posts 128 karma points
    Mar 11, 2019 @ 15:32
    Lewis Moorcroft
    0

    v8 - PluginController

    Hi folks

    So as a bit of a self learning exercise, I've taken my person website (v7) and rebuilt it from scratch in v8. I've got pretty much all of it re-written where necessary and working except one thing which is to do with how I generate my Sitemap.xml.

    So to paint a quick picture my SitemapContoller is inheriting from the Umbraco.Web.Mvc.PluginController and I've dumbed down the code just to try and get a proof-of-concept working, so the Controller itself has just a Xml ActionResult that returns an empty Xml result.

    In my v7 implementation I was using the ApplicationStarted event to register the sitemap.xml route with the controller name and action, and for the v8 implementation have moved this into a Composition/Component.

    However when I hit the Url in the v8 imlementation I get :

    [NullReferenceException: Object reference not set to an instance of an object.]
       Umbraco.Web.Runtime.<>c.<Compose>b__0_6(IFactory factory) +34
       Umbraco.Core.FactoryExtensions.GetInstance(IFactory factory) +55
       Umbraco.Web.Mvc.PluginController..ctor() +197
       MyProject.Controllers.SitemapController..ctor() +36
       DynamicMethod(Object[] ) +30
       LightInject.PerRequestLifeTime.GetInstance(Func`1 createInstance, Scope scope) in C:\projects\lightinject\src\LightInject\LightInject.cs:6207
       Umbraco.Web.Mvc.ContainerControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +45
    
    [Exception: Failed to create an instance of controller type MyProject.Controllers.SitemapController (see inner exception).]
       Umbraco.Web.Mvc.ContainerControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +220
       Umbraco.Web.Mvc.UmbracoControllerFactory.CreateController(RequestContext requestContext, String controllerName) +109
       Umbraco.Web.Mvc.RenderControllerFactory.CreateController(RequestContext requestContext, String controllerName) +12
       System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +262
       System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +77
       System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +1122
       System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) +213
       System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +131
    

    From the information from the stack trace, I've tried various different ways of trying to register the controller (in the Composer) but to no effect.

    I'm sure I'm missing something quite straight forward, but any ideas? Can provide code examples if needed.

    Cheers

    -lewis

  • Sebastiaan Janssen 5045 posts 15477 karma points MVP admin hq
    Mar 11, 2019 @ 15:45
    Sebastiaan Janssen
    0

    Shannon has been working to update Articulate to v8 and I don't know if any of these actually work at the moment, but you might spot the difference between your implementation and his:

    This one looks the simplest: https://github.com/Shazwazza/Articulate/blob/v8/src/Articulate/Controllers/WlwManifestController.cs

    And then there's: https://github.com/Shazwazza/Articulate/blob/v8/src/Articulate/Controllers/MarkdownEditorController.cs https://github.com/Shazwazza/Articulate/blob/v8/src/Articulate/Controllers/FeedController.cs https://github.com/Shazwazza/Articulate/blob/v8/src/Articulate/Controllers/OpenSearchController.cs https://github.com/Shazwazza/Articulate/blob/v8/src/Articulate/Controllers/RsdController.cs

    And attributed controllers: https://github.com/Shazwazza/Articulate/blob/v8/src/Articulate/Controllers/ThemeTreeController.cs https://github.com/Shazwazza/Articulate/blob/v8/src/Articulate/Controllers/ThemeEditorController.cs

    Hope it helps and if it does, do update this post so others can learn too! 👍

  • Lewis Moorcroft 8 posts 128 karma points
    Mar 11, 2019 @ 19:49
    Lewis Moorcroft
    0

    Thanks! I've had a look and can't see anything I've missed - the implementations do look similar. I think I'm going to have to pull down Articulate and see if they work.

  • Lewis Moorcroft 8 posts 128 karma points
    Mar 11, 2019 @ 22:57
    Lewis Moorcroft
    0

    OK for anyone who may be following the thread, I think I've found the issue.

    The routes in Articulate appear to be working as expected. I noticed that the only real difference between the two implementations is that my implementation contains a file extension (e.g. .xml) in the route url.

    So in short this will work:

    routes.MapRoute(
        "SitemapXml",
        "sitemap",
        new
        {
            controller = "Sitemap",
            action = "Xml"
        }
    );
    

    This will cause the error to be thrown:

    routes.MapRoute(
        "SitemapXml",
        "sitemap.xml",
        new
        {
            controller = "Sitemap",
            action = "Xml"
        }
    );
    

    As mentioned the file extension version works in v7 so could well be a bug, or something else needs to be considered.

    -lewis

  • Jason Larcombe 8 posts 28 karma points
    Oct 22, 2019 @ 20:04
    Jason Larcombe
    0

    I've just run in to this issue myself using Umbraco 8.1.5.

    Everything works as expected until a file extension is added to the custom route URL, for example trying to map a route to sitemap.xml. At which point I get the same error as in your original post.

    Can be reproduced by creating a simple controller with an action that returns a string, will resolve as expected when the route is mapped to /sitemap but borks when set to /sitemap.xml for example.

    Did you ever find a solution to this?

  • Lewis Moorcroft 8 posts 128 karma points
    Oct 23, 2019 @ 17:07
    Lewis Moorcroft
    0

    No, unfortunately I didn't find a solution in the end. I ended up just using a extension-less URL for my sitemap and declaring it in robots.txt.

    I've not re-visited the issue since but I am pretty sure this is a bug specifically to do with the Umbraco PluginController, as my robots.txt is also dynamically generated using a standard Mvc Controller and is accessed via a route with a .txt extension, and that works fine.

    With this reminder I'll raise an issue :)

  • Jason Larcombe 8 posts 28 karma points
    Oct 25, 2019 @ 22:06
    Jason Larcombe
    0

    Interesting. I'm just updating some of my starter kit stuff for v8. I also dynamically generate robots.txt and a manifest.json but none of them are working due to this issue with custom routes with extensions at the moment.

    I don't seem to be able to use standard MVC controllers either (I was using them for this stuff in v7), DI framework errors, not related to the routing with extensions issue iirc. Maybe i'm missing something... I'll re-visit tomorrow to make sure.

  • Filipe Sousa 43 posts 205 karma points
    Oct 26, 2019 @ 09:49
    Filipe Sousa
    0

    You can find two other solutions here https://umbracians.slack.com/archives/C06G5LWBV/p1572021036469000.

    Cheers

  • Jason Larcombe 8 posts 28 karma points
    Oct 26, 2019 @ 11:44
    Jason Larcombe
    0

    Hey Filipe. Interested to see how you solved this but I don't have access to that workspace.

    Having delved a bit deeper I can see that getting an Umbraco context instance from the factory at https://github.com/umbraco/Umbraco-CMS/blob/release-8.1.5/src/Umbraco.Web/Runtime/WebInitialComposer.cs#L116 is null when resolving a custom route including any file extension. Simply removing the extension from the route url avoids this issue. Haven't had a chance to look any deeper yet.

  • Chris Brown 1 post 72 karma points
    Nov 14, 2019 @ 12:02
    Chris Brown
    1

    MVC doesn't allow you to route "static" paths (anything with a full-stop character) by default, so a non-Umbraco option is to tell IIS to let those requests through to be routed:

    https://stackoverflow.com/questions/2006529/mvc-how-to-route-sitemap-xml-to-an-actionresult

    However, this sometimes then has issues with Umbraco's context and service resolution, so I find the easiest way is to do a quick IIS rewrite instead:

    Component:

    routes.MapRoute(
        "SitemapXml",
        "sitemap-xml",
        new
        {
            controller = "Sitemap",
            action = "Xml"
        }
    );
    

    web.config:

    <rewrite>
    <rules>
        <rule name="XML Sitemap" stopProcessing="true">
            <match url="sitemap.xml" />
            <action type="Rewrite" url="sitemap-xml" appendQueryString="false" />
        </rule>
    </rules>
    </rewrite>
    
Please Sign in or register to post replies

Write your reply to:

Draft