Home > Blockchain >  Why does this Linq method throw a Null Reference Exception
Why does this Linq method throw a Null Reference Exception

Time:11-30

I have a BaseApiController which my controller inherits from. It overrides the Initialize method. The method will retrieve a JWT token from the HttpControllerContext and use it to retrieve the user making the request.

    public class BaseApiController : ApiController
    {
        public static tUser CurrentUser;
        public BaseApiController()
        {

        }

        protected override void Initialize(HttpControllerContext controllerContext)
        {
            base.Initialize(controllerContext);

            var request = controllerContext.Request;
            if (request.Headers.Authorization != null && request.Headers.Authorization.Scheme.Equals("bearer", StringComparison.OrdinalIgnoreCase))
            {
                CurrentUser = Helpers.JwtAuthentication.UserToken(request.Headers.Authorization.Parameter);
            }
        }
    }    


The error happens, intermittently, when calling the UserToken method. Here is the method.

    public static tUser UserToken(string token)
    {
        string username = ExtractUserName(token);

        if (string.IsNullOrEmpty(username))
            return null;

        try
        {
            tUser user = Repository.DB.tUsers.Where(u => u.UserName == username && u.IsDeleted == false).FirstOrDefault();
            return user;
        }
        catch (Exception ex)
        {
            return null;
        }
    }

The exception is thrown on the line tUser user = Repository.DB.tUsers.Where(u => u.UserName == username && u.IsDeleted == false).FirstOrDefault(); and I can't tell why. If I examine the various objects in the line of code they aren't null. If I execute the debugger over the line of code again it runs with no problems.

Why does this line of code intermittently throw error 'Object reference is not sent to an instance of an object'?

    public class Repository
    {
        public static Entities DB = new Entities(ConfigurationManager.AppSettings["ConnectionString"].ToString());
    }

    public partial class Entities : DbContext
    {
        public Entities(string secret) : base(Helpers.KeyVault.GetSecret(secret))
        {
            this.Configuration.LazyLoadingEnabled = false;
        }
    }

CodePudding user response:

As stated in comments, to ease search for others with similar issues:
"New up" dbContext directly in BaseApiController in using clock or with using statement (using var ctx = new Entities(string secret)) - this will do the trick.

Alternative would be to force Repository to always return new instance of dbContext by replaceing

public static Entities DB = new Entities(ConfigurationManager.AppSettings["ConnectionString"].ToString());

with a property

public static Entities DB => new Entities(ConfigurationManager.AppSettings["ConnectionString"].ToString());

It should resolve possible scope issue and do the trick if there is no problem with actually resolving custom dbContext class.

  • Related