Copied to clipboard

Flag this post as spam?

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


  • Eric Gaspard 6 posts 58 karma points
    Oct 31, 2014 @ 15:03
    Eric Gaspard
    0

    718 Custom MVC Routes - umbracoContext is null

    Hello,

    I'm trying to setup a custom MVC route in order to generate a specific file (AppCache manifest) but when I'm trying to execute the URL I got an the following error :

    [ArgumentNullException: Value cannot be null.
    Parameter name: umbracoContext]
       Umbraco.Web.Mvc.UmbracoController..ctor(UmbracoContext umbracoContext) +77
       Umbraco.Web.Mvc.UmbracoController..ctor() +20
       CCE.Umbraco.Controllers.ClientAppCacheController..ctor() +29
    
    [TargetInvocationException: Exception has been thrown by the target of an invocation.]
       System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0
       System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +159
       System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +251
       System.Activator.CreateInstance(Type type, Boolean nonPublic) +87
       System.Activator.CreateInstance(Type type) +6
       System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +55
    
    [InvalidOperationException: An error occurred when trying to create a controller of type 'CCE.Umbraco.Controllers.ClientAppCacheController'. Make sure that the controller has a parameterless public constructor.]
       System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +169
       System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +77
       Umbraco.Web.Mvc.OverridenDefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +9
       Umbraco.Web.Mvc.UmbracoControllerFactory.CreateController(RequestContext requestContext, String controllerName) +89
       Umbraco.Web.Mvc.RenderControllerFactory.CreateController(RequestContext requestContext, String controllerName) +14
       Umbraco.Web.Mvc.MasterControllerFactory.CreateController(RequestContext requestContext, String controllerName) +134
       System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +192
       System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +55
       System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +48
       System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16
       System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +329
       System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +14

    As far as I understand, the controller is correctly resolved (ClientAppCacheController) but the Umbraco Context seems to not have been initialized yet.

    My controller :

    namespace CCE.Umbraco.Controllers
    {
    public class ClientAppCacheController : UmbracoController
    {
    public ActionResult Index()
    {
    //...
    }
    }
    }

    My route declaration (I'm having a custom default controller for another purpose) :

      public class Application : ApplicationEventHandler
    {
    protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
    {
    // Sets the fallback/default MVC controller (so that all templates/Views can inherit from a common base-class)
    DefaultRenderMvcControllerResolver.Current.SetDefaultControllerType(typeof(MasterPageController));

    RouteTable.Routes.MapRoute("Application Cache Manifest", "manifest.xml", new { controller = "ClientAppCache", action = "Index" });
    }
    }

    Can anyone help me, please ?

    Thanks and regards,

    Eric.

  • Eric Gaspard 6 posts 58 karma points
    Nov 03, 2014 @ 08:10
    Eric Gaspard
    103

    Hello,

    As I searched in google, I found out that an issue was already submitted in the Umbraco Tracker : U4-5445 which happened to be the same issue I was experiencing.

    As explained in the issue, the problem revolve in a current change (from 7.1.6 I believe) regarding the creation of the current UmbracoContext which is now only created on url without extensions or being one of the following : ".aspx", ".ashx", ".asmx", ".axd", ".svc"

    Since my custom route was a .xml it did not fit the criteria and no context was created hence my error message. As explained by Shannon Deminick, you can create yourself the context using UmbracoContext.EnsureContext. The difficulty is that both HttpContext and Umbraco are properties of the UmbracoController and interfere with the compiler type disanbiguation. The correct wirting :

      public class ClientAppCacheController : UmbracoController
    {
    public ClientAppCacheController()
    : base(
    UmbracoContext.EnsureContext(
    new HttpContextWrapper(System.Web.HttpContext.Current)
    , ApplicationContext.Current
    , new global::Umbraco.Web.Security.WebSecurity(new HttpContextWrapper(System.Web.HttpContext.Current)
    , ApplicationContext.Current)
    , true))
    {

    }
    }

    As you can see this really hard to read so I would really vouch for the "white list" extension to be configurable. At least the documentation should be updated to reflect this breaking change.

    Finally it was also suggested that using IoC would have prevented that issue so maybe that is the better way to go with ?

Please Sign in or register to post replies

Write your reply to:

Draft