Home > front end >  How do I prevent a duplicate entry for a Create/Edit Functionality in ASP.NET Core w/ EF?
How do I prevent a duplicate entry for a Create/Edit Functionality in ASP.NET Core w/ EF?

Time:11-29

I am trying to prevent a user from creating a form with a FirstName, LastName, and DOB that match an entry in the database and editing a form to match an existing entry. If you could also lead me to how I can show an error when this happens, that would be awesome.

My Model:

public class MRegForm
{
    public int MRegFormId { get; set; }
    [Display(Name = "First Name")]
    public string FirstName { get; set; } = string.Empty;
    [Display(Name = "Last Name")]
    public string LastName { get; set; } = string.Empty;
    public DateTime DOB { get; set; }

[I tried Index attribute. It did not work for me. I was able to create new duplicate forms with no issues.

[Index(nameof(FirstName), nameof(LastName), nameof(DOB), IsUnique = true)]
public class MRegForm
{

I also tried this. Same thing.

    protected override void OnModelCreating(ModelBuilder modelbuilder)
    {
        base.OnModelCreating(modelbuilder);

        modelbuilder.Entity<MRegForm>()
            .HasIndex(x => new { x.FirstName, x.LastName, x.DOB})
            .IsUnique();

    }

    public DbSet<MRegForm> MRegForm { get; set; } = default!;

I think that there is maybe a way to prevent this in the OnPostAsync()

This is my create OnPostAsync():

public async Task<IActionResult> OnPostAsync()
    {
        MRegForm.CreatorId = UserManager.GetUserId(User);

        var isAuthorized = await AuthorizationService.AuthorizeAsync(User, MRegForm, RegFormOperations.Create);

        if (isAuthorized.Succeeded == false)
            return Forbid();

        Context.MRegForm.Add(MRegForm);
        await Context.SaveChangesAsync();

        return RedirectToPage("./Index");
    }

This is my Edit OnPostAsync():

public async Task<IActionResult> OnPostAsync(int id)
    {
        var mRegForm = await Context.MRegForm.AsNoTracking().SingleOrDefaultAsync(m => m.MRegFormId == id);

        if (mRegForm == null)
            return NotFound();

        MRegForm.CreatorId = mRegForm.CreatorId;

        var isAuthorized = await AuthorizationService.AuthorizeAsync(User, MRegForm, RegFormOperations.Update);

        if (isAuthorized.Succeeded == false)
            return Forbid();

        MRegForm.Status = mRegForm.Status; // the Status is the current Status - Do Not Reset

        Context.Attach(MRegForm).State = EntityState.Modified;

        try
        {
            await Context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MRegFormExists(MRegForm.MRegFormId))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }

        return RedirectToPage("./Index");
    }

    private bool MRegFormExists(int id)
    {
      return (Context.MRegForm?.Any(e => e.MRegFormId == id)).GetValueOrDefault();
    }
}

CodePudding user response:

You can try to download the entity from the database if exists and make changes to it or creating new one if not exist. Your clients can always make new MRegForm in the form, but you add or update in the back and. Bether option will be to pass the existing MRegForm to the form and the client see and change all props he need.

public async Task AddOrUpdate(MRegForm input)
{

   var mRegForm = await Context.MRegForm
      .FirstOrDefaltAsync(x => x.FirstName == input.FirstName && x.LastName == input.LastName && x.DOB == input.YourDate);

   if(mRegForm != null)
   {
       //Make changes on mRegForm

       mRegForm.SomeProp = input.SomeProp,
       ...
   }
   else
   {
       var newMRegForm = new MRegForm
       {
          //Set all props you need
       }

       await this.Context.AddAsync(newMRegForm );
   }

   await this.Context.SaveCangesAsync();

}
  • Related