Custom Controller using View()

Hi, this is most probably my c# skill lacking and not directly related to Litium, but I’m trying to create a custom controller.

I create the controller:
Litium.Accelerator.Mvc/Controllers/TestController.cs
And the views:
Litium.Accelerator.Mvc/Views/Test/Index.cshtml
Litium.Accelerator.Mvc/Views/Shared/_ViewTest.cshtml

From the testController I try call return View() this returns an error about
context.CurrentStae.PageType.Name beeing null from the ContentProvider.cs

So am thinking I need to create a new “base view” so I create it and put it in the Shared view folder, then run: View(“Index”,“ViewTest”), but i still get the same error.

The only thing that I manage to get working is PartialView(), but that is not really what I want :slight_smile:

Any suggestions?

Litium version: 6

You should be working with pagetypes and templates, see this article for more information:

https://docs.litium.com/more/training/start-with-litium/pagetypes-and-templates

This is how I do it when I want to create a new pageType inside Litium (For CMS pages etc).

This time I just want to create a completely custom controller and view that has nothing to do with the adminpanel, no admin model or data should be used.

Is this not possible using view? Is partialView my only option then?

Standard ASP.NET MVC will have a route registered for the controller, when using Litium you got the hierarchic url to reflect the page structure in the site together with the product structure.

_from https://docs.litium.com/documentation/architecture/mvc_

However the accelerator adds another route in Litium.Accelerator.Mvc.RouteConfig:

// Register direct access for controllers
RouteTable.Routes.MapRoute(
   "ControllerDirect", // Route name
   "site.axd/{controller}/{action}/{id}", // URL with parameters
   new {action = "Index", id = UrlParameter.Optional} // Parameter defaults
).DataTokens["SkipAutoLayout"] = true;

So you should be able to access your controller on _http://domain/site.axd/test_ and if you need to you can define some other route for access.

Thank you for your patience, I don’t think that I’m explaining myself very well. I can access the controller with no problem.

url.com/api/test/ and this render just fine to the browser if i return a manual string or a partialView from the controller.
I just want to know if it is possible to use the View(‘template’,‘master’) logic somehow :confused:
Thanks!

So is the problem that you are unable to use a layout with your custom controller?

I tried to reproduce the problem but for me it works (if I understand the problem), I have created a testcontroller for which i can define a layout (see attached image).

Yes we seam to understan each other now! So your test is with the Litium.Accelerator.Mvc.RouteConfig config from before?

Else it seams exactly like my setup: except I try to use the RoutePrefix insted of RouteConfig :
image

Is this the problem, going via RoutePrefix will demand a Litium pageType being defined??

In the route that is registered in the accelerator we are adding an extra data token with name SkipAutoLayout (see last row).

In the _ViewStart.cshtml we are checking if this data token have been set, if the data token not have been set we are automatic setting the Layout for the view depend on the settings in accelerator.

From _ViewStart.cshtml

@using Litium
@using Litium.Accelerator.ContentProviders
@{
    if (ViewContext.RouteData.DataTokens["SkipAutoLayout"] == null 
        || ((bool?)ViewContext.RouteData.DataTokens["SkipAutoLayout"]).GetValueOrDefault() == false)
    {
        if (IoC.Resolve<IContentProvider>().ShowLeftColumnData)
        {
            Layout = "~/Views/Shared/_LayoutWithLeftColumn.cshtml";
        }
        else
        {
            Layout = "~/Views/Shared/_Layout.cshtml";
        }
    }
}

To be able to set the view from the controller and use litium hierarchical url routing you manually need to add the DataTokens["SkipAutoLayout"] = true before render the view.

I think if you update LitiumController with this extra override you will get your master layout to be used instead of the automatic selection. You need to inherit the LitiumController instead of the Controller in your implementation.

        protected override ViewResult View(string viewName, string masterName, object model)
        {
            RouteData.DataTokens["SkipAutoLayout"] = true;
            return base.View(viewName, masterName, model);
        }
1 Like

Thank you both! And thank for this full explanation, I understand now and got it all working the way I want!