1

I have a problem with using a dot in url umbraco MVC custom routes. /logo/images/image.jpg?width=100 gives following errors:

[NullReferenceException: Object reference not set to an instance of an object.]
   Umbraco.Web.Mvc.UmbracoVirtualNodeByIdRouteHandler.FindContent(RequestContext requestContext, UmbracoContext umbracoContext) +18
   Umbraco.Web.Mvc.UmbracoVirtualNodeRouteHandler.GetHttpHandler(RequestContext requestContext) +48
   System.Web.Routing.UrlRoutingModule.PostResolveRequestCache(HttpContextBase context) +11987058
   System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +141
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +91

/logo/images/image.jpg/?width=100

Works, but this isn’t a good solution for me. I have tried adding this in webconfig

<location path="logo">
        <!-- This only applies it to the relevant path and keeps the protection in place for elsewhere -->
        <system.web>
            <httpHandlers>
                <add path="/images/*" type="System.Web.Handlers.TransferRequestHandler" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" />
            </httpHandlers>
        </system.web>
        <!-- Required for IIS 7.0+ -->
        <system.webServer>
            <modules runAllManagedModulesForAllRequests="true" />
            <validation validateIntegratedModeConfiguration="false" />
            <handlers>
                <add name="ApiURIs-ISAPI-Integrated-4.0" path="*" type="System.Web.Handlers.TransferRequestHandler" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" preCondition="integratedMode,runtimeVersionv4.0" />
            </handlers>
        </system.webServer>
    </location>

taken from https://average-joe.info/allow-dots-in-url-iis/ but it won't work:(

My custom route looks like this:

protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
    {
        //custom route
        RouteTable.Routes.MapUmbracoRoute(
        "images",
        "logo/{action}/{key}",
        new
        {
            controller = "Image",
            key = UrlParameter.Optional,



        },
      new ProductsRouteHandler(4884));
    }
}
public class ProductsRouteHandler : UmbracoVirtualNodeByIdRouteHandler
{

    public ProductsRouteHandler(int realNodeId) : base(realNodeId)
    {
    }

    protected override IPublishedContent FindContent(RequestContext requestContext, UmbracoContext umbracoContext, IPublishedContent baseContent)
    {
        return base.FindContent(requestContext, umbracoContext, baseContent);
    }
}

I'am using umbraco vs.7.4.3

  • Your example URL is for a .jpg file extension, Umbraco includes a dependency onf ImageProcessor which would handle dynamically resizing images and my be suitable for your requirements? – Anth12 Jun 09 '16 at 13:07
  • yes I’am already using ImageProcessor in the imagecontroller to resize pictures. The pictures are located outside the webserver and I want the resizing to work similar as ImageResize.NET. That code will work except for the routing wont allow using a dot at the end. – Goran Backlund Jun 09 '16 at 15:02

1 Answers1

1

The UmbracoModule ignores Urls with a file extension, so an UmbracoContext will never get created for a request containing a file extension.

You can create a context using UmbracoContext.EnsureContext, however if you did this in FindContent method of your handler, you'd encounter this exception. This is caused by a stale variable on line 18 of the UmbracoVirtualNodeRouteHandler holding a reference to a null UmbracoContext, and doesn't pick up the freshly created context.

The following is how worked around it so I could call EnsureContext before the VirtualNodeRouteHandler gets called.

var route = routes.MapRoute("RouteName", "some/url/file.ext", new
{
    controller = "MyController",
    action = "Index"
}
route.RouteHandler = new UrlWithExtensionHandler();

Notice its not the MapUmbracoRoute, but the standard MVC Map Route, and a standard MVC IRouteHandler which calls EnsureContext before returning an instance of a UmbracoVirtualNodeRouteHandler.

public class UrlWithExtensionHandler : IRouteHandler
{
    #region Implementation of IRouteHandler

    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        // init umbraco context
        var httpContext = new HttpContextWrapper(HttpContext.Current);

        UmbracoContext.EnsureContext(
            httpContext,
            ApplicationContext.Current,
            new WebSecurity(httpContext, ApplicationContext.Current),
            UmbracoConfig.For.UmbracoSettings(),
            UrlProviderResolver.Current.Providers,
            false);

        var handler = new UrlWithExtensionVirtualNodeRouteHandler();
        return handler.GetHttpHandler(requestContext);
    }

    #endregion
}

public class UrlWithExtensionVirtualNodeRouteHandler : UmbracoVirtualNodeRouteHandler
{
    protected override IPublishedContent FindContent(RequestContext requestContext,
            UmbracoContext umbracoContext)
    {
        return someIPublishedContent;
    }
}

Not an ideal solution, but a valid workaround until the stale variable issue gets merged into core - I've submitted a PR to fix it

A few others have had the same issue too http://issues.umbraco.org/issue/U4-9384

tompipe
  • 949
  • 6
  • 8