1

私は MVC C# 初心者です。

.net の組み込みの単純なメンバーシップ機能を使用しているプロジェクトがあります。私はそれがすべて正常に機能しています。ただし、ユーザーが登録時に、まだデータベースにない特定のユーザー名を選択できないようにしたいと考えています。

このリストに対して、ajax 呼び出しと送信の両方でテストしたいと考えています。これについての適切な方法は何ですか?DBから使用中のユーザー名をチェックするシステムがすでにありますが、問題はありません。

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

前もって感謝します!!!!!


アップデート

そのため、アドバイスに従ってカスタム検証属性を作成しましたが、送信時にうまく機能します。ありがとう!クライアント側の検証で動作させる方法はありますか? 2 つのフィールドを比較し、それらが等しくないことを確認する同様のカスタム検証属性があります。私はそのコードに従いましたが、うまくいきませんでした。これが今のコードです:

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 に答える