ASP.NET Core 3.1“‘用户’不包含‘FindFirstValue’的定义”

Posted

技术标签:

【中文标题】ASP.NET Core 3.1“‘用户’不包含‘FindFirstValue’的定义”【英文标题】:ASP.NET Core 3.1 "'User' does not contain a definition for 'FindFirstValue'" 【发布时间】:2020-04-06 15:13:19 【问题描述】:

在尝试从这里实现答案时> How to get the current logged in user Id in ASP.NET Core 用户将我重定向到这里 > https://github.com/dotnet/aspnetcore/issues/18348

var UserId = User.FindFirstValue(ClaimTypes.Name);

^ 这不起作用,并打印以下错误'User' does not contain a definition for 'FindFirstValue'

编辑:添加控制器 sn-p

我的控制器的完整 sn-p...

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);
        
    

我的控制器正在调用的完整 sn-p...

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();
        
    

知道为什么会出现此错误吗?

【问题讨论】:

彻底阅读我更新的答案。它会解决你的问题。 【参考方案1】:

您可能遇到的问题是您缺少正确的软件包。

安装这个:Microsoft.Extensions.Identity.Core

一旦包含 using 语句,它就应该开始工作了。

【讨论】:

【参考方案2】:

好的!有问题。 User ClaimPrinciple 仅在 Controller 上下文中可用。我看到你的 ControllerNameProcessing 不是 Controller 类。所以你应该这样做:

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
     

那么你应该在Startup类中注册IHttpContextAccessor,如下:

public void ConfigureServices(IServiceCollection services)

    services.AddHttpContextAccessor();

现在在您的控制器中:

[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);
    

那么你应该在Startup类中注册OtherClassNameProcessing,如下:

public void ConfigureServices(IServiceCollection services)

    services.AddHttpContextAccessor();
    services.AddScoped<OtherClassNameProcessing>();

【讨论】:

我已经添加了两个 sn-ps,并且在构建过程中出现以下错误:“错误 CS7036 没有给出与 'ControllerNameProcessing.控制器名称处理(IHttpContextAccessor)'”。知道为什么会这样吗? 这又是一个错误!您正在创建类的实例而不传递构造函数所需的参数。最好将您的课程作为依赖注入传递。 啊,是的,控制器中的波浪线(有问题的编辑代码)。现在我需要通过构造函数将它作为对象传递,因为我收到一条错误消息“字段初始值设定项无法引用非静态字段、方法或属性'ClassNameController._httpContextAccessor'”。(当前未显示在问题代码中,但只添加实时)。我想我需要学习如何用这个东西进行依赖注入(_httpContextAccessor)。 我注意到您删除了 private OtherClassNameProcessing proc = new OtherClassNameProcessing(); 行。不确定我是否应该在函数本身中引用它,以便在控制器解决方案的倒数第四行使用它。所以我将var data = proc.GetUserName(); 更改为var data = _otherClassNameProcessing.GetUserName();。没有构建错误,但它返回一个 null 这里就完成了!在这里关闭问题。现在提交 anothet 以获得 null。【参考方案3】:

尝试按如下方式获取用户 ID(对于 ClaimsPrincipal 类型的用户)

 var userId = User.Claims.Where(c => c.Type == "sub").FirstOrDefault().Value;

对于 System.Web.Providers.Entities.User 类型的用户使用

User.UserId

https://docs.microsoft.com/en-us/previous-versions/aspnet/dn253175(v=vs.108)

【讨论】:

出现相关错误:“用户”不包含“索赔”的定义 用户类型是什么?通常应该是 ClaimsPrincipal System.Web.Providers.Entities.User 因此您可以将 User.UserId 属性用作“docs.microsoft.com/en-us/previous-versions/aspnet/…”。但我认为你应该使用 IdentityUser。 所以当我尝试这样做时,它说它不能用作静态上下文。所以我添加了User user = new User();,现在我遇到的问题是返回null。我的同事说它必须到达 oicd 服务器。我不确定这意味着什么,但我们能够让它与 .net mvc 和 .net 框架一起使用。但是 .net 核心存在问题(与 CRUD 后端一起使用)。

以上是关于ASP.NET Core 3.1“‘用户’不包含‘FindFirstValue’的定义”的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core--.net core 3.1 部署到 IIS

从 ASP.NET Core 3.1 升级到 ASP.NET 5.0 后,User.Claims 为空

Wcf 服务在 .NET Core 3.1 控制台应用程序中工作,但在 ASP.NET Core 3.1 Web API 中无法工作

不记名令牌出现 401 错误 - asp.net core 3.1

如何在 ASP.NET Core 3.1 中使用 Java?

HTTP 错误 500.0 - Dot net core 3.1 中的 ASP.NET Core IIS 托管失败(进程中)