0

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.
        }

    }
 }
ecasper
  • 489
  • 1
  • 10
  • 30

1 Answers1

2

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.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
  • Thanks for the answer. It sounds like a mass modification to the application and I'm sure there are more than 1000 places where repoes have been used. – ecasper Nov 03 '14 at 06:53
  • 1
    That doesn't negate the need to make the change though. You can use find and replace or a good refactoring tool to ease the pain, but leaking your web context into classes that have nothing to do with it, is going to cause you a heap of problems in n the long run. – Chris Pratt Nov 03 '14 at 15:05
  • By the way I changed all the repos as you suggested. But I still seem to have the same issue. how do you think I can terminate GetSessionKey class being executed any further if there is an error? – ecasper Nov 04 '14 at 17:54