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.