1

我是 MVC C# 新手。

我有一个使用.net 内置的简单会员功能的项目。我有这一切工作正常。但是,我确实希望防止用户在注册时选择某些用户名,这些用户名已经不在数据库中,例如脏话(我今天已经使用了很多)。

我想在 ajax 调用和提交时针对这个列表进行测试。解决这个问题的正确方法是什么?我已经让系统从数据库检查正在使用的用户名,没有问题。

我在 RegisterModel 中添加了一个名为 ReservedWords 的列表,但我只是不知道在哪里或如何填充它,以便它可用于 2 个控制器(异步和发布)。

模型如下所示:

public class RegisterModel
{
    public string Email { get; set; }

    public string UserName { get; set; }

    public string Password { get; set; }

    public List<ReservedWord> ReservedWords { get; set; }
}

我应该在模型文件或控制器中填充它吗?无论哪种情况,您都可以提供样品吗?

异步和回发的控制器代码都在这里:

 // 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);
    }

提前致谢!!!!!


更新

所以我按照建议创建了一个自定义验证属性,它在提交时效果很好。谢谢!有没有办法让它与客户端验证一起工作?我有一个类似的自定义验证属性,它比较两个字段并确保它们不相等。我遵循了该代码,但没有运气。这是现在的代码:

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"
        };

    }
}

再次感谢!

4

1 回答 1

2

我会使用自定义验证。如果您将模式更改为

public class RegisterModel
{
    public string Email { get; set; }

    [BlackListWord]
    public string UserName { get; set; }

    public string Password { get; set; }
}

然后自定义验证属性可能类似于:

    [AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = false)]
    public class BlackListWordValidationAttribute : ValidationAttribute {
        private readonly List<string>  blackListedWords = new List<string>();

        public BlackListWordValidationAttribute() {
            //populate from database or text file with cache dependency on either
            blackListedWords.Add("bananas");
        }
        protected override ValidationResult IsValid(object value, ValidationContext validationContext) {
            if(value!=null) {
                if (blackListedWords.Any(x => x.ToLower() == value.ToString().ToLower()))
                    return new ValidationResult(@"Cannot use black listed word.");
            }

            return ValidationResult.Success;
        }
    }

您可以将黑名单存储在数据库或文件或 xml 或其他任何内容中。

然后您也可以添加客户端验证。为了帮助解决这个问题,请考虑使用类似这个肮脏列表的东西,您可以通过 Web 服务访问它。

编辑/更新 2 号:

根据提问者的要求。使代码对“异步和回发”都可用的最佳方法是创建一个字符串扩展方法。例如,

public static class StringExtension {
        public static bool IsUserNameAllowed(this string value) {
    List<ReservedWord> ReservedWords = GetReservedWordsFromPersistantMedium();

    return ReservedWords.All(x => x.Word.ToLower() != value.ToLower());
    }
} 

将上面的类放在一个引用的项目或带有 web 项目的扩展文件夹中。

然后你可以打电话

model.UserName.IsUserNameAllowed() or userName.IsUserNameAllowed()

例如:

[AllowAnonymous]
[HttpPost]
public JsonResult doesUserNameExist(string UserName)
{
    if !(UserName.IsUserNameAllowed())
    {
        return Json(new { ErrorMessage="An error has occured"});
    }
    var user = Membership.GetUser(UserName);
    return Json(user == null);
}

在任何一种情况下

于 2012-09-26T23:29:50.670 回答