Custom Route Error in Umbraco 8 - No physical template file was found for template
Hey,
I am wanting to create a custom route, to pass through parameters to a page in a freindly url, rather than on a query string. Followed the instructions for creating a route, but didn't find it very clear, and am missing something.
I am getting a "No physical template file was found for template " error. On inspecting the model it all looks good.
My Custom Route code
public class RegisterCustomRouteComposer : ComponentComposer<RegisterCustomRouteComponent>
{ }
public class RegisterCustomRouteComponent : IComponent
{
public void Initialize()
{
// Custom route for explore search results
// IPublishedContent for the current rendering page
RouteTable.Routes.MapUmbracoRoute("AccomodationCustomRoute", "explore/accommodation/{region}/{type}/search", new
{
controller = "AccommodationSearchResultsPage",
Action = "Search",
type = UrlParameter.Optional
}, new AccomodationRouteHandler(17070));
}
public void Terminate()
{
// Nothing to terminate
}
}
public class AccomodationRouteHandler: UmbracoVirtualNodeByIdRouteHandler
{
public AccomodationRouteHandler(int realNodeId) : base(realNodeId)
{
}
}
And the Controller...
public class AccommodationSearchResultsPageController : RenderMvcController
{
public ActionResult Index(ContentModel model)
{
return base.Index(model);
}
public ActionResult Search(ContentModel model, string type, string region)
{
AccommodationSearchResultsPage page = new AccommodationSearchResultsPage(model.Content)
{
Region = region, Type = type
};
return base.CurrentTemplate(model.Content);
}
}
Is your Custom RenderMVCController actions hit? if you set a breakpoint inside the Index and Search Actions.. which one is hit by a request to your custom route?
The id of the PublishedContent associated with the route: 17070 - does that correspond to a node with a template?
and do you have a template called search?
When you return base.Index(Model) it will return only the default template for the content item eg 17070, whne you return CurrentTemplate(Model) then Umbraco will use either the default template or the template requested via ?altTemplate=aliasoftemplatetouse
So I'm just wondering if the custom routing is successfully making it to your controller and it can't work out which template to return or whether it's not making it to your template and trying to use the default template for 17070 and not finding one?
Yes it reaches the search action (I tested with the index one as well)
Yes the node has a default template, this is what I thought it would use.
I don't have a "search" template, as the template is the name of the doc type eg "AccommodationSearchResultsPage". Do I need a different template setup?
When you return CurrentTemplate() (and this is what the base.Index() calls in the underlying RenderMvcController implementation) - Umbraco reads the 'action' name that from the controller that is being executed and uses this as the name of the template to render - the CurrentTemplate method checks whether this file exists on disk and throws an error if it does not.
In your example if you route via the Search Action - the the template being looked for is called Search - and you'd need to have a Search.cshtml template on disk for it to work...
... now interestingly if you route the request via the Index action, then CurrentTemplate is looking for an 'Index' template, which is unexpected, as the 'default implementation' of RenderMVCController requests that aren't custom routed, would have it's action to be set to the name of the default template the page is published with... however when you custom route in this fashion you bypass the steps in the core that would set this for you.
Therefore the options for working around this are to either:
a) Create a template that matches your action or vice versa - use an action name that matches your template name
b) don't use CurrentTemplate and instead return the View directly from your controller:
eg:
return View("~/Views/home.cshtml",page);
c) set the action name to match the template before using CurrentTemplate
public ActionResult Index(ContentModel model, string type, string region)
{
//hardcode
ControllerContext.RouteData.Values["action"] = "home";
//or with db lookup
//ControllerContext.RouteData.Values["action"] = model.Content.GetTemplateAlias();
AccommodationSearchResultsPage page = new AccommodationSearchResultsPage(model.Content)
{
Region = region,
Type = type
};
return CurrentTemplate(page);
}
(also in your example above in the Search action you are not returning your custom page viewmodel, eg return base.CurrentTemplate(model.Content); should be return base.CurrentTemplate(page);
Custom Route Error in Umbraco 8 - No physical template file was found for template
Hey,
I am wanting to create a custom route, to pass through parameters to a page in a freindly url, rather than on a query string. Followed the instructions for creating a route, but didn't find it very clear, and am missing something.
I am getting a "No physical template file was found for template " error. On inspecting the model it all looks good.
My Custom Route code
And the Controller...
Hi Nadia
Is your Custom RenderMVCController actions hit? if you set a breakpoint inside the Index and Search Actions.. which one is hit by a request to your custom route?
The id of the PublishedContent associated with the route: 17070 - does that correspond to a node with a template?
and do you have a template called search?
When you return base.Index(Model) it will return only the default template for the content item eg 17070, whne you return CurrentTemplate(Model) then Umbraco will use either the default template or the template requested via ?altTemplate=aliasoftemplatetouse
So I'm just wondering if the custom routing is successfully making it to your controller and it can't work out which template to return or whether it's not making it to your template and trying to use the default template for 17070 and not finding one?
regards
marc
Yes it reaches the search action (I tested with the index one as well)
Yes the node has a default template, this is what I thought it would use.
I don't have a "search" template, as the template is the name of the doc type eg "AccommodationSearchResultsPage". Do I need a different template setup?
Hi Nadia
When you return CurrentTemplate() (and this is what the base.Index() calls in the underlying RenderMvcController implementation) - Umbraco reads the 'action' name that from the controller that is being executed and uses this as the name of the template to render - the CurrentTemplate method checks whether this file exists on disk and throws an error if it does not.
In your example if you route via the Search Action - the the template being looked for is called Search - and you'd need to have a Search.cshtml template on disk for it to work...
... now interestingly if you route the request via the Index action, then CurrentTemplate is looking for an 'Index' template, which is unexpected, as the 'default implementation' of RenderMVCController requests that aren't custom routed, would have it's action to be set to the name of the default template the page is published with... however when you custom route in this fashion you bypass the steps in the core that would set this for you.
Therefore the options for working around this are to either:
a) Create a template that matches your action or vice versa - use an action name that matches your template name b) don't use CurrentTemplate and instead return the View directly from your controller:
eg:
c) set the action name to match the template before using CurrentTemplate
(also in your example above in the Search action you are not returning your custom page viewmodel, eg return base.CurrentTemplate(model.Content); should be return base.CurrentTemplate(page);
regards
Marc
is working on a reply...