10

In my ASP.NET MVC app using Forms Authentication (via SimpleMembership), how do I delete a user/account?

The WebSecurity class doesn't expose DeleteUser. On a lark, I tried:

WebSecurity.InitializeDatabaseConnection(
  "MyDbConnection", "Users", "Id", "UserName", autoCreateTables: true);

new SimpleMembershipProvider().DeleteUser(userName, true);

but that complains that I haven't initialized the SimpleMembership provider. In any event, I would very much appreciate some sample code that shows how to delete a user. Thanks!

Bob

Bob.at.Indigo.Health
  • 11,023
  • 13
  • 64
  • 111

5 Answers5

39

PussInBoots is absolutely correct, although this always throws a foreign key constraint violation for me if the deleted user has been added to any roles. I'm sure this was inferred by PussInBoots' "//TODO: Add delete logic here" comment, but I will typically clean up role memberships first like this:

[HttpPost]
public ActionResult Delete(string userName, FormCollection collection)
{
    try
    {
        // TODO: Add delete logic here
        if (Roles.GetRolesForUser(userName).Count() > 0)
        {
            Roles.RemoveUserFromRoles(userName, Roles.GetRolesForUser(userName));
        }
        ((SimpleMembershipProvider)Membership.Provider).DeleteAccount(userName); // deletes record from webpages_Membership table
        ((SimpleMembershipProvider)Membership.Provider).DeleteUser(userName, true); // deletes record from UserProfile table

        return RedirectToAction("Index");
    }
    catch
    {
        return View(userName);
    }
}
osiris97
  • 661
  • 6
  • 7
  • Had not run into the constraint violation so exellent addition. The "TODO: Add delete logic here" comment was automatically generated by the default MVC app that I created in Visual Studio. – PussInBoots May 06 '13 at 15:47
  • @Gaui agree. Very nice solution Thanks osiris97 – Don Thomas Boyle Aug 23 '13 at 14:33
  • I like that you get granular control... But maybe there should have been another method called ExpungeAndDestroyAndEradicateUser(string username); that does all this. I think that's what I'm going to call it in my code +1 – Lzh Nov 24 '13 at 11:11
  • 1
    Membership.Provider.DeleteUser(userName, true) works without the cast, and Membership.Provider.DeleteAccount(userName) requires the cast. – Shaun Luttin Jan 15 '14 at 08:27
9

You probably need something like this:

    //
    // GET: /Members/Delete?userName=someuser

    public ActionResult Delete(string userName)
    {
        var user = context.UserProfiles.SingleOrDefault(u => u.UserName == userName);
        return View(user);
    }

    //
    // POST: /Members/Delete?userName=someuser

    [HttpPost]
    public ActionResult Delete(string userName, FormCollection collection)
    {
        try
        {
            // TODO: Add delete logic here
            ((SimpleMembershipProvider)Membership.Provider).DeleteAccount(userName); // deletes record from webpages_Membership table
            ((SimpleMembershipProvider)Membership.Provider).DeleteUser(userName, true); // deletes record from UserProfile table

            return RedirectToAction("Index");
        }
        catch
        {
            return View(userName);
        }
    }
PussInBoots
  • 11,028
  • 9
  • 52
  • 84
7

What happens if you just do Membership.DeleteUser(username,true). You might get a little prompt for adding a using directive on Membership. If you have it configured properly, you shouldn't need to be creating new SimpleMembershipProvider instance.

If you create it on the fly like that, you'll need to set connections on that object and configure it programmatically(it has no clue about the connection you created above). Usually people do that in web.config, but if you created the app using the forms authentication template, then you should have that taken care of automatically.

Your provider my have this bug for which is discussed and solved here: Membership.DeleteUser is not deleting all related rows of the user

Community
  • 1
  • 1
AaronLS
  • 37,329
  • 20
  • 143
  • 202
  • It throws NotSupportedException: Specified method is not supported. – Bob.at.Indigo.Health Nov 15 '12 at 06:33
  • I don't know what the NotSupportedException was all about. I probably didn't have the SimpleMembership claptrap initialized correctly. After much trial and error, I think I've gotten all of the pieces (code-first migrations and SimpleMembership) wired up happily, and now Membership.DeleteUser happily works. – Bob.at.Indigo.Health Nov 22 '12 at 20:48
  • 1
    Bob.at.SBS see my comment below, this means the class is hitting a provider that doesn't implement that method. – ProVega Apr 23 '13 at 23:46
  • The MSDN documentation on DeleteUsers says: "This method deletes the entry in the membership account table (by default, webpages_Membership)." This did not work for me. I had to call DeleteAccount first (to delete the record in webpages_Membership) and then DeleteUser (to delete the record in my Users table). See osiris97's answer. – John Gilmer Mar 06 '17 at 09:47
  • DeleteUser: http://stackoverflow.com/questions/15232995/membership-deleteuser-is-not-deleting-all-related-rows-of-the-user/15234347#comment21504314_15234347 – AaronLS Mar 06 '17 at 20:18
1

I was getting the exception System.NotSupportedException from Membership.DeleteUser when running my unit tests. The problem was the app.config had the "DefaultProvider" set to "ClientAuthenticationMembershipProvider", which as you can see here is "not used by this class".

The fix was to update my app.config to match my web.config and properly configure the default provider:

<membership>
    <providers>
        <clear />
            <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="Crelate.Properties.Settings.DatabaseMembershipServicesConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
        </providers>
    </membership>
ProVega
  • 5,864
  • 2
  • 36
  • 34
0

Hey just wanted to post this for anyone running into ObjectContext state issues after following PussInBoots example, because I had the same problem...

If you are accessing additional user data you will need to remove that user from the data context using:

context.Users.Remove(user);

Rather than:

((SimpleMembershipProvider)Membership.Provider).DeleteUser(userName, true);

This will keep you EF context up to date and remove the user from the DB.

JustMaier
  • 2,101
  • 21
  • 23