1

This is my User model Class:

public class User 
{
    public int Id { get; set; }

    [Required]
    [MaxLength(100)]
    public string FullName { get; set; }

    [Required]
    [MaxLength(30)]
    [Remote("IsUsernameExists", "Home", HttpMethod = "Post")]
    public string UserName { get; set; }

    [Required]
    [RegularExpression(@"^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$"]
    public string Email { get; set; }

    [Required]
    [StringLength(maximumLength: 18, MinimumLength = 8)]
    public string Password { get; set; }
}

This is IsUsernameExists method in Home controller

public JsonResult IsUsernameExists(string UserName)
{            
    return Json(!db.Users.Any(x => x.Username == UserName), JsonRequestBehavior.AllowGet);
}

But it doesn't work. Any further help will highly be appreciated!

Tetsuya Yamamoto
  • 24,297
  • 8
  • 39
  • 61
  • What do you mean by doesn't work exactly? You get any exception or error message? Unexpected result? You need to be more specific about your problem. – Salah Akbari Dec 19 '18 at 13:25
  • nothing happen. when i enter a username that already exists it will go to database and record it – farshid torkaman Dec 19 '18 at 13:27
  • Try to use `x => x.Username == UserName.ToLowerInvariant()` and let me know if it works! – Salah Akbari Dec 19 '18 at 13:31
  • still nothing happened – farshid torkaman Dec 19 '18 at 13:35
  • Your `UserName` might contains spaces also. You can also try the `Trim` method after `ToLower` method and see if it works! – Salah Akbari Dec 19 '18 at 13:38
  • you mean this ? x => x.Username == UserName.ToLowerInvariant().Trim() if that it doesn't work again – farshid torkaman Dec 19 '18 at 13:42
  • @GregH The method (`IsUsernameExists`) that is posted in the question is used for *RemoteVaidation* and there is no need to be marked as Post. – Salah Akbari Dec 19 '18 at 13:53
  • @farshidtorkaman, Dear I posted an answer to your question taking some times! You didn't tell whether it had worked for you or not! If you just ignore after getting the answer then how will the people get inspired to help you again? Thank you. – TanvirArjel Dec 26 '18 at 08:17
  • actually i did read everyone answers. but when you post your asnwer i find the solution. and i didn't try your solution. i'm sorry for not answering. – farshid torkaman Dec 26 '18 at 08:20
  • @farshidtorkaman Okay! I have seen your own answer! This is not the best way to do these things! May be it solve your problem for the time being but not the good practice. Read my answer thoroughly it will help you to understand these things clearly. Good Luck! – TanvirArjel Dec 26 '18 at 09:22

3 Answers3

5

You can make a model property Unique by using Both DataAnnotation and FluentApi as follows:

Using Data Annotation:

[Required]
[StringLength(30)]
[Index("Ix_UserName",Order =1,IsUnique =true)]
public string UserName { get; set; }

Using Fluent Api:

In Entity Framework >= 6.2,

In DbContext:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
     base.OnModelCreating(modelBuilder);

     modelBuilder.Entity<User>().Property(u => u.UserName).HasMaxLength(30);
     modelBuilder.Entity<User>().HasIndex(u => u.UserName).IsUnique();
}

In Entity Framework < 6.2

In DbContext:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
     base.OnModelCreating(modelBuilder);

     modelBuilder.Entity<User>().Property(t => t.UserName).HasMaxLength(30)
                                  .HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute("Ix_UserName"){IsUnique = true}));
}

Remember: With Index attribute you must have to use StringLength attribute also.

For making RemoteAttibute working, write your RemoteAttibute on UserName property as follows:

[Required]
[StringLength(30)]
[Index("Ix_UserName",Order =1,IsUnique =true)]
[Remote("IsUserNameExist", "Home", AdditionalFields = "Id", ErrorMessage = "User Name already exists")]
public string UserName { get; set; }

And then the IsUserNameExist method in the HomeController as follows:

public JsonResult IsUserNameExist(string UserName, int? Id)
{
     var IsUserNameExists = db.Users.Any(x => x.UserName== UserName && x.Id != Id);
     return Json(!IsUserNameExists, JsonRequestBehavior.AllowGet);
}

Finally ensure that your view contains the following jQuery files:

<script src="~/Scripts/jquery-version.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

Everything should work now fine!

TanvirArjel
  • 30,049
  • 14
  • 78
  • 114
1

The RemoteAttribute doesn't have anything to do with Entity Framework. It simply ignores this attribute. Furthermore, as the documentation says, it's a jQuery validation attribute, it's supposed to work on front end part only.

If User is both MVC model and database entity, you should create a unique index for the property. One way to do that is in OnModelCreating method in your DbContext:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<User>().HasIndex(x => new { x.Username }).IsUnique();
}

Then create a migration, apply it to the database and you're good to go. However, be aware of the exception you will get when saving duplicates and make sure you handle it properly.

Imantas
  • 1,621
  • 13
  • 19
-2

I create a method in HomeController

   public bool IsUserExist(string email)
   {
        return db.Users.Where(c => c.Email == email).IsAny();
   } 

and in Action

    if( IsUserExist(model.Email) )
    {
        // my code
    }