0

I'm trying to create a ViewComponent for a series of checkboxes based on this article here:

https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components?view=aspnetcore-2.2

And this SO answer here: https://stackoverflow.com/a/42853705/2300177

Seems like a perfect case scenario for what I'm trying to do. However, I've created my ViewComponent to include Identity UserManager to get the userId:

using BlogPlayground.Data;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;

namespace BlogPlayground.ViewComponents
{
    public class LatestArticlesViewComponent : ViewComponent
    {
        private readonly ApplicationDbContext _context;
        private readonly UserManager<IdentityUser> _userManager;


        public LatestArticlesViewComponent(ApplicationDbContext context, UserManager<IdentityUser> userManager)
        {
            _context = context;
            _userManager = userManager;
        }

        public async Task<IViewComponentResult> InvokeAsync()
        {
            string userId = _userManager.GetUserId(User);

            var lastArticles = await _context.Article
                                            .OrderByDescending(a => a.CreatedDate)
                                            .Take(howMany)
                                            .ToListAsync();
            return View(lastArticles);
        }
    }
}

The problem is that when I call this line:

string userId = _userManager.GetUserId(User);

I'm getting an error for Userthat reads:

cannot convert from 'System.Security.Principal.IPrincipal' to 'System.Security.Claims.ClaimsPrincipal'

This exact code works in all my controllers and I have no idea where the User even comes from. Seems like magic, but I'm guessing somewhere inherent inside Identity? Or did I just miss something included in my controllers? (I searched "User" in my controllers and can't link that to anything.)

I'm using the Pomelo MySQL nuget package if that makes a difference? I wouldn't think so.

Anyone know what I'm missing and how to eliminate this error?

Update: Seems it will work with this (at least it gets rid of the error):

string userId = _userManager.GetUserId(Request.HttpContext.User);

Is that the same thing? Is there a using statement I'm missing? Visual studio (2017) usually clues me in to what I'm missing.

Sum None
  • 1,534
  • 2
  • 19
  • 28
  • Kindly go through this link. It may be helpful for you https://stackoverflow.com/questions/30701006/how-to-get-the-current-logged-in-user-id-in-asp-net-core – Sunil Dhappadhule May 27 '19 at 06:41
  • casting the user to claims principal should solve the problem `(ClaimsPrincipal)User` – Elyas Esna May 27 '19 at 08:32
  • @ElyasEsna Hi Elyas, thanks for the reply. That seems to have made the error go away. Now I just need get back around to testing it... when I was reading more into that first link, seems ViewComponents are their own thing. So, I'm kind of leaning away from it. – Sum None May 27 '19 at 12:15

1 Answers1

0

Please make sure you configured services.AddDefaultIdentity and enabled app.UseAuthentication Identity in your Startup.

This is needed to make it available to the app through dependency injection, so you can get it loaded in your LatestArticlesViewComponent.

See the details here: Introduction to Identity on ASP.NET Core

Dmitry Pavlov
  • 25,557
  • 8
  • 92
  • 105
  • Hi, thanks for the reply. I did all that. As I explained, it works ok in my controllers, just not in the ViewComponent. – Sum None May 27 '19 at 12:11
  • @SumNone as for retrieving the current user ID check [Asp.net Core Get User by User Id](https://stackoverflow.com/a/52503510/804385). – Dmitry Pavlov May 27 '19 at 16:58
  • Thanks, yes, I'm aware of that way too. I'm actually doing that in my api where the user is not authed through Identity and doing quick verification of the email address. I guess I'm just looking for why the ControllerBase "User" doesn't seem to work. I'm kind of OCD about code uniformity. :) – Sum None May 27 '19 at 23:06
  • If you pickup the user details from JWT token (with AddJwtBearer) - the trick thing here - override default Name claim with what you have in your token claims (you can decode it with jwt.io online). I mean your `options.TokenValidationParameters = new TokenValidationParameters { NameClaimType = "yourclaimname" }` By default `NameClaimType` a fully qualified URI - see https://www.jerriepelser.com/blog/overriding-name-claimtype-aspnetcore-oidc/ – Dmitry Pavlov May 29 '19 at 15:45