Is there a good way to change the aspnet_Users, aspnet_Membership, aspnet_Applications and other table names which are generated by the ASPNET SQL Server registration tool -
http://msdn.microsoft.com/en-us/library/ms229862%28VS.80%29.aspx#3
and change the reference to them in web.config or machine.config without breaking the default login, profiles and roles functionality that is provided by those tables?
If you really want that much control (btw, the OOB stuff works great), you might want to consider implementing your own Membership Provider
If you look in C:\windows\Microsoft.NET\Framework\v2.0.50727\
You can see the installation scripts used to create these tables/procs etc...
They are InstallMembership.sql etc..
You could back these up, change them then run aspnet_regsql.exe
I may be wrong but IIRC the standard implementation does not reference the tables directly. All DB calls go though stored procedures created by the same script that creates the tables. Just change the code inside the procedures. Should be easier (but not that elegant) than implementing a membership provider from scratch
Related
I have an existing ASP.Net Web Forms application which is using EF Code First with Existing Database i.e. I am using EF classes and DbContext to point to an existing database.
I want to give the project the functionality to create/edit tables/fields and just wondering if people can recommend the best way to do this. I can't use migrations because the project is used on several different servers/databases.
I thought about putting something in the Global.asax file in Application_Start using SqlCommand. Is this a good idea or can you suggest a better way to do this, preferably with EF?
I'm not sure what if any code would be helpful so please let me know if there is anything you would like me to add to the question.
EDIT:
Based on answers so far felt I should also note that I cannot directly access the servers the application is installed on because they belong to clients. Project is deployed locally, zipped and uploaded onto a site for their download.
When using EF Code First, you should use EF Code First Migrations, although you say it's impossible.
Your only reason not to use this is the multiple database servers. Do you use Distributed Transactions?
Otherwise, the only variable is the ConnectionString to the database server, and EF Migrations will do all the work for you to update your SQL schema.
It's probably a bad idea to do this as part of application startup - it'll require that the user that your application connects to the database with has escalated privileges in order to create/edit tables.
You can use migrations to initialise a database as part of a deployment process using the migrate.exe which is part of the EF NuGet package.
It's probably also useful to read a bit more around migrations - there is support for multiple contexts that can each be migrated separately...
Alternatively you could use a SQL script as part of your deployment process but then you'd need to manage the SQL by hand...
I created a login system for one MVC App based on the new Identity framework, and since I already went through all the hard work of modifying my database to match the Identity 2.0 requirements, I was wondering if it would be possible to use it outside of MVC, so I could reuse what I already created, like a login system for a desktop project that I'm working on for example. If so, can I implement the login system on a .dll that can be reused on other projects?
Yes, you could use your existing database for another application. Add the ADO.NET Entity Data Model, and point it to your database. Then, if you need to, select "Update Model from Database" and you should be all set.
Although, it may be just as easy to create your own user/roles tables. It's frustrating (to me) that Identity creates the Primary keys as strings, even though they are essentially Guids.
I'm really unsure about how to handle this.
What I think I need is to have the usernames people register with ( through the default Provider ) to be copied to the UserName column of my other database, which has a junction table for a many:many relationship between User and Badge.
I've tried using SQL to copy the table over, but that's not really working out, as I don't know what table exactly I'm supposed to copy..
Any help would be dearly appreciated, and if more info is needed, please ask!
I'm not sure what your circumstances are, but as you're saying that the users are registered through the default Provider, I guess that the tables may have been generated by the aspnet_regiis tool?
If so, the users are stored in a table called aspnet_Users and the user names are in the column UserName.
I may have misinterpreted your question, but is this what you were asking for?
This really depends on your requirements which aren't really clear. If you always want your data to be up to date in your other database then syncing by copying the whole table isn't the way to go.
If you don't mind that you get the usernames on a later moment in time then syncing is the way to go. For example if you use the other database for BI purposes only, then a simple job for example in the night will do fine. Like Christoffer said you will need the UserName column from the aspnet_User table for this.
Now if you want it to be always up to date then you have two options:
Hacky and not advised by me. Extend the stored procs which are called by the default membership provider by also updating the other database. For example you could alter dbo.aspnet_Membership_CreateUser. Check your database for all aspnet membership stored procedures.
Implement your own membership provider which calls your own stored procedures or the default stored procedures + additional queries for updating the other database. This one is the most work and would be my choice. For examples of custom implementations see this one and this one.
Both options will need you to get familiar with the asp.net membership infrastructure.
So I'm using Forms Authentication on my site, and I've set up all the tables and stored procedures in SQL Server. The only thing is, I really don't think I need all these tables, and I'm not a big fan of the table names either.
For instance, I'm using the authentication for employees, so it would be nice to change the table name from "aspnet_Users" to "Employees". And I don't really need the Personalization tables. But I don't know if that would break anything.
Is it possible to modify/delete tables and stored procedures without messing everything up?
Steven, I take it you ran the aspnet_regsql.exe command line tool to add these database objects? Alternatively, you can add just the necessary tables/views/stored procedures for different parts of Membership by running the applicable SQL scripts, which you'll find in the %WINDIR%\Microsoft.Net\Framework\version folder (where version is the .NET version you are using, like v4.0.30319).
There you'll find files named InstallCommon.sql, InstallMembership.sql, InstallRoles.sql, InstallProfile.sql, InstallSqlState.sql, and so on. You'll need to run InstallCommon.sql and then just those other files you need. So if you need just Membership and Roles, you'd run InstallCommon.sql, InstallMembership.sql, and InstallRoles.sql. In this way your database would not include the tables/views/sprocs for profile, SQL state, and so on.
All that being said, I'd just leave in all of the database objects that ASP.NET added. It's probably more work than it's worth to add just the subset of interest and, who knows, you may need to implement profile or Health Monitoring later so why not have these other database objects in place and
ready to go.
And to answer your first question - No, there is no way to change the table name from aspnet_Users to Employees. However, it's not uncommon to create your own table (perhaps called Employees) that stores information about an employee. This table, then, would have a foreign key back to aspnet_Users that links an employee to a particular login account. See Storing Additional User Information for a look at how this can be accomplished.
Happy Programming!
Why not write a simple SqlMembershipProvider?
Edit: No, the default providers expect that schema. I would not recommend modifying it.
Have you considered just leaving the authentication stuff in it's own database?
You can change all references to aspnet_Users to Employees in the .sql scripts mentioned by Scott Mitchell but it isn't recommended. The Membership / Roles API uses stored procs. So if you don't change storedProc names you will be fine.
The issues might be if any future changes to membership / Roles providers and/or API.
Also say in future you need to give access to some users who are not the Employees, the renaming will lose its meaning.
We are developing an ASP.NET MVC Application that currently uses it's own database ApplicationData for the domain models and another one Membership for the user management / membership provider.
We do access restrictions using data-annotations in our controllers.
[Authorize(Roles = "administrators, managers")]
This worked great for simple use cases.
As we are scaling our application our customer wants to restrict specific users to access specific areas of our ApplicationData database.
Each of our products contains a foreign key referring to the region the product was assembled in.
A user story would be:
Users in the role NewYorkManagers should only be able to edit / see products that are assembled in New York.
We created a placeholder table UserRightsRegions that contains the UserId and the RegionId.
How can I link both the ApplicationData and the Membership databases in order to work properly / having cross-database-key-references? (Is something like this even possible?)
All help is more than appreciated!
In my opinion, you should be able to integrate your database with the standard aspnet_db reliably, but I would advise against duplicating or replacing the aspnet_users table.
That is the focal point of all the providers that use the aspnet_db schema, including custom providers that may augment but do not implement custom replacement.
To maximize reuse of strong tested infrastructure code in the provider stack/API it is best to go with that flow.
You will want to be very attentive to any modified membership core functions and ensure that the way your new constraints behave in an expected fashion in each case.
The facet of the membership story that I have found needs the most attention is deleting a user, and a simple modification/addition to the delete user sproc can manage this capably.
It sounds like you might need to create your own customized Membership Provider. You can probably (not positive here) extend the existing one so you don't have to completely reinvent it. Here is a video from ASP.net that describes how to do that. Google "asp.net membership provider" for tons more.
You can try rolling your own membership or just extend is like Dave suggests.
Create your own [Users] Table which can be populated based off the aspnet_Membership table. So therefore you could have more control over it.
You could also just implement a more involved Profiles system. The .NET team has improved the way profiles are stored now, so instead of "blobicizing" them, you can set them up to be stored in an actual table now [thank god].
Table Profile Provider
If you find the right articles, it's really easy to extend the membership provider to allow for extra functionality. I've moved my users table to my main SQL server table and have written my own role manager that gets values from a separate table. What it sounds like you need to do is to set up a table in your users DB with the location of each user, then create a method on the user object something like "GetLocation()" that returns the user's location from the DB, you could then user that to filter your data from your main DB. Here's a few articles I had kicking aroundin my bookmarks, see if they help, if you have a look on the main ASP.NET site or google for membership provider extending articles, there are plenty around.
http://msdn.microsoft.com/en-us/library/ms998347.aspx
https://web.archive.org/web/20211020202857/http://www.4guysfromrolla.com/articles/120705-1.aspx
http://msdn.microsoft.com/en-us/library/aa479048.aspx
As the others have pointed out there are many good resources available that can help you with creating your custom provider using the existing database.
It looks like you are headed in the right direction with mapping tables. I think the one piece you are missing is Distributed Queries. This link is specific to Sql Server 2008. There is a link there to the documentation for Sql Server 2005 if that is what you are using.