4

I'm working on an ASP .NET Core application, and I'm trying to load a view component inside of _LoginPartial. _LoginPartial was created automatically when I created the new project, and my view component is called UserNameViewComponent. The view component should get the logged-in person's username and display it at the top of the screen.

Whenever I log in, the page application gets stuck on the login screen until I stop it. I added a breakpoint to the line in _LoginPartial that calls the view component. When the view component is called it gets my username successfully, but then when it goes back to _LoginPartial it runs the same line of code again to go back to the view component, and this happens forever.

Block of code in _LoginPartial where view component is called:

 @if (SignInManager.IsSignedIn(User))
{
<li class="nav-item">
    <a class="nav-link text-light" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">@await Component.InvokeAsync("UserName")</a>
</li>
    <li class="nav-item">
        <form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Action("Index", "Home", new { area = "" })">
            <button type="submit" class="nav-link btn btn-link text-light">Logout</button>
        </form>
    </li>
}

UserNameViewComponent:

namespace Tangy.ViewComponents
{
public class UserNameViewComponent : ViewComponent
{
    private readonly ApplicationDbContext _db;
    public UserNameViewComponent(ApplicationDbContext db)
    {
        _db = db;
    }

    public async Task<IViewComponentResult> InvokeAsync()
    {
        var claimsIdentity = (ClaimsIdentity)this.User.Identity;
        var claim = claimsIdentity.FindFirst(ClaimTypes.NameIdentifier);

        var userFromDb = await _db.Users.Where(u => u.Id == claim.Value).FirstOrDefaultAsync();

        return View(userFromDb);
    }

}

Default.cshtml:

@model Tangy.Models.ApplicationUser
@{
    ViewData["Title"] = "Default";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

Hi @Model.FirstName @Model.LastName <i class="far fa-user"></i>

Does anyone know what I'm doing wrong here?

3
  • can you post the view that InvokeAsync is returning Commented Jan 11, 2019 at 21:07
  • Just added it. The view is called Default.cshtml, and it's located inside Shared/Components/UserName Commented Jan 11, 2019 at 21:16
  • Just realized my problem - I needed to take "Layout = "~/Views/Shared/_Layout.cshtml"" out of the view. Thanks for suggesting that I add that portion to my post! Commented Jan 11, 2019 at 21:18

1 Answer 1

4

It looks like the issue is that _LoginPartial is contained in _Layout and rendering your View Component which then references _Layout. This will create a circular reference and the code for your view component (and the code for _Layout) will be called over and over.

_Layout -> _LoginPartial -> Default.cshtml (from view component) -> _Layout -> _LoginPartial -> Default.cshtml (from view component ) on and on and on.....

setting the Layout to null in the ViewComponent's view should solve your issue.

@{
    ViewData["Title"] = "Default";
    Layout = null;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.