-1

I have an ASP.NET application where users are authenticated using the UserIdentity class. Recently, I have just implemented a soft-delete feature by adding 'ActiveStatus' to the ApplicationUser class.

The issue arises where the user cannot re-register with the soft-deleted email address as a new account. Can someone help me with this?

Francesco B.
  • 2,729
  • 4
  • 25
  • 37
Enson
  • 71
  • 1
  • 1
  • 5

1 Answers1

0

I've just managed to achieve this in my MVC application using the instructions and sample code from https://www.codeguru.com/csharp/csharp/soft-deleting-entities-cleanly-using-entity-framework-6-interceptors.html posted by Rakesh Babu Paruchuri on August 28th, 2015

The sample code link from that blog entry is https://github.com/rakeshbabuparuchuri/EFExpensionPoints

In case those links become unavailable here are the key points:

It uses a custom attribute "SoftDeleteAttribute" with an Entity Framework Interceptor. The key elements that I included in my own project were:

  • a class for the SoftDeleteAttribute inherited from System.Attribute
  • a SoftDeleteQueryVisitor class that inherits from System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder.DefaultExpressionVisitor
  • a SoftDeleteInterceptor class that inherits from System.Data.Entity.Infrastructure.Interception.IDbCommandTreeInterceptor

Then you register the interceptor - in my case I put the following code in the same file as my ApplicationDbContext (inherited from IdentityDbContext):

public class ApplicationDbConfiguration : DbConfiguration
{
    public ApplicationDbConfiguration()
    {
        AddInterceptor(new Helpers.SoftDeleteInterceptor());
    }
}

And override OnModelCreating to add a convention for dealing with the SoftDeleteAttribute:

 var conv = new AttributeToTableAnnotationConvention<SoftDeleteAttribute, string>(
    "SoftDeleteColumnName",
    (type, attributes) => attributes.Single().ColumnName);
  modelBuilder.Conventions.Add(conv);

The final step was adding the SoftDeleteAttribute to my ApplicationUser class.

[SoftDelete("IsDeleted")]
public class ApplicationUser : IdentityUser<int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>, IUser<int>
{
    //some code removed to emphasise the important bit

    [StringLength(150)]
    public string Forenames { get; set; }

    [StringLength(50)]
    public string Surname { get; set; }

    public bool IsDeleted { get; set; }

}

In addition to this I've also dropped and re-created the unique index on the Username column of my users table in the database so that it uses a condition so that I can re-use the usernames of deleted users (not recommended but I'm using an existing database):

CREATE UNIQUE NONCLUSTERED INDEX [UserNameIndex] 
ON [dbo].[tbl_user] ([UserName] ASC) 
WHERE ([IsDeleted]=(0))

I also ran some migrations - I'm not sure if that migrations step is important for getting it to work, I've literally only done this myself today so haven't had a chance to try it against a manually-created database.

With these changes I can soft-delete users and then create new users with the same username and/or email address

I also found a similar solution at http://marisks.net/2016/02/27/entity-framework-soft-delete-and-automatic-created-modified-dates/ which also uses command interceptors, but replaces the SoftDelete Attribute with a fixed column name and has the code arranged a little differently. He does also include updating Created and Modified columns as well as the soft-delete flag. That article references's Rakesh's article which helped me find it :)

J Fay
  • 71
  • 3