powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / MVC 2-3 ModelState.IsValid выдаёт false при использовании IDataErrorInfo interface
2 сообщений из 2, страница 1 из 1
MVC 2-3 ModelState.IsValid выдаёт false при использовании IDataErrorInfo interface
    #37467450
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Создал сайт с умолчальным шаблоном для учётных записей. Всё работало. Добавил реализацию проверки достоверности через интерфейс IDataErrorInfo - всё работало. Добавил рекапчу, но не внёс проверку правильности её ввода в интерфейс IDataErrorInfo - всё работало. Только если рекапча неправильно введена была, то пользователя просто перебрасывало обратно на заполнение формы регистрации, т. е. надо было как-то дать ему знать, что рекапчу надо правильно ввести. Ввёл проверку рекапчи через IDataErrorInfo так, как показано будет ниже - валидация стала всегда проваливаться.

Модель - умолчальная, плюс добавлено свойство CAPTCHA_Validated. Если убрать проверку CAPTCHA_Validated из IDataErrorInfo, то всё будет работать как надо - пользователь будет проходить регистрацию при правильной капче и отправляться на повторную при неправильной. Сама модель (точнее, только проблемное действие регистрации):

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
    public class RegisterModel : System.ComponentModel.IDataErrorInfo
    {
        [Required]
        [Display(Name = "User name")]
        public string UserName { get; set; }

        [Required]
        [DataType(DataType.EmailAddress)]
        [Display(Name = "Email address")]
        public string Email { get; set; }

        [Required]
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
        public string Password { get; set; }

        [DataType(DataType.Password)]
        [Display(Name = "Confirm password")]
        [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
        public string ConfirmPassword { get; set; }

        // добавлено мной
        public bool CAPTCHA_Validated { get; set; }


        // Интерфейс добавлен мной.
        #region IDataErrorInfo Members

        public string Error { get { return null; } }

        public string this[string propertyName]
        {
            get
            {
                if ((propertyName == "Email") && !System.Text.RegularExpressions.Regex.IsMatch(this.Email, ".+\\@.+\\..+"))
                {
                    return "Введите правильный адрес электронной почты.";
                }

                // без этой проверки всё валидируется
                if ((propertyName == "CAPTCHA_Validated") && this.CAPTCHA_Validated == false)
                {
                    return "Введите правильно символы капчи.";
                }

                return null;
            }
        }

        #endregion
    }

Кусок метода контроллера - помечено, где ModelState.IsValid даёт false:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
        [HttpPost]
        public ActionResult Register(RegisterModel model)
        {
            model.CAPTCHA_Validated = Microsoft.Web.Helpers.ReCaptcha.Validate(privateKey: "Мой закрытый ключ");

            // эта проверка всегда даёт false, если капчу валидирую через IDataErrorInfo
            if (ModelState.IsValid)
            {
                  // создаю учётную запись и прочие дела
            }

            // If we got this far, something failed, redisplay form
            // Собственно, после провала валидации сразу переходит сюда и показывает форму заново.
            return View(model);
        }

Вот стандартное представление, только предпоследним полем добавил рекапчу:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
@model Site2.Models.RegisterModel

@{
    ViewBag.Title = "Register";
}

<div id="allWidthMainBlock">
    <h2>Create a New Account</h2>
    <p>
        Use the form below to create a new account. 
    </p>
    <p>
        Passwords are required to be a minimum of @Membership.MinRequiredPasswordLength characters in length.
    </p>

    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

    @using (Html.BeginForm()) {
        @Html.ValidationSummary(true, "Не удалось создать учётную запись. Пожалуйста, исправьте обишки и попытайтесь снова.")
        <div>
            <fieldset>
                <legend>Account Information</legend>

                <div class="editor-label">
                    @Html.LabelFor(m => m.UserName)
                </div>
                <div class="editor-field">
                    @Html.TextBoxFor(m => m.UserName)
                    @Html.ValidationMessageFor(m => m.UserName)
                </div>

                <div class="editor-label">
                    @Html.LabelFor(m => m.Email)
                </div>
                <div class="editor-field">
                    @Html.TextBoxFor(m => m.Email)
                    @Html.ValidationMessageFor(m => m.Email)
                </div>

                <div class="editor-label">
                    @Html.LabelFor(m => m.Password)
                </div>
                <div class="editor-field">
                    @Html.PasswordFor(m => m.Password)
                    @Html.ValidationMessageFor(m => m.Password)
                </div>

                <div class="editor-label">
                    @Html.LabelFor(m => m.ConfirmPassword)
                </div>
                <div class="editor-field">
                    @Html.PasswordFor(m => m.ConfirmPassword)
                    @Html.ValidationMessageFor(m => m.ConfirmPassword)
                </div>

                // рекапча
                <div class="editor-label">
                    Введите изображённые символы:                    
                </div>
                <b>
                    @Html.ValidationMessageFor(m => m.CAPTCHA_Validated)
                </b>
                <div class="editor-field">
                    @ReCaptcha.GetHtml(theme: "red")                    
                </div>
                
                <p>
                    <input type="submit" value="Register" />
                </p>
            </fieldset>
        </div>
    }
</div>

Пройдя в дебаге по коллекции ModelState, нашёл, что элемент, соответствующий ключу CAPTCHA_Validated, имеет значением (value) null, хотя в контроллере я явно присвоил ему true и в модели должна была пройти валидация. Т. е. по идее логика проверки у меня правильно написана, это ModelState с DefaultModelBinder чего-то не может разобраться с моим CAPTCHA_Validated.

Что мне делать? Писать свой привязчик модели? Выносить логику валидации капчи за умолчальный привязчик модели? Но второй вариант рушит схему "все проверки - в одном месте". Или, может, как-то можно натравить умолчальный привязчик на моё свойство CAPTCHA_Validated?
...
Рейтинг: 0 / 0
MVC 2-3 ModelState.IsValid выдаёт false при использовании IDataErrorInfo interface
    #37467886
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот покороче листинги.

Модель:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
public class RegisterModel : System.ComponentModel.IDataErrorInfo
    {
        public bool CAPTCHA_Validated { get; set; }

        // IDataErrorInfo Members

        public string Error { get { return null; } }

        public string this[string propertyName]
        {
            get
            {
                if ((propertyName == "Email") && !System.Text.RegularExpressions.Regex.IsMatch(this.Email, ".+\\@.+\\..+"))
                {
                    return "Введите правильный адрес электронной почты.";
                }

                // без этой проверки всё валидируется
                if ((propertyName == "CAPTCHA_Validated") && this.CAPTCHA_Validated == false)
                {
                    return "Введите правильно символы капчи.";
                }

                return null;
            }
        }
    }

Контроллер:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
[HttpPost]
        public ActionResult Register(RegisterModel model)
        {
            model.CAPTCHA_Validated = Microsoft.Web.Helpers.ReCaptcha.Validate(privateKey: "Мой закрытый ключ");

            // эта проверка всегда даёт false, если капчу валидирую через IDataErrorInfo
            if (ModelState.IsValid)
            {
                  // создаю учётную запись и прочие дела
            }

            // If we got this far, something failed, redisplay form
            // Собственно, после провала валидации сразу переходит сюда и показывает форму заново.
            return View(model);
        }

Представление:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
@model Site2.Models.RegisterModel

    @using (Html.BeginForm())
	{
        @Html.ValidationSummary(true, "Не удалось создать учётную запись. Пожалуйста, исправьте обишки и попытайтесь снова.")

                // рекапча
                @Html.ValidationMessageFor(m => m.CAPTCHA_Validated)
				
                <div class="editor-field">
                    @ReCaptcha.GetHtml(theme: "red")                    
                </div>
    }
...
Рейтинг: 0 / 0
2 сообщений из 2, страница 1 из 1
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / MVC 2-3 ModelState.IsValid выдаёт false при использовании IDataErrorInfo interface
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]