I am an MVC C# newbie.
I have a project which is using the built-in simple membership features of .net. I have that all working fine. I do however want to prevent a user from choosing certain usernames when registering which are NOT in the database already, such as swear words (of which I have been using plenty today).
I want to test against this list both in an ajax call and on submit. What is the proper way of going about this? I already have the system checking for usernames in use from the DB with no problem.
I have added a list called ReservedWords to the RegisterModel, but I just do not know where or how even to populate it so that it is available to the 2 controllers (async and post).
The Model looks like this:
public class RegisterModel
{
public string Email { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public List<ReservedWord> ReservedWords { get; set; }
}
Am I supposed to populate it in the model file or in the controller? In either case can you please provide a sample?
The controller code is here for both the async and post backs:
// POST: /Account/doesUserNameExist async
[AllowAnonymous]
[HttpPost]
public JsonResult doesUserNameExist(string UserName)
{
var user = Membership.GetUser(UserName);
return Json(user == null);
}
// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the user
try
{
WebSecurity.CreateUserAndAccount(model.UserName, model.Password);
Roles.AddUserToRole(model.UserName, Request.Form["RoleName"]);
WebSecurity.Login(model.UserName, model.Password);
return RedirectToAction("Index", "Home");
}
catch (MembershipCreateUserException e)
{
ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
Thanks in advance!!!!!
Update
So I followed the advice to create a custom validation attribute and it works great on submit. Thanks! Is there a way to get it to work with the client side validation? I have a similar custom validation attribute which compares two fields and makes sure they're not equal. I followed that code but no luck. Here is the code now:
public class BlackListWordAttribute : ValidationAttribute, IClientValidatable
{
private const string defaultErrorMessage = "{0} cannot use forbidden word.";
private readonly List<string> blackListedWords = new List<string>();
public BlackListWordAttribute()
: base(defaultErrorMessage)
{
//populate from database or text file with cache dependency on either
blackListedWords.Add("bananas");
}
public override string FormatErrorMessage(string name)
{
return string.Format(ErrorMessageString, name);
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value != null)
{
if (blackListedWords.Any(x => x.ToLower() == value.ToString().ToLower()))
{
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
}
return ValidationResult.Success;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
yield return new ModelClientValidationRule
{
ErrorMessage = FormatErrorMessage(metadata.DisplayName),
//This is the name of the method added to the jQuery validator method (must be lower case)
ValidationType = "blacklistword"
};
}
}
Thanks again!