Search code examples
c#asp.net-coreasp.net-core-2.1asp.net-core-identity

Asp.Net Core 2.2 Identity pages wont work with Layout in View/Shared folder


I have just begun working on the registration/login/logout functionality of a new web app using Asp.Net Core 2.2.

I have scaffolded out the Identity pages, just easier for me. I'm not a fan of this new methodology.

My page code generates the link for the register page like so

<div class="text-right reg-button">
    <a asp-area="Identity" asp-page="/Account/Register" class="submit">Register</a>
</div>

this generates the link

<div class="text-right reg-button">
    <a class="submit" href="/Identity/Account/Register">Register</a>
</div>

clicking on that link produces a error

NullReferenceException: Object reference not set to an instance of an object.

The link looked right so I suspected there is something wrong with the layout its trying to use since this is also part of the error detail.

NullReferenceException: Object reference not set to an instance of an object. AspNetCore.Views_Shared__Layout_Industry.b__14_0() in _Layout-Industry.cshtml + var controllerName = this.ViewContext.RouteData.Values["controller"].ToString();

so I set the layout to null directly in the Register page and the page rendered in its basic form.

So the question becomes two fold;

  1. Why does the layout I've set in the Identity sections ViewStart file (The layout I also have set in the Views/Shared folder) fail with all the Identity pages, but work perfectly fine in any other page not under the Areas folder?

  2. Even If I set the layout full path directly in the file, it still fails with the same error. The layouts file name is _Layout-Industry but I noticed in the error detail it shows it as _Layout_Industry, is that hyphen causing an issue?

    Here is the site when first opened

Site Main Page

If you click on the Register/Link button in top right corner it should take you to the Register page but it fails

The register page is the default register page that comes in the default web application, the Layout page is my own, and it works on all 14 other pages that are NOT under the Identity area, and are in the standard Views subfolders

Page load enter image description here

UPDATE:

I have a view component that loads the meta tag section to the page. Here is the code

@{
    var controllerName = this.ViewContext.RouteData.Values["controller"]?.ToString();
    var actionName = this.ViewContext.RouteData.Values["action"]?.ToString();
    var userid = UserManager.GetUserId(User);
}
<!--Meta Tags- Using MetatagViewComponent-->
@if (controllerName != null && actionName != null)
{
    @await Component.InvokeAsync("Metatag", new MetatagViewComponent.MetatagRequest { Controller = controllerName, Action = actionName })
}

The controller and action calls were failing because there are no controllers in the Identity pages. I made them nullable and bypass them and the register page now loads. Is there a way to get the view name from the identity pages, I can then retrieve the metatags as I do for all other pages.


Solution

  • It's using your layout. The problem is that your layout literally throws an exception. Now, the reason it throws an exception when used by a Razor Page vs a traditional MVC view is that with Razor Pages, there's no controller, and therefore ViewContext.RouteData.Values["controller"] is null. Trying to call ToString() off that results in your NullReferenceException.

    With Razor Pages, neither "action" nor "controller" will be in your RouteData, since neither of those concepts apply. Instead, you'll have "page" and "handler". If you want to use this same layout with both Razor Pages and MVC views, then you'll need to adjust the logic around what you're doing with the controller name to accommodate Razor Pages as well.