In the constructor I want to set some ViewData, in order to read this data in f.e the Layout view.
private async Task SetLayoutViewModelAsync()
{
if (ViewData[LayoutViewModelKey] == null)
{
var publishedContent = TryGeyPublishedContent();
if (publishedContent != null)
{
ViewData[LayoutViewModelKey] = await _layoutFactory?.ConstructAsync(publishedContent);
}
}
}
When I set a breakpoint and call the LoginController, I see that the code in the DefaultController is executing and seems good to me. But in the LoginView its null.
When I override the Index method in Login - and DefaultController, its working fine, but I want this to work everywhere by using the base constructor.
In the constructor there is the SetLayoutViewModelAsync() method, this is responsible for nothing more then collecting usefull properties,settings etc.
public async Task<Layout> ConstructAsync(IPublishedContent content)
{
var website = content.GetHome(); //Umbraco's root node
var currentUser = _backofficeUserAccessor.BackofficeUser;
var currentMember = await _memberManager.GetCurrentMemberAsync();
return new Layout
{
Content = content,
User = currentUser.IsAuthenticated
? new Models.Structs.BackOfficeUser()
{
Id = currentUser.FindFirstValue(ClaimTypes.NameIdentifier).TryParse(null),
UserName = currentUser?.Name ?? string.Empty,
Roles = _backofficeUserAccessor.GetAllRoles(),
IsAuthenticated = currentUser.IsAuthenticated,
IsAdmin = _backofficeUserAccessor.UserIsAdmin(),
} : null,
Member = currentMember,
};
}
Now I have another controller, for example LoginController, where I use access the ViewData in Razor.
var Model = (Layout)ViewData[DefaultController.LayoutViewModelKey];
But this is always null.
In case I call the method in base from Index, its working as expected. But I do not want to think about that.
[HttpGet]
public IActionResult Index()
{
base.SetLayoutViewModelAsync(); }
Why ViewData is null even when I call base.SetLayoutViewModelAsync() in the LoginControlle ctor?
Long strory, short; This concept is running fine in U8 and took it in a just setten up U9 project and cannot get it work jet. 👍
Set ViewData in Default Controller constructor
I have a default controller where all requests pass through. This part is working fine.
I used this documentation: https://our.umbraco.com/documentation/Reference/Routing/custom-controllers
The final goal is; To enrich the view model passed to the template with additional properties (from other published content items or outside Umbraco)
In the constructor I want to set some ViewData, in order to read this data in f.e the Layout view.
When I set a breakpoint and call the LoginController, I see that the code in the DefaultController is executing and seems good to me. But in the LoginView its null.
When I override the Index method in Login - and DefaultController, its working fine, but I want this to work everywhere by using the base constructor.
Hi Peter,
Can you post some more code ?
Dave
Hi Dave,
Here I have my default controller.
In the constructor there is the SetLayoutViewModelAsync() method, this is responsible for nothing more then collecting usefull properties,settings etc.
Now I have another controller, for example LoginController, where I use access the ViewData in Razor.
But this is always null.
In case I call the method in base from Index, its working as expected. But I do not want to think about that.
Why ViewData is null even when I call base.SetLayoutViewModelAsync() in the LoginControlle ctor?
Long strory, short; This concept is running fine in U8 and took it in a just setten up U9 project and cannot get it work jet. 👍
Hi Peter,
Is your login controller inheriting from your DefaultController ?
Dave
Hello Dave,
Yes, it is.
I notice now that DefaultController is inheriting from RenderController, in U8 this is inheriting SurfaceController and IRenderMvcController.
Maybe that is the issue here.
Inherting from RenderController is what you need to do. Mixing Surface and RenderControllers is not a good idea. See https://our.umbraco.com/forum/umbraco-7/using-umbraco-7/73791-getting-an-error-with-custom-routes-could-not-find-a-surface-controller-route-in-the-routetable-for-controller-name-authorization#comment-236516 for some more background.
Do you have a doctype called Login ?
Dave
In that case I will keep the RenderController, good point!
I have the Login doctype, debugging in LoginController is also working well.
Do you call the base constructor from the constructor of your login controller ?
Dave
Yes, here is the Login controller:
If you put a debugger in the defaultController constructor. Does that hit when you call the login controller ?
Dave
Yes, that is working well as expected.
Hi Peter,
That is strange. I will try to reproduce this today.
Dave
Hi Dave,
I just created an new solution and created the same state. https://github.com/PetervandenDungen/Umbraco9.LayoutFactory
Peter
Hi Peter,
I just pulled your solution. And I can confirm setting it in the constructor does not work. Only when you call it from the base Index action.
Probably something change how .NET core handles constructors in controllers compared to .NET Framework.
Dave
Thanks for the confirmation. 👍
Peter
is working on a reply...