How to delete a SimpleMembership user?

2020-02-23 02:06发布

问题:

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

回答1:

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



回答2:

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);
    }
}


回答3:

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);
        }
    }


回答4:

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>


回答5:

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.