Почему проверка на стороне клиента ASP.NET MVC не выполняется, если в модели представления существует свойство 'Title'? - PullRequest
0 голосов
/ 16 января 2019

Этот вопрос уже указывает на половину проблемы, которая, по-видимому, является чрезвычайно обременительной ошибкой фреймворка, а именно: Когда ваша модель представления имеет свойство Title, привязка к этому свойству делает невозможной проверку на стороне клиента. :

Html.TextBoxFor(m => m.Title)

Результирующий тег input не содержит в себе атрибутов проверки, и он также, кажется, делает проверку на стороне клиента неудачной для других свойств (в этом я уверен на 90%).

Вопросы:

  1. Кто-нибудь еще документировал эту давнюю ошибку?

  2. Что здесь происходит? Важно, что это происходит только тогда, когда выполняется какое-то дополнительное условие? У меня такое чувство, что структура путает ViewBag.Title со свойством Title вашей собственной модели представления.

  3. Что нужно сделать, чтобы смягчить эту проблему?

Если не получить эти ответы, то просто зная, что это может быть одной из причин, почему проверка на стороне клиента терпит неудачу, является победой, в моем случае это просто украло полтора дня моего времени, пока я не сузил дело до это единственное Title свойство. Но хотелось бы услышать ответы, в частности, на первые два вопроса выше. Что касается # 3)

Чтобы смягчить проблему, одно из решений состоит в том, чтобы просто не использовать это свойство, назовите свойство, например. Title2. И если вы используете маппер, вы все равно можете добавить свойство Title, которое получает и устанавливает из этого вспомогательного поля Title2, которое сработало для меня, например ::

public string Title { get => Title2; set { Title2 = value; } }

--- Редактировать ---

Ниже приведен минимальный пример. У меня нет времени, чтобы сделать полный проект или воспроизвести все. Конечно, существует вероятность того, что некоторые настройки в большом проекте, в котором я работаю (полнофункциональный MVC 5.2.6), что-то делают, что приводит к этому, я не знаю. Но это лучше, чем ничего. Если вы привязываетесь к Title, это не получается, привязка к Title2 работает:

Посмотреть модель FooVM:

public class FooVM
{
    [Required]
    [StringLength(64)]
    public string Title2 { get; set; }

    public string Title { get; set; }

    // fix with this: public string Title { get => Title2; set { Title2 = value; } }

    [Required]
    [StringLength(256)]
    public string Body { get; set; }

    [Range(1, 100_000_000)]
    [Required]
    public int FooId { get; set; }

    public int OrgId { get; set; }

}

View

@model FooVM
@{
    ViewBag.Title = "Foo!";
    string msg = ViewBag.Message ?? "";
    // you can test it out directly here if you want:
    //string str2 = Html.TextBoxFor(m => m.Title).ToHtmlString();
}

<div class="pagetile">
    <div class="row-fluid">
        <div class="span12">

            <h2>Yo dog, why you not workin'?</h2>
            <p> @msg.ToHtmlString() </p>

            @using (Html.BeginForm()) {
                @Html.ValidationSummary()

                @Html.HiddenFor(m => m.FooId)
                @Html.HiddenFor(m => m.OrgId)

                <div>
                    Title:
                    @Html.TextBoxFor(m => m.Title)  @*change to Title2 and it works*@

                    @* 
you can do this manually as well, both helpers fail to produce the validation tags on the generated input element:
@Html.TextBox("Title", "", null, null)
*@

                    @Html.ValidationMessageFor(model => model.Title) @*this part is always fine*@               
                </div>

                <button type="submit">Submit</button>
            }
        </div>
    </div>
</div>

Контроллер

public class FooController
{
    public async Task<ActionResult> Foo() 
    {
        return View(new FooVM());
    }

    [HttpPost]
    public async Task<ActionResult> Foo(FooVM vm)
    {
        if (!ModelState.IsValid) {
            ViewBag.Message = $"Not valid!";
            return View(vm);
        }

        ViewBag.Message = "Cool beans";
        return View(vm);
    }
}

Когда он связан с Title, он генерирует этот HTML: <input id="Title" name="Title" type="text" value="">

enter image description here

Привязка к Title2 создает это: <input data-val="true" data-val-length="The field Title2 must be a string with a maximum length of 64." data-val-length-max="64" data-val-required="The Title2 field is required." id="Title2" name="Title2" type="text" value="">

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...