4

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?

asked Apr 6, 2020 at 15:13
1
  • Read my updated answer thoroughly. It will solve your problem. Commented Apr 6, 2020 at 15:34

4 Answers 4

10

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.

answered Sep 28, 2021 at 13:35
Sign up to request clarification or add additional context in comments.

Comments

5

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>();
}
answered Apr 6, 2020 at 15:30

6 Comments

I've added both snippets and I'm getting the following error during the build: "Error CS7036 There is no argument given that corresponds to the required formal parameter 'httpContextAccessor' of 'ControllerNameProcessing.ControllerNameProcessing(IHttpContextAccessor)'". Any idea why this is happening?
This another error! You are creating an instance of class without passing the constructor required parameter. Better pass your class as Dependency Injection.
ah yes, the squiggly line found in the controller (edited code in question). Now I need to pass that as an object through the constructor, as I get an error saying "A field initializer cannot reference the non-static field, method, or property 'ClassNameController._httpContextAccessor'".(not currently shown in the question code, but only adding live). I guess I need to learn how to do dependency injection with this thing(_httpContextAccessor).
I noticed you removed the line 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 null
Okay, I agree this is another type of issue and will close this one here. Thank you for your patience. Also if you could please change var 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.
|
1

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)

answered Apr 6, 2020 at 15:20

7 Comments

Getting relevant error: 'User' does not contain a definition for 'Claims'
Whats the type of User? Normally it should be ClaimsPrincipal
System.Web.Providers.Entities.User
So you can use User.UserId property as 'learn.microsoft.com/en-us/previous-versions/aspnet/…'. But i think you should use IdentityUser.
So when I try that, it says it cannot be used as a static context. So I added 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).
|
0

This was my solution:

result = _httpContextAccessor.HttpContext.User.Claims.First(x => x.Type == ClaimTypes.Name).Value;

answered May 24, 2023 at 2:22

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.