Search code examples
c#asp.net-mvc-4repositorysession-variablesmultiple-databases

Validating session variable at the model Repository MVC 4 code first


I have multiple databases linked to the same db context and I pass the connection string which is saved in a session variable to the db context. In order to make the application more robust, I would like to validate whether the session variable is null or not.If it is null then redirect the user to the login page.

I don't seem to find out a way to do that. I often hits following error at the Repository when trying to pass the connection string. It never reaches the error handling part.

What wrong am I doing here?

System.NullReferenceException: Object reference not set to an instance of an object.

Following is my code.

DbContext:

public class AppContext : DbContext
{
    public AppContext()
        : base()
    {

    }

    static AppContext()
    {
        Database.SetInitializer<AppContext>(null);
    }

    public AppContext(string connectionKey)
        : base("Name =" + connectionKey)
    {

    }

    public DbSet<App.Models.Contact> Contacts { get; set; }
}

Model Repo:

public class ContactRepository : IContactRepository
{
    // Following line generates the error.
    AppContext context = new AppContext(Helpers.GetSessionKey("_ConnectionString").ToString());

    public IQueryable<Contacts> All
    {
        get { return context.Contacts; }
    }
}

Helper Method:

internal static class Helpers
{
    public static object GetSessionKey(string key)
    {
        if (HttpContext.Current.Session != null)
        {
            return HttpContext.Current.Session[key];
        }
        else {
            // This never fires.

            // Handle the error.
        }

    }
 }

Solution

  • You should absolutely not be interacting with HttpContext inside your repository. I'm really surprised things haven't imploded on you long before now. If you need a value from Session for your context, that's fine, but you should simply pass in that value when newing up your repository/context. For example:

    public class ContactRepository : IContactRepository
    {
        private readonly AppContext context;
    
        public ContactRepository(string connectionString)
        {
            context = new AppContext(connectionString);
        }
    
        ...
    

    Then, in your controller, the only place you should be working with something like HttpContext, you can do something like:

    var repo = new ContactRepository(Session["_ConnectionString"] ?? "Default Connection String Here");
    

    That way, there's no leakage of the request context into your data layer.