How Get RoleID in ASP.NET MVC - asp.net

Is there any way to get RoleId without get directly from DB?, I know we can get role Names by:
string[] allRoles = System.Web.Security.Roles.GetAllRoles();
string[] allRolesForUser = System.Web.Security.Roles.GetRolesForUser(httpContext.User.Identity.Name);
But I need to access roleId.
Does any one have any idea about it?

No. The role provider have no knowledge about the data source. It can be a very slow web service or a super deluxe NoSQL database. The provider doesn't know that your db as a primary key.
Sure. The SqlMembershipProvider does. But having it exposing the key would likely lead to violations against Liskovs Substitution Principle.
The role name should be unique. So you should yourself be able to fetch it from the database. Or why can`t you simply use the role name directly instead of the db key?

You must add aspnet_Roles table to your model and use query (for example LINQ) to get roleId .You can change MembershipProvider but it need more work for doing it.

You can't. ASP.NET MVC doesn't allow to get RoleId with standard functon, you must get it from database with the help of role name.

I realize this is a few years old, but when i bumped into it I saw that noone actually answers completely answers the question ...so I thought I would post a full solution.
Soooo...
Simply put:
SELECT RoleId, RoleName FROM aspnet_Roles;
GO
But for getting RoleIds for a User it is like this:
SELECT UR.RoleID, R.RoleName FROM
aspnet_Users U, aspnet_Roles R, aspnet_UsersInRoles UR
WHERE U.UserName = #Username
AND UR.UserId = U.UserId
AND UR.RoleID = R.RoleId
GO
This will give you a 2 column list of RoleIds and RoleNames for a particular user.
In reality, you should not be trying to do this as there is a potential for Security breach when a RoleId is exposed. You should only work with RoleNames and use the Membership and Roles methods to manage things.
Hope this helps :)

Related

Entity Framework 4.1 - select Many to Many Association

I use Entity Framwork 4.1 and MVC 3. My question is about Join tables in Entity Framework.
I created three tables
User - UserId, Username
Role - Role Id, Rolename
UserInRoles- UserId, RoleId
I pulled these tables to my edmx file,
Only two tables appear i.e. the User and Role with a Many to Many Association between two.
If I want to get a user's role from UserInRoles table, What is the approach?
I did something like
var result = (from ar in roles
from au in users
where au.UserName == username
select new {});
This is not working. Please help.
As you guessed, the Entity Framework does combine simple look up tables like that into the parent tables in an effort to help you out. You won't be able to access the look up table in your code, but it will do the heavy lifting and allow you to navigate through the tables like such.
var result = (from ar in roles
where ar.Users.UserName == username
select ar);
Or if you prefer lambdas (personal preference):
var result = context.roles.Where(x => x.Users.UserName == username);
They should be linked I suppose:
var result =
from au in users
where au.UserName == username
select au.Roles;
Not sure if it will give you an empty collection by default. The Roles collection may have to be manually fetched. (Possibly result.Fetch(), but I'm not too familiar with it.)
(Or do you wat access to the actual UserInRole items that are stored in the database?)
Entity framework automatically generates a many to many relationship in the model, when there is only a relationshiptable with one shared primarykey that are foreign keys to other tables.
You can either add another column to this table to add it to your model or generate another unique key for the relationship.
Read more about this here :
http://learnentityframework.com/LearnEntityFramework/tutorials/many-to-many-relationships-in-the-entity-data-model/

Merging two ASP.NET membership databases

I have to merge two ASP.NET membership databases with related role and profile tables. Both databases have an identical role and profile structure. They use the built in providers (SqlMembershipProvider and friends). Duplicates are possible.
Do you have recommendations for me? Is there a tool to do this? If not: Can you recommend using the membership API or is it easier to use SQL.
Update
Here is the script I finally used to transfer the membership data.
insert into targetMembershipDatabase.dbo.aspnet_users
select * from sourceMembershipDatabase.dbo.aspnet_users
where username not in (select username from targetMembershipDatabase.dbo.aspnet_users)
insert into targetMembershipDatabase.dbo.aspnet_membership
select * from sourceMembershipDatabase.dbo.aspnet_membership
where userid in (select userid from targetMembershipDatabase.dbo.aspnet_users)
and not userid in (select userid from targetMembershipDatabase.dbo.aspnet_membership)
insert into targetMembershipDatabase.dbo.aspnet_profile
select * from sourceMembershipDatabase.dbo.aspnet_profile
where userid in (select userid from targetMembershipDatabase.dbo.aspnet_users)
and not userid in (select userid from targetMembershipDatabase.dbo.aspnet_profile)
insert into targetMembershipDatabase.dbo.aspnet_usersinroles
select * from sourceMembershipDatabase.dbo.aspnet_usersinroles
where userid in (select userid from targetMembershipDatabase.dbo.aspnet_users)
and not userid in (select userid from targetMembershipDatabase.dbo.aspnet_usersinroles)
Provided as is. No check for duplicate emails. No warranty that this is working in a more complex scenario.
I not aware of any tool which will do this, but the schema is pretty simple so it would be a straightforward enough job to just do it in SQL. All the keys are GUID anyway, so there shouldn't be a problem.
Obviously you'd need to check the user_name field for duplicates and email addresses, if the unique email address rule is applied. But if the roles are the same in both databases then all you're really interested in are the users. Once you've got them over it would just be a case of updating the RoleId and ApplicationId in aspnet_Users and aspnet_UsersInRoles.
I am currently use a single database for three different applications. Each of them has its own ApplicationID and nothing special happend for me withing this 2 years. even similar mails are available (because sql check the ApplicationID and in each application only you have one mail) so I don't think that you have to consider something special
Just create a script from data and run in your mainDatabase just not that don't replace the schema of Tables.

membership.deleteuser() returning false

I am trying to delete an asp.net user from all tables.
When I call:
bool isDeleted = Membership.DeleteUser(username, true);
isDeleted is being set to false;
Is there a way to tell why it is not deleting the user?
I found another reason why the user could not be deleted:
it happens also if you change (in the aspnet_Users) the UserName but not the LoweredUserName accordingly.
At least this is what happened to me:
as soon that I changed also the LoweredUserName I could finally delete the user.
Put a break point on that line of code and press F8 to step into it in debug mode.
Unfortunately it looks like when you delete membership user, even with deleteAllRelatedData=true
e.g.
Membership.DeleteUser(UserName.Text, true);
The user is NOT deleted from the dbo.aspnet_Users table which means that user cannot then re-register with the same name again (even though they will will have a different GUID)
I understand this is intended behaviour though it makes no sense to me.
However, the following routine will remove all traces from the aspnet database
CREATE PROCEDURE [dbo].[ASPNET_Member_DELETE_By_Name]
#UserNameToDelete nvarchar(255)
AS
BEGIN
DECLARE #UserToDelete nvarchar(255)
SELECT #UserToDelete = UserID
FROM aspnet_Users WHERE UserName = #UserNameToDelete)
DELETE FROM aspnet_Profile WHERE UserID = #UserToDelete
DELETE FROM aspnet_UsersInRoles WHERE UserID = #UserToDelete
DELETE FROM aspnet_PersonalizationPerUser WHERE UserID = #UserToDelete
DELETE FROM aspnet_Membership WHERE UserID = #UserToDelete
DELETE FROM aspnet_Users WHERE UserID = #UserToDelete
END
However, this has limitations if you are using aspnet membership across several applications (as I am) with the same database - you may have a situation where the same user logs in to multiple applicatiosn with the same user name.
For this scenerio you will need to pass in the application name and determine the application ID for the user prior to performing the delete.
First time I've posted here so be gentle...
The username is probably wrong - either the name doesn't match what's in the database, or the user isn't really in the database.
However, the ApplicationName could be wrong, or you could be pointed at the wrong Membership database by mistake.
The only other possibility that I can see is that you've modified the aspnet_Users_DeleteUser sproc and broke it.
Try removing the provider name, it worked for me by sending the username only.
I'm using SharePoint 3.0 with FBA, when a user is removed from SharePoint you can still find it in the FBA database. That's why I use this function as followed:
bool deleteUserResult = Membership.DeleteUser(currentUserLogin, true);
if (!deleteUserResult) throw new Exception("...);
hope this helps,
Damien

ASP.NET Membership Profile

I want to send out an email to all users where their birthday is today
I am using the built-in asp.net (3.5) membership. All users have a profile (stored in aspnet_Profile) which contains a date/time property called 'birthday'. I need to get a list of users email addresses from the 'aspnet_Membership' table where a users birthday is today, along with the users 'firstname' which is string property in the aspnet_Profile table.
I would like a list returned preferrably using C# LINQ.
I am not sure how to access the birthday property in the profile table, based on the way it is stored in the db table i.e name/value columns
I think you should consider changing to the much-improved table based provider:
http://weblogs.asp.net/scottgu/archive/2006/01/10/435038.aspx
This allows you to separate your data into one value per table column in the standard SQL way. This performs petter than the standard provider and it solves your problem of querying the Profiles database.
It will take a small amount of work to convert the database, but on the code side, it is just a matter of configuring in a different provider and nothing else should change. That is the beaurty of the provider pattern.
I don't use LINQ enough to give you a good answer, but the following may be the underlying SQL you need (This is how my SSMS generated it in the query designer):
SELECT aspnet_Profile.PropertyValuesString AS firstname, aspnet_Membership.Email
FROM aspnet_Profile INNER JOIN
aspnet_Membership ON aspnet_Profile.UserId = aspnet_Membership.UserId INNER JOIN
aspnet_Profile AS aspnet_Profile_1 ON aspnet_Profile.UserId = aspnet_Profile_1.UserId
WHERE (aspnet_Profile_1.PropertyNames LIKE N'birthday') AND (aspnet_Profile.PropertyNames LIKE N'firstname') AND (DATEADD(dd, 0, DATEDIFF(dd, 0,
aspnet_Profile_1.PropertyValuesString)) = DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE())))
The Profile mechanism parses the values out by splitting each name/value pair up, and then parsing them individually. You could write code to do that yourself. Or you could follow #Daniel's approach and use the alternative provider, which makes life easier. The out-of-the-box provider is a pain with the string concatenation.
Is this code in the same app? You could just use the profile object to retrieve it, if you are talking C#... what context is this piece of code in? Batch service?

Best database design approach to join complex data to ASP.Net Membership tables

I'm looking to use a slightly modified ASP.Net Membership Provider to handle the standard user account creation/authentication/etc in a website. We have a fair amount of legacy data that I need to migrate in order to provide continuity with our existing users' saved information (like order history, wishlist, etc). [NOTE: We have to migrate anyway, so this is not the reason we're migrating data]
I'm wondering what a sensible approach is for joining this additional data to the asp.net membership tables. There are a two unique keys that I could use on the user table - UserId or email - which we will use as a surrogate for username.
My question is, what is the better access pattern (and hence foreign key) to use elsewhere in my tables for storing orders, wishlists, etc?
In HttpContext, a User object is available that contains the "Username", our email address,
but doesn't have the Guid for userId available.
I see 3 options:
I'd like to simply use the uniqueidentifier UserId for efficiency of access over a lengthy varchar email address, but it doesn't appear readily available without extra database calls to fetch it via email/login. Is there some way to get the UserId so I can make it the foreign key on different tables?
I can pass in email address (username) as the input parameter, join on userId where email address = #emailAddress, and use userId as the foreign key on other tables.
Not viable
I can store username/email address on all the other tables as a foreign key - which would be an unfortunate denormalization
Any thoughts on a best method from either a DB perspective or from an application efficiency perspective?
You can get UserId:
MembershipUser myObject = Membership.GetUser();
string UserID = myObject.ProviderUserKey.ToString();
or maybe (please, check it)
string userId = Membership.GetUser(User.Identity.Name).ProviderUserKey.ToString();

Resources