I'm just starting a new project on ASP.NET MVC and this will be the first project actually using this technology. As I created my new project with Visual Studio 2010, it created to my sql server a bunch of tables with "aspnet_" prefix. Part of them deal with the built-in user accounts and permission support.
Now, I want to keep some specific information about my users. My question is "Is it a good practice changing the structure of this aspnet_ tables, to meet my needs about user account's information?".
And as i suppose the answer is "No." (Why exactly?), I intend to create my own "Users" table. What is a good approach to connect the records from aspnet_Users table and my own custom Users table.
I want the relationship to be 1:1 and the design in the database to be as transparent as possible in my c# code (I'm using linq to sql if it is important). Also, I don't want to replicate the usernames and passwords from the aspnet_ tables to my table and maintain the data.
I'm considering using a view to join them. Is this a good idea?
Thanks in advance!
EDIT: From the answer, I see that I may not be clear enough, what I want. The question is not IF to use the default asp.net provider, but how to adopt it, to my needs.
I would create custom membership provider and omit those aspnet_x tables completely. I've seen what happens when one joins these tables and custom ones with nhibernate mappings - pure nightmare.
If you are choosing to use the Membership API for your site, then this link has information regarding how to add extra information to a user.
I was faced with the same scenario recently and ended up ditching the membership functionality and rolled my own db solution in tandem with the DotNetOpenAuth library.
Using the membership system in asp.net has its advantages and drawbacks. It's easy to start, because you don't have to worry about validation, user registration, resetting passwords. (Be careful if you plan to modify the table structures, you will have to change them in the views/store procedures generated
However there are drawbacks to using Membership
You will have to maintain 2 separated systems, because the Membership API has restrictions, for example, you cannot perform operations inside a transaction with the membership api. (Unless you use TransactionScope i think, but you don't have other choices).
A valid alternative would be to implement your own security validation routines, and using FormsAuthentication. This way you will have total control over your users tables, and remove dependency to the membership API.
Related
We are looking to move our application to using the new SimpleMembership included in ASP.NET MVC 4 but we currently have multiple applications using the AspNet_Applications table of the old membership provider.
The reasons we are looking to move are the obvious ones, SimpleMembership is much smaller and we can map directly to our user table and also we want to start using OAuthWebSecurity.
Is there anyway to introduce this support by either extending SimpleMembershipProvider or even ExtendedMembershipProvider to allow multiple applications in the same database.
Alternatively should we just write our own membership which we can then use OAuthWebSecurity with without it using the webpages_ tables?
Would prefixing the username with an application name work?
Instead of user#example.com you would have 5|user#example.com or whatever format you chose. As long as you do this every time you read or write to the SimpleMembership table you'd be fine.
Create your own little abstration wrapper and I think you should be good to go. If you find any issues would be interested to hear them since I'm considering doing this myself too.
Though I asked few questions about the how to use membership providers with ASP.NET MVC 4 but hardly got any response. It is taking me time (as a newbie) to get started with membership providers in ASP.NET MVC 4. I have been reading article, trying stuff but that only added to the confusion rather than helping.
What would be the answers to the following queries by a beginner:
I want to try all the membership providers (including the simple membership provider) before deciding which one should I use for which project. What membership providers can I use with ASP.NET MVC 4 and How can I configure each one of it. Any documentation or links?
Though the internet template comes with pre-configured Account controller which sets the membership functionality, but how can I add membership functionality to the basic template. What steps should I follow in order to configure membership using membership providers (I assume there will be different set of steps/configuration/settings for different membership provider).
Running the ASP.NET MVC 4 project created with internet project template (without making any changes to it) create 5 tables in the database namely UserProfile, webpages_Membership, webpages_OAthMembership, webpages_Roles, webpages_UsersInRoles). In AccountModel.cs I see definition for only one, UserProfile. Where are the other tables defined. Do I always need to have all these tables in database in order to use membership. Can I customize them, rename them or choose not to use some of them?
I do not see any membership configuration in web.config for the internet project template yet is using membership. In some of the articles tutorial I saw people configuring it by adding <membership></membership> to web.config. When do I need to add configuration settings to web.config and when do I need not?
I think membership providers are meant to make developers life easy yet for me it is making it more difficult.
I know I really need to study it and that's what I am trying for the last 7, 8 days but unable to figure out.
Any help, links (hopefully not those which I went through many times) are more than welcome.
I agree with you, the guidance around what membership types do what just sucks.
You can use any of the providers with ASP MVC. The default template in Visual Studio that is the Internet MVC app is the only one that uses SimpleMembership.
Good question, I've not found any explicit, decent documentation on that at all. As far as I can tell most of the membership things are setup very similar.
At least SimpleMembership will create the needed DB tables that are required if they do not exist. I think the only one you can really customize is your user table.
I think like the sql tables, the membership tags in the web.config are implied. If you accept the defaults they magically work.
Best link I've found is this
http://blog.longle.net/2012/09/25/seeding-users-and-roles-with-mvc4-simplemembershipprovider-simpleroleprovider-ef5-codefirst-and-custom-user-properties/
In that post there are two others that are helpful as well.
For question 3, I tried something and it turned out that:
Yes: You can add new columns to UserProfile (and all other tables, I guess)
No: You cannot rename the table, even if u have modified the codes in AccountModels to match new table names.
In this case, a set of tables with old names will be created again when you launch application. And all codes provided by MVC4(MembserShip, WebSecurity, Users, Roles....) will used the old tables.
And, I have never found any information about how to rename these tables.
I am trying to understand how I can create an ASP.NET MVC site that exists as a VS2010 project in a solution, and then for multiple "tenants" I would create a site that inherits from that one. That would give the flexibility of adding modular features to one without affecting another one, and both could benefit from core library optimizations.
Is that a crazy idea? What patterns exist for that kind of thing? I have done something similar for a webform-based site (adding DLLS as plugins), but not in MVC.
A "tenant" is a business client. Each already has their own MSSQL database and seperate processing around them, each client is in its own silo. The databases are similar with a few features added here and there, they are versioned and deployed seperately, that whole process works well. A client has n logons. I want to develop a single "base site" that can then be used to give function to a tenant, and all activities are segerated for a tenant to a single database. Where things get ugly is how I can add a new component (say a forum) to one tenant site without mucking up the site experience for other tenants.
All ideas appreciated. Thanks.
I have worked extensively on the development of a multi-tenant web application. Here are three basic pointers to help you get started:
Security
The TenantId is part of the login credentials. These are stored in the Thread.CurrentPrincipal. This effectively binds each request (thread) to a specific user and thus tenant. Thread.CurrentPrincipal can be easily accessed from any code.
Database
We used a single database to store all data. A separation was made between tables (entities) that were specific for one tenant (multi-tenant), and tables that were not (cross-tenant). Tables that were multi-tenant had a column called 'TenantId'. In our entity model, we made sure these entities inherited from a special IMultiTenant interface. This interface contained the C# equivalent of the TenantId field. We extended the architecture of Entity Framework to provide default filtering on TenantId for multi-tenant entities. This ensured that one tenant could never access or modify the data of another tenant.
Plugins
We used a bit of Dependency Injection trickery in order to support the implementation of tenant specific code. Based on the current TenantId, our DI container injects a tenant-specific implementation of that interface.
For my ASP.NET MVC app, I just find dealing with unique-identifiers harder, so I have added my own field to ASPNET_USERS table - UserIdInt (which is actually a bigint!) So most of user operations use userIdInt as reference.
Anyway, I am debating between two approaches:
1)When a user logs in, look up from the database and store the userIdInt in a session variable and any-time session variable slips away, re-look it up and put it back in session variable. (It's okay to use sessions in MVC app, right?)
2)Any time an operation needs to be performed, simply pass userName to database and take care of UserIdInt at database side by doing joins and such on ASPNET_Users table any time an operation from user needs to be performed.
I am heavily leaning towards 1)... but I want to make sure I am on right track.
I asked this question on Serverfault first, but I was told to ask this question here.
progtick,
you may be far better looking into the use of custom profile providers as this would allow you to leave the aspnet_* tables as is (which is a good idea in case a later version of sqlserver changes how they operate) plus offer the additional bebnefit of having a multitude of additonal profile related properties availabale to your application. i can't overstate enough the benefits in going down this track as i've found it very useful to have such an approach in both my standard asp.net apps as well as my mvc ones.
you can get a feel for what's involved in this by looking thro a couple of these links:
here's one on SO for starters:
Implementing Profile Provider in ASP.NET MVC
and one from my old mate, lee dumond:
http://leedumond.com/blog/asp-net-profiles-in-web-application-projects/
hope this helps
An alternative approach is to alter the forms authentication ticket to add your unique id to the data stored in the cookie. Then, by implementing a custom IPrincipal you can have your unique id available anywhere that the User object is available.
I'm in a bit of a conundrum here and I'm hoping for some of you Guru's to help fill in the blanks.
The situation I'm currently facing is with regards to my "Users" table and my "OpenID" table. My app allows for a user to have multiple OpenID's, so I keep track of them in a separate table.
Users
ID
Username
OpenID
ID
UserID
Claimedidentifier
I have a CRUD repository for each table, and I also have a Service that interfaces with the Repository (one service per repo).
The question I have is with regards to inserting a new user (since updating will follow the same principal). Here are the options that I have in my head.
Have the UserService insert a new user, retrieve the user's ID and then insert a new OpenID using the UserID
Have the UserService send the new user along with the ClaimedIdentifier to the UserRepository, and have the repository insert both the User and the OpenID (this doesn't fit the CRUD methodology very well)
Create a View of both the User table an the OpenID table, create a UsersOpenIDRepository and a UsersOpenIDService, and then insert to the View.
Any other thoughts or suggestions beyond what I can think of will be greatly appreciated.
Please note, I am not using NHibernate whereby I can model my domain however I see fit. I am sticking to Linq to SQL on this project,
In my experience Linq2SQL does not fit the CRUD methodology very well anyway. Making it fit means jumping through too many hoops to be really worth it. The problem you are describing isn't even the one only one - it gets even worse when updating entities.
Therefore I opted for solution 2 (inserting both entities in the usersrepostory) in my current project.
I also gave up on update methods for the repositories. Unstead my repositories simply have a SubmitChanges method which must be called after all updates are performed on loaded entities. All repositories created in the same web request share the same DataContext, so it doesn't really matter which repository I call Submitchanges on. It's not CRUD, but it lends itself much better to the LINQ2SQL way of performing database updates.
If you really absolutely want pure CRUD, you might want to check out EF with the POCO entity generation template.