【问题标题】:ASP.NET Core 3.1 "'User' does not contain a definition for 'FindFirstValue'"ASP.NET Core 3.1“‘用户’不包含‘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();
        }
    }
}

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

【问题讨论】:

  • 彻底阅读我更新的答案。它会解决你的问题。

标签: asp.net-core .net-core asp.net-core-identity .net-core-3.1


【解决方案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 后端一起使用)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多