【问题标题】:Object Reference not set to an instance in ASP.Net Core 3.0对象引用未设置为 ASP.Net Core 3.0 中的实例
【发布时间】:2021-08-04 13:55:28
【问题描述】:

在 Manage.Data 项目中,我有管理存储库,并且在管理存储库中实现了服务调用。我有另一个项目 Manage.API,我有一个名为 Authenticate.cs 的类。我想从 Authenticate.cs 类文件中调用 GetLoginInfo() 方法。

private IManageRepository _memRepository;
_memRepository.GetLoginInfoAsync("","",Guid.Empty);  

它不工作。谁能指导我。

CustomAuthenticate.cs

namespace CamManager_API
{

    [AttributeUsage(AttributeTargets.Class)]
    public class CustomAuthorization : Attribute, IAuthorizationFilter
    {
        private IManageRepository IManageRepository;

        public CustomAuthorization(IManageRepository manageRepository)
        {
            this._manageRepository = manageRepository;
        }
        /// <summary>
        /// This will Authorize User
        /// </summary>
        /// <returns></returns>
        public void OnAuthorization(AuthorizationFilterContext filterContext)
        {
           
            if (filterContext != null)
            {
                Microsoft.Extensions.Primitives.StringValues authTokens;
                filterContext.HttpContext.Request.Headers.TryGetValue("Authorization", out authTokens);

                var _token = authTokens.FirstOrDefault();

                if (_token != null)
                {  
                    string authToken = _token;
                    if (authToken != null)
                    {
                        var responseModel =  _manageRepository.GetLoginInfoAsync("","",Guid.Empty);

                    }

                }
                else
                {
                }
            }
        }

        public bool IsValidToken(string authToken)
        {
            //validate Token here
            return true;
        }
    }
}


ManageRepository.cs

using Dapper;
using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Threading.Tasks;

namespace CamManager.DataAccess
{
    public class ManageRepository : SqlRepository<Member>, IManageRepository
    {
        public ManageRepository(string connectionString) : base(connectionString) { }

        public override async Task<Login> GetLoginInfoAsync(string firstName, string password, Guid accessKey)
        {
            using (var conn = GetOpenConnection())
            {
                var parameters = new DynamicParameters();
                parameters.Add("@Firstname", firstName, System.Data.DbType.String);
                parameters.Add("@Password", password, System.Data.DbType.String);
                parameters.Add("@AccessKey", accessKey, System.Data.DbType.Guid);
                return await conn.QueryFirstOrDefaultAsync<Login>("Login", parameters, commandType: CommandType.StoredProcedure);
            }
        }
        public override async Task<IEnumerable<Member>> GetAllAsync()
        {
        }
        public override async Task<Member> FindAsync(long id)
        {
        }
        public override async Task<Result> InsertAsync(Member entity)
        {
        }
        public override async Task<Result> UpdateAsync(Member entity)
        {
        }
        public override async Task<Result> DeleteAsync(long id)
        {
            
        }

    }
}

【问题讨论】:

  • 什么不起作用?
  • 收到错误“对象引用未设置为实例”
  • 你有没有初始化过_memRepository?在我看来你会很难使用 C#,我建议你阅读教程,你需要了解对象、接口等。
  • 正如其他人所提到的,很难看到您的实现,因为这里没有很多代码。你有更完整的例子和/或完整的错误吗?
  • 大家好,我已经实现了下面的代码。但还没上传。

标签: c# asp.net asp.net-core webapi


【解决方案1】:

也许您需要在构造函数中初始化您的存储库...否则向我们显示所有文件内容以检测确切的问题

public class MainClass
{
    private IManageRepository _memRepository;
    public MainClass(IManageRepository _memRepository)
    {
        this._memRepository = _memRepository;
    }
}

将此代码添加到您的启动中

public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IManageRepository , ManageRepository >();
}

【讨论】:

  • 嗨 Lajil... 我已经执行了上面的代码。我收到错误“没有给出与'CustomAuthorization.CustomAuthorization(IManageRepository)'所需的形式参数'manageRepository'相对应的参数”
  • @Abhishek,您真的需要分享更多代码。你只是显示两条线,没有办法以这种方式帮助你。如果你不熟悉如何实例化一个类,那么你有一个更大的问题需要首先解决。
  • 把代码全部分享给你会更方便
  • 嗨 Lajil A... 我已经编辑了我的问题并添加了代码。请看一下并帮助我
  • 1) 问:错误是否发生在“_memRepository”行? 请告诉我们失败的代码行!还向我们展示CLASS。 “认证”?这很重要。 2)问:你熟悉调试器吗?如果没有,请学习它。现在。否则,在您 THINK 初始化变量的位置设置一个断点。 3) 检查初始化时的值。确保您正在对其进行初始化。我THINK你可能需要在“Authenticate's”类的构造函数中初始化“_memRepository”(NOT“_manageRepository”!)。 5) 使用此信息更新您的帖子。
【解决方案2】:

我想你忘了为 ASP 依赖注入注册你的接口。否则 DI 不能做任何事情。 More information here

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IManageRepository, ManageRepositoryImplementation>();
}

其中 ManageRepositoryImplementation 只是一个占位符 实现接口 IManageRepository 并且您要创建其实例的类。这 只有你能知道的信息。

那就像Lajil Adel说的那样做:

public class MainClass
{
    private IManageRepository _memRepository;
    public MainClass(IManageRepository _memRepository)
    {
        this._memRepository = _memRepository;
    }
}

【讨论】:

    【解决方案3】:

    我会把你的问题分成两半,一个是基于你当前的方法,一个是更合适的。

    我意识到您尝试实现的目标是构建自定义身份验证挑战,并单独使用或与默认挑战结合使用。

    使用您当前的方法: 该属性不会像那样工作(你应该给它参数少的构造函数或只是一些常量标志来标记一些特殊的东西),否则你将不会获得本机 DI。编译器会这样对你大喊大叫

    Require constructor param right the moment you use it

    如果您想为了简单起见而保留您的方法,则必须先注册您的服务。

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddScoped<IManageRepository, ManageRepository>();
    }
    

    您可以将服务注册为单例或范围,具体取决于您手动创建 SqlConnection 的方式。

    然后像这样将服务从 HttpContext 中取出:

    public void OnAuthorization(AuthorizationFilterContext filterContext)
        {
            var manageRepository = filterContext.HttpContext.RequestServices
                .GetRequiredService<IManageRepository>();
        }
    

    你去...实现你的逻辑的其余部分。

    更好的方法:

    试一试authentication scheme,然后构建一个策略方案,为每个Action应用相应的方案,或者可能是整个控制器。

    这为您提供了一个在应用中描述您的身份验证/授权过程的中心位置,它更加清晰且高度适用于复杂的身份验证要求。

    将它与 redis 而不是 sqlConnection 结合起来会更好,并且对于生产环境具有可扩展性。

    【讨论】:

      猜你喜欢
      • 2017-04-01
      • 2013-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-15
      • 2020-04-13
      • 2013-04-19
      • 1970-01-01
      相关资源
      最近更新 更多