I'm trying to build a small website using ASP.NET MVC With EntityFramework on Visual Studio 2013.4
I have this model:
public Class User
{
Public int UserID {get;set;}
[Required]
[ValidUserName]
public string UserName { get; set; }
[Required]
public string UserPassword { get; set; }
}
This model has a Custom Attribute which is called [ValidUserName]
.
public class ValidUserName : ValidationAttribute
{
PMAIDEntities db;
public ValidUserName()
{
db = new PMAIDEntities();
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value != null)
{
var valueAsString = value.ToString();
bool IsExist = db.Users.Where(x => x.UserName == (string)value).Any();
if (IsExist)
{
var errorMessage = FormatErrorMessage(validationContext.DisplayName);
return new ValidationResult("User Name is Already Exist !!");
}
}
return ValidationResult.Success;
}
}
The problem is when I try to add a new record to the database the [ValidUserName]
works fine, which informs the end-user if the username exists in the database or not. But, when the update operation occur on a record to change password the [ValidUserName]
gives me that the username exists in the database.
I know that the username already exists, but how can I solve this problem to let [ValidUserName]
accept current username because the username shall remain as is?
This the the code in the controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "UserID,UserName,UserPassword,UserRole,UserFullName,UserEmail,UserMobile,UserLastLogin,UserAddress,UserBio,UserNationality,UserGender,UserDOB,UserAge,UserDateAdded")] User user)
{
if (ModelState.IsValid)
{
db.Entry(user).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.UserNationality = new SelectList(db.Nationalities, "Id", "Name", user.UserNationality);
return View(user);
}
edit
i use this code in model
public class User
{
public int UserID { get; set; }
[Required]
[Remote("IsUserNameValid", "Users", AdditionalFields = "UserID", ErrorMessage = "Username already exists.")]
[ValidUserName]
public string UserName { get; set; }
[Required]
public string UserPassword { get; set; }
}
and in the controller i add the following code
public JsonResult IsUsernameValid(string UserName, int UserID)
{
var isValid = true;
if (UserName != null)
{
isValid = !db.Users.Where(x => x.UserName == UserName && x.UserID != UserID).Any();
}
return Json(isValid, JsonRequestBehavior.AllowGet);
}
the problem here is the remote attribute require to specify the controller name , in this case what should i write if is my controller located inside an area called 'Admin'
You need to use Remote Validation (RemoteAttribute). Add this action method to your controller (I'm assuming your UserID is integer):
public JsonResult IsUserNameValid(string UserName, int UserID = 0)
{
var isValid = true;
if (UserName != null)
{
isValid = !db.Users.Where(x => x.UserName == UserName && x.UserID != UserID).Any();
}
return Json(isValid, JsonRequestBehavior.AllowGet);
}
Then, use it in your model like this (updated for calling the controller in the Admin area):
public class User
{
[Required]
[Remote("IsUserNameValid", "Users", "Admin",
AdditionalFields = "UserID", ErrorMessage = "Username already exists.")]
public string UserName { get; set; }
[Required]
public string UserPassword { get; set; }
// other properties...
}
You can read more about implementing Remote Validation in asp.net MVC here.