Dynamically connect to different databases in a hybrid multitenant solution - asp.net

I was researching about multi-tenancy and multi-instance approaches and chose a hybrid.
I keep a single instance of my ASP.Net MVC 2 application but clone the database structure for each client. I am using LINQ to SQL.
Right now, I have one instance of both so just a single connection string is working.
I am planning to expand it for many clients.
I can write code to create a clone of the database structure, create a db user and give permissions whenever a new client signs up. I also will save all these details (db name, db user, allowed app users) in a table.
But how can I make the app use a different database based on who is logged in?
I can't even figure out the approach I should take to do this. Should I programmatically add connection string to web.config? Is there another way to do this?

One of the constructors for DataContext accepts the connection string. You can assemble this string based on the user for the specific request.
This will override the default connection.

Check the constructor overloads for the DataContext, there is one that takes connection string. You just need to map a string property against the logged in user.
Please don't programmatically add EVERY user's connection string to web.config, think scalability!!!

Related

Multiple Database Usage, Second Connection After Login

There is a scenario like in the picture. There is a common database. Customers are connecting to the same database. After the connection, company-specific information is kept in a separate database. The connecting string is pulled from the company information in the database after the user logs in. How can I do this logic in .net core. I'm new and need ideas.
Click to see the script
When the user logs in, company information is also taken as in the picture.
Click for user company information
I can't define it in the "startup.cs" file because the user needs to be logged in.
Where and how can I define the connecting clause? Can you give an idea?
Startup.cs file
appsettings.json file
login method
In the login method, I need to migrate first. To create the tables. If there are tables, I need to connect to the company's product table. Can this special link be added to swagger too?
Specifically within .net core project you can utilise DBFactoryBase class, and create a constructor which accept appsettings json key to fetch another connection string.

Change Entity Framework Context Connection String Based On Logged in User

I've been struggling with this one for quite some time and have been unable to find a good solution. I'm using the code first method, and this is what I'm trying to accomplish:
First, when a user logs into the application, I authenticate him and retrieve his connection string from a company table in a membership database.
Next, I want to use this connection string for the dbcontext. Each company has it's own database with the same structure.
Here are two things I'd like to avoid:
I don't want to pass the connection string to the context constructor because this is an existing app and there are several calls.
I don't want to use session because the library is shared with a windows service app that loops through the connections in the company table to perform data imports.
Any suggestions? Any help is appreciated. Thanks.

SignalR on ASP.NET MVC and Multiple User Types

I am currently in the process of sketching-out an application that allows real-time interactions with website visitors.
Therefore, I have two different "User-types":
Unregistered User: these are the visitors
Registered User: these have a (custom) ASP.NET MVC membership
Now, I am persisting "UserNames" and ConnectionIds in a DB so I can freely scale at some point in the future. I do this by accessing Context.Identiy.User.UserName from within the Hub and then query the DB for any existing "sessions".
Here is the problem:
I need two different types of "User"
For one, I want to dynamically generate a GUID - these are the visitors and will be removed from the database after a given amount of inactivity.
These are the admins, they have their proper identities attached to the Context object.
So, how would one go about accessing a "session" from SignalR? It is not really a Session, I just need to get a SessionId from a Cookie on each initial request to the MVC-Controller, that's all. All I need to be able to do is:
Have an auto-generated "SessionId" which I can use to persist visitors across requests
Have a more "extended" identity: I want to use UserId instead of UserName
Anyway, I hope this makes sense but chip in if anything is unclear.
Okay, I just realised that I can use "HttpContext.Current.Request.AnonymousId" and I am linking this up to a Session-database.
Here some relevant documentation: http://msdn.microsoft.com/en-us/library/system.web.httprequest.anonymousid.aspx
This solved my problem in this case. :-)

How to log inserts, updates in SQL Server?

I am wondering what would be the best practice to logging when a user inserts or updates some data from my ASP.NET application.
In my application I need to know which user made the change, I think I have to options:
Register my ASP.NET users into the SQL Server adding them the rights for the tables needed, and store for each of my users
individual connectionstring. Thus I could use the currently logged in
user's connectionstring when connecting to the database, so that I
could write T-SQL triggers for SELECT and UPDATE.
The other option I thought of is that I can write stored procedures that get the ASP.NET user name as input parameter and makes
the log for me, (I use only one connectionstring in the application).
After modifying the database from the application I would call this
procedure giving the currently logged in user's username.
The second option seems simpler to me, but I think that for that purpose I should choose the first option.
Go for the second option. Managing users in a database creates more of a headache for you and what happens if you have to move the database server? You would need to update all of the connection strings for all the users. It just creates an extra admin overhead.
Furthermore, if you need to log all the changes in the database then I have come up with something that I have used in the past to store all changes made to a database over time. Have a look, it might be useful.
http://richhooper.wordpress.com/2012/06/11/sql-server-row-level-versioning/

Asp.net override Membership settings at runtime (asp.net mvc)

I had an application that hooked onto 1 single database.
The app now needs to hook into multiple databases. What we want to do is, using the same application/domain/hostname/virtual dir give the user the option on the login screen to select the "App/Database" they want to connect into.
Each database has the App tables/data/procs/etc as well as the aspnet membership/roles stuff.
When the user enters the username/password and selects (select list) the application, I want to validate the user against the selected applications database.
Presently the database connection string for membership services is saved in the web.config. Is there any way I can override this at login time?
Also, I need the "remember me" function to work smoothly as well. How does this work when the user comes back to the app in 5 hours... This process should be able to identify the user and application and log in appropriately.
The only way possible is to change the conn string via reflection:
// Set private property of Membership provider.FieldInfo connectionStringField
= GetType().BaseType.GetField("_sqlConnectionString", BindingFlags.Instance | BindingFlags.NonPublic);
connectionStringField.SetValue(this, connectionString);
Found here:
http://forums.asp.net/p/997608/2209437.aspx
Why not just implement your own membershipprovider? Very easy to do and then you have full control of whats happening. I'm sure you'll come up with another custom scenario the default provider doesn't work well with.
AFAIK the remember me function should work exactly how your describing as long as the user doesn't delete their cookies.
Below is a link to an example using multiple connection strings for your membership providers.
ASP.NET Forum - Multiple Providers

Resources