While trying to implement the answer from here> How to get the current logged in user Id in ASP.NET Core and the user redirected me to here> https://github.com/dotnet/aspnetcore/issues/18348
var UserId = User.FindFirstValue(ClaimTypes.Name);
^ This is not working, and prints the following error 'User' does not contain a definition for 'FindFirstValue'
Edit: Adding controller snippet
The full snippet of my controller...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using ProjectName.Processing;
using ProjectName.Repository;
using Newtonsoft.Json;
namespace ProjectName.Controllers
{
[ApiController]
[Route("api/[controller]/[action]")]
public class ClassNameController : ControllerBase
{
private readonly ILogger<ClassNameController> _logger;
private OtherClassNameProcessing proc = new OtherClassNameProcessing();
public ClassNameController(ILogger<ClassNameController> logger)
{
_logger = logger;
}
[HttpGet]
[ProducesResponseType(typeof(List<2ndOtherClassNameRepository>), StatusCodes.Status200OK)]
public IActionResult GetUserName()
{
var data = proc.GetUserName();
return Ok(data.Result);
}
}
}
The full snippet my controller is calling...
using Microsoft.EntityFrameworkCore;
using ProjectName.Data;
using ProjectName.Repo;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//using System.Web;
using System.Threading.Tasks;
using System.Security.Claims;
using Microsoft.AspNetCore.Http;
using System.Web.Providers.Entities;
namespace ProjectName.Processing
{
public class OtherClassNameProcessing
{
private readonly ProjName_DevelContext _context = new ProjName_DevelContext();
private async Task<List<2ndOtherClassNameRepository>> GetNameFromRepo()
{
List<2ndOtherClassNameRepository> repoList = new List<2ndOtherClassNameRepository>();
var Temp = await _context.tablename.ToListAsync();
/* Working Test
2ndOtherClassNameRepository repo = new 2ndOtherClassNameRepository();
repo.UserName = "JohnDoe";
repoList.Add(repo);
return repoList;
*/
2ndOtherClassNameRepository repo = new 2ndOtherClassNameRepository();
// repo.UserName = "JohnDoe";
var userId = User.FindFirstValue(ClaimTypes.Name);
repo.UserName = userId;
repoList.Add(repo);
return repoList;
}
internal async Task<List<2ndOtherClassNameRepository>> GetUserName()
{
return await GetNameFromRepo();
}
}
}
Any idea why I'm getting this error?
-
Read my updated answer thoroughly. It will solve your problem.TanvirArjel– TanvirArjel2020年04月06日 15:34:46 +00:00Commented Apr 6, 2020 at 15:34
4 Answers 4
The issue you are likely having is that you lack the right package.
Install this: Microsoft.Extensions.Identity.Core
Then it should start working once the using statement is included.
Comments
Okay! Got the problem. User
ClaimPrinciple
is only available in the Controller
context. I see your ControllerNameProcessing
is not a Controller
class. So you should do as follows:
public class ControllerNameProcessing
{
private readonly IHttpContextAccessor _httpContextAccessor;
public ControllerNameProcessing(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
private async Task<List<2ndClassNameRepository>> GetNameFromRepo()
{
// Omitted your other codes for brevity
var userName = _httpContextAccessor.HttpContext.User.FindFirstValue(ClaimTypes.Name);
// Omitted your other codes for brevity
}
}
Then you should register IHttpContextAccessor
in the Startup
class as follows:
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
}
Now in your controller:
[ApiController]
[Route("api/[controller]/[action]")]
public class ClassNameController : ControllerBase
{
private readonly ILogger<ClassNameController> _logger;
private OtherClassNameProcessing _otherClassNameProcessing;
public ClassNameController(ILogger<ClassNameController> logger, OtherClassNameProcessing otherClassNameProcessing)
{
_logger = logger;
_otherClassNameProcessing = otherClassNameProcessing;
}
[HttpGet]
[ProducesResponseType(typeof(List<2ndOtherClassNameRepository>), StatusCodes.Status200OK)]
public IActionResult GetUserName()
{
var data = proc.GetUserName();
return Ok(data.Result);
}
}
Then you should register OtherClassNameProcessing
in the Startup
class as follows:
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
services.AddScoped<OtherClassNameProcessing>();
}
6 Comments
_httpContextAccessor
).private OtherClassNameProcessing proc = new OtherClassNameProcessing();
. Not sure if I should be referencing this within the function itself in order to use it on the 4th-to-last-line in your controller solution. So I changed var data = proc.GetUserName();
to var data = _otherClassNameProcessing.GetUserName();
. No build errors, but it is returning a nullvar data = proc.GetUserName();
to var data = _otherClassNameProcessing.GetUserName();
so others don't have to debug the solution they copy and paste... it would be much appreciated.Try to get user id as follow (for User of type ClaimsPrincipal)
var userId = User.Claims.Where(c => c.Type == "sub").FirstOrDefault().Value;
And For User of type System.Web.Providers.Entities.User use
User.UserId
https://learn.microsoft.com/en-us/previous-versions/aspnet/dn253175(v=vs.108)
7 Comments
User user = new User();
and now the issue I am having is returning null
. My co-worker is saying something about it has to reach the oicd servers. I'm not sure what all that entails, but we were able to get this to work with .net mvc and .net framework. But having issues with .net core (going with CRUD backend).This was my solution:
result = _httpContextAccessor.HttpContext.User.Claims.First(x => x.Type == ClaimTypes.Name).Value;
Comments
Explore related questions
See similar questions with these tags.