membership.deleteuser() returning false - asp.net

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

Related

How Get RoleID in ASP.NET MVC

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 :)

How to manually change password in asp.net membership?

I would like to change password in database manually, but I am not sure what exactly I need to change and which methods to use. I would change it via code but currently I have only access to db.
If you want to change the password directly through the database, you are going to need to create a new user or find an existing user that you know the password of. Then, you'll need to get the password and salt, then update the user in question with the same password and salt.
Get the user's password/salt:
SELECT
au.username, aa.ApplicationName, password, passwordformat, passwordsalt
FROM
aspnet_membership am
INNER JOIN
aspnet_users au ON (au.userid = am.userid)
INNER JOIN
aspnet_applications aa ON (au.applicationId = aa.applicationid)
WHERE
au.UserName = '[user to change password]'
Change the password:
DECLARE #changeDate DATETIME
SET #changeDate = GETDATE()
EXEC aspnet_Membership_setPassword
'applicationName',
'user',
'password',
'passwordsalt',
#changeDate,
Passwordformat
Taken from here...
See this page: https://learn.microsoft.com/en-us/aspnet/web-forms/overview/older-versions-security/admin/recovering-and-changing-passwords-cs
The code calls a stored procedure:
Like with the other methods in the Membership framework, the ResetPassword method delegates to the configured provider. The SqlMembershipProvider invokes the aspnet_Membership_ResetPassword stored procedure, passing in the user's username, the new password, and the supplied password answer, among other fields. The stored procedure ensures that the password answer matches and then updates the user's password.

I need help with sql and data relation tables

i building a mini forum site.. and i constructed a few tables.
1) Users
2) Threads
3) Comments
4) Topics
i build a function that would insert a comment each time a user would submit a comment:
string saveComment = "INSERT INTO Comments(";
saveComment += " UsersID, ThreadsID, Date, Comments, CommentResponse";
saveComment += "Values('" + "','";// no idea what to insert in the UsersID
saveComment += "" + "','";// no idea what to insert in the ThreadsID
saveComment += DateTime.Now + "','";
saveComment += CommenttxtBox.Text + "','";
saveComment += commentResponseString + "')";
As you can see the fields have UsersID and ThreadID, both connected by a foreign key to the comments table.
Now, each time the user submits a comment, i guess i need to insert also to the UsersID field (which is an int in the comments table, and that field increases incrementally by 1 in the Users table). How can i insert a comment, and notify the other table not to increase the UserID by 1. in fact i want it the UserID to stay the same for each user submitting a comment..
How do i do that? i need to insert to a few fields in one table (comments) but keep the other tables informed that it is actually the same user who submitted the comment .
Note: i dont know any vb, only c#, and i use visual studio 2010. asp.net
BTW, the way you are inserting is a security issue, you could get SQL injection ...
Use the system.data.sqlclient.sqlparameters to passe values.
You are creating a very standard normalised structure. Your Users table will be responsible for controlling the UserID values that are generated.
You have two situations to cope with when inserting new comments:
The User exists and is logged in.
The User does not exist and is anonymous.
In the first situation, when you are inserting the comments you will not need to bother looking at the Users table. This assumes you have the UserID already loaded (as the user is logged in).
In the second situation, you will first need to a new row to the Users table and return the UserID that the table generates (assuming you are using an identity column). You can then pass this value to the Comments table.
The following script is an example of addressing the second situation:
DECLARE #userId int
INSERT INTO Users (Username, FirstName)
VALUES ('adamh', 'Adam')
SET #userId = SCOPE_IDENTITY()
INSERT INTO Comments(UserId, ThreadId, Comment)
VALUES (#userId, 1, 'My comment')
If you want to continue with your current coding style, simply concatenate the values into the relevant parts of the string.
However, with such as neatly defined structure as the one you have, I'd advise using something like Entity Framework 4.0, or LINQ to SQL, which cuts a lot of plumbing out once you have defined your structures.

Handling Constraint SqlException in Asp.net

Suppose I have a user table that creates strong relationships (Enforce Foreign Key Constraint) with many additional tables. Such orders table ..
If we try to delete a user with some orders then SqlException will arise.. How can I catch this exception and treat it properly?
Is this strategy at all?
1) first try the delete action if an exception Occur handel it?
2) Or maybe before the delete action using code adapted to ensure that offspring records throughout the database and alert according to .. This piece of work ...
So how to do it?
--Edit:
The goal is not to delete the records from the db! the goal is to inform the user that this record has referencing records. do i need to let sql to execute the delete command and try to catch SqlException? And if so, how to detect that is REFERENCE constraint SqlException?
Or - should I need to write some code that will detect if there are referencing records before the delete command. The last approach give me more but its a lot of pain to implement this kind of verification to each entity..
Thanks
Do you even really want to actually delete User records? Instead I'd suggest having a "deleted" flag in your database, so when you "delete" a user through the UI, all it does is update that record to set the flag to 1. After all, you wouldn't want to delete users that had orders etc.
Then, you just need to support this flag in the appropriate areas (i.e. don't show "deleted" users in the UI).
Edit:
"...but just for the concept, assume that i do want delete the user how do i do that?"
You'd need to delete the records from the other tables that reference that user first, before deleting the user record (i.e. delete the referencing records first then delete the referenced records). But to me that doesn't make sense as you would be deleting e.g. order data.
Edit 2:
"And if so, how to detect that is REFERENCE constraint SqlException?"
To detect this specific error, you can just check the SqlException.Number - I think for this error, you need to check for 547 (this is the error number on SQL 2005). Alternatively, if using SQL 2005 and above, you could handle this error entirely within SQL using the TRY...CATCH support:
BEGIN TRY
DELETE FROM User WHERE UserId = #MyUserId
END TRY
BEGIN CATCH
IF (ERROR_NUMBER() = 547)
BEGIN
-- Foreign key constraint violation. Handle as you wish
END
END CATCH
However, I'd personally perform a pre-check like you suggested though, to save the exception. It's easily done using an EXISTS check like this:
IF NOT EXISTS(SELECT * FROM [Orders] WHERE UserId=#YourUserId)
BEGIN
-- User is not referenced
END
If there are more tables that reference a User, then you'd need to also include those in the check.

Community server Username issue - User Username not found in membership store does not exist

I have an error occuring frequently from our community server installation whenever the googlesitemap.ashx is traversed on a specific sectionID. I suspect that a username has been amended but the posts havn't recached to reflect this.
Is there a way a can check the data integruity by performing a select statement on the database, alternatively is there a way to force the database to recache?
This error could be thrown by community server if it finds users that aren't in the instance of MemberRoleProfileProvider.
See CommunityServer.Users AddMembershipDataToUser() as an example
UPDATE:
I Solved this problem for my case by noticing that the usernames are stored in two tables - cs_Users and aspnet_Users. Turns out somehow the username was DIFFERENT in each table. Manually updating so the names were the same fixed this problem.
Also, the user would left out of membership in the following line of the stored procedure cs_Membership_GetUsersByName:
INSERT INTO #tbUsers
SELECT UserId
FROM dbo.aspnet_Users ar, #tbNames t
WHERE LOWER(t.Name) = ar.LoweredUserName AND ar.ApplicationId = #ApplicationId
The #tbNames is a table of names comes from cs_Users(?) at some point and therefore the usernames didn't match and user was not inserted in to the result later on.
See also: http://dev.communityserver.com/forums/t/490899.aspx?PageIndex=2
Not so much an answer, but you can find the affected data entries by running the following query...
Select *
FROM cs_Posts
Where UserID Not In (Select UserID
From cs_Users Where UserAccountStatus = 2)

Resources