Reputation: 686
I have a Master view in my MVC solution which requires data (Companies) from a separate database to the Umbraco CMS database.
Shared\Master.cshtml
@inherits Umbraco.Web.Mvc.UmbracoViewPage<MyCode.Web.Portal.Models.Master>
<!DOCTYPE html>
<html>
<head>
<title>@Umbraco.Field("title")</title>
</head>
<body>
<div>
<span>
<h1>@Umbraco.GetDictionaryValue("Application Name")</h1>
</span>
<span>
<h1>@Umbraco.GetDictionaryValue("Company"):</h1>
<!--This is the data from a separate database.-->
@Html.DropDownListFor(model => model.SelectedCompany, new SelectList(Model.Companies))
</span>
</div>
@Html.Partial("Navigation")
<div class="container">
@Html.Partial("Breadcrumb")
<div class="body-content">
<!--This is where I expect the Umbraco view to be nested.-->
@RenderBody()
</div>
</div>
</body>
</html>
I then have Template views in Umbraco which use this master view as a layout.
ChildNodeSelectionPage.cshtml
@{
Layout = "Shared/Master.cshtml";
}
<img src="@Model.Content.GetProperty("icon")"/>
<h2>@Model.Content.GetProperty("title")</h2>
@Html.Raw(Model.Content.GetProperty("description"))
@Html.Partial("Child Node Grid")
When a controller which should generate this view (a Document named Home which uses ChildNodeSelectionPage.cshtml as its Template) is first hit, the model is null and I can't create it! What do I need to do to get the model to not be null?
MVC Home Controller:
public class HomeController : RenderMvcController
{
private ActionResult Index(IPublishedContent content, CultureInfo currentCulture)
=> CurrentTemplate
(
new Master
(
content,
currentCulture,
new Company(0, "Automobilli Lamborghini Spa"),
new[]
{
new Company(0, "Automobilli Lamborghini Spa"),
new Company(1, "Ital Design")
}
)
);
public override ActionResult Index(RenderModel model)
//The model is null, the PublishedContentRequest is null and Umbraco.TypedContentSingleAtXPath fails! I can't even hack myself a fresh model!
=> Index
(
model?.Content ?? UmbracoContext.Current.PublishedContentRequest?.PublishedContent ?? Umbraco.TypedContentSingleAtXPath("Home"),
model?.CurrentCulture ?? UmbracoContext.Current.PublishedContentRequest?.Culture ?? CultureInfo.CurrentUICulture
);
}
}
Master Model:
public class Master : RenderModel
{
public Company SelectedCompany { get; }
public IEnumerable<Company> Companies { get; }
public Master
(
IPublishedContent content,
CultureInfo culture,
Company selectedCompany,
IEnumerable<Company> companies
)
: base
(
content,
culture
)
{
SelectedCompany = selectedCompany;
Companies = companies;
}
}
Please note I'm new to Umbraco and still trying to figure out the best way to integrate it with an existing MVC website. If the approach I have taken here is wrong, feel welcome to suggest another to avert this problem I am having with the controller not receiving a model.
Upvotes: 0
Views: 697
Reputation: 686
The issue was in my RouteConfig.cs
file in that I was calling MapRoute
which in turn was overriding Umbraco's own routing and thus not allowing it to pass in the model for its template. I removed this call and renamed my HomeController
to match the name of the Umbraco Template I was using for the Home Page and Umbraco was then able to call the Index
method itself whilst passing in the RenderModel
.
My RouteConfig
class now looks like this:
public static class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//This code was the source of the problem.
//routes.MapRoute
//(
// name: "Default",
// url: "{controller}/{action}/{id}",
// defaults: new
// {
// controller = "Home",
// action = "Index",
// id = UrlParameter.Optional
// }
//);
}
}
Ensure the name of this controller matches the file name of the Umbraco Template being used by the Umbraco Document but suffix it with the word "Controller".
//Previously named HomeController.
public class ChildNodeSelectionPageController : RenderMvcController
Now matches template files name + "Controller" (see under "Child Node Selection Page" editable textbox).
This is the Umbraco "Home" Document using that template.
Upvotes: 1