TheMadMan
TheMadMan

Reputation: 21

C# MVC ASP.NET Identity - Dynamically change ApplicationDbContext connection string during runtime

I have 3 databases, one GlobalDb is used to manage and redirect users the correct database based on login details.

The other 2 databases are different to the GlobalDb but are the the same as each other. Lets call these 2 databases Company1 and Company2.

GlobalDb does not require the identity framework so it is just being connected to by using standard EntityFramework connections, the other 2 do required the Identity framework.

3 connection strings are saved in the web.config.

I can query all databases bases correctly, and they all return data. The main issue i am having is on login, how do i tell the SignInManager which connection string for the database to use?

IdentityModels.cs

public class CompanyDb : IdentityDbContext<ApplicationUser>
{
    public CompanyDb(string CompanyName)
        : base(CompanyName, throwIfV1Schema: false)
    {
    }

    public static CompanyDb Create(string CompanyName)
    {
        return new CompanyDb(CompanyName);
    }

    // Virtual class and table mappings go here.
}

AccountController Login

public async Task<ActionResult> CustomLogin(string Email, string Password, string returnUrl)
    {
        GlobalDb Global = new GlobalDb();

        // check what company the user belongs to based on email.
        var CompanyName = Global.Users.Where(u => u.Email == Email && u.Active == true).Select(u => u.Company).FirstOrDefault();

        // Connect to the desired database to get test data.
        CompanyDb Company = new CompanyDb(CompanyName);
        var DataTest = Company.Users.ToList();


        if (CompanyName != null)
        {
            var result = await SignInManager.PasswordSignInAsync(Email, Password, false, shouldLockout: false); // <-- How to connect to the correct DB?
            switch (result)
            {
                case SignInStatus.Success:
                    return RedirectToLocal(returnUrl);
                case SignInStatus.LockedOut:
                    return View("Lockout");
                case SignInStatus.RequiresVerification:
                    return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = false });
                case SignInStatus.Failure:
                default:
                    ModelState.AddModelError("", "Invalid login attempt.");
                    return View("");
            }
        }

        return View("");
    }

I keep getting a null value in the following file and function

IdentityModel.cs

 // You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
public class ApplicationUser : IdentityUser
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }
}

Upvotes: 0

Views: 1968

Answers (1)

TheMadMan
TheMadMan

Reputation: 21

Ive Figured it out.

On my login action if just wrapped the SignInManager within a Context Using statement as follows.

public async Task<ActionResult> CustomLogin(string Email, string Password, string returnUrl)
    {
        GlobalDb Global = new GlobalDb();

        // check what company the user belongs to based on email.
        var CompanyName = Global.Users.Where(u => u.Email == Email && u.Active == true).Select(u => u.Company).FirstOrDefault();

        if (CompanyName != null)
        {
            using (CompanyDb db = new CompanyDb(CompanyName))
            {
                var result = await SignInManager.PasswordSignInAsync(Email, Password, false, shouldLockout: false); // <-- How to connect to the correct DB?
                switch (result)
                {
                    case SignInStatus.Success:
                        return RedirectToLocal(returnUrl);
                    case SignInStatus.LockedOut:
                        return View("Lockout");
                    case SignInStatus.RequiresVerification:
                        return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = false });
                    case SignInStatus.Failure:
                    default:
                        ModelState.AddModelError("", "Invalid login attempt.");
                        return View("");
                }
            }

        }

        return View("");
    }

Upvotes: 2

Related Questions