Скрытые поля формы не отображаются в модели MVC после обратной передачи

У меня есть новое приложение MVC 4 с довольно простым представлением/контроллером. Связанная модель содержит пару свойств, которые я сопоставил с полями формы Hidden. Когда страница отображается в первый раз (например, с помощью действия HttpGet), все выглядит нормально. Но когда форма публикуется путем нажатия кнопки «Отправить», результирующая модель, представленная действию, больше не имеет установленных значений скрытого поля. Вот пошаговое руководство по деталям.

Вот пример Модели:

public class Application
{
    public bool ShowSideBars { get; set; }
}

Вот начальное Контроллер *Действие* (которое работает нормально):

[HttpGet]
public ActionResult Application()
{
    var model = Request.ParseFromQueryString<Application>();
    model.ShowSideBars = true;

    return View(model);
}

Это сопоставляется с View следующим образом:

<fieldset>
    @Html.HiddenFor(m => m.ShowSideBars)
...
</fieldset>

В результате внутри набора полей будет отображаться следующая разметка:

<input data-val="true" data-val-required="The ShowSideBars field is required." id="ShowSideBars" name="ShowSideBars" type="hidden" value="True" />

Примечание. Хотелось бы мне знать, почему MVC решил добавить содержимое "... поле обязательно", хотя я не пометил его как обязательное, но это уже другой вопрос

Вот Действие, которое вызывается при отправке формы. С этого момента для вышеупомянутого свойства больше не будет установлено значение «true».

[HttpPost]
public ActionResult Application(Application application)
{
    // Other work done here

    return View(application);
}

В настоящее время нет пользовательских связывателей моделей. Кроме того, я протестировал некоторые другие типы данных и вижу то же самое.

Может кто-нибудь объяснить, почему скрытые значения формы не возвращаются? Я просто делаю все это неправильно?


person JoeGeeky    schedule 19.03.2012    source источник
comment
data-val-required визуализируется, потому что тип модели bool. Логические значения по умолчанию обязательны, они должны быть истинными или ложными. Если вы не хотите видеть data-val-required, сделайте свойство bool?.   -  person danludwig    schedule 19.03.2012
comment
Кроме того, аннотации данных добавляют «обязательный» к любому типу, не допускающему значения NULL. Ints и Bools будут автоматически помечены как требуемые.   -  person Jarrett Meyer    schedule 19.03.2012
comment
@danludwig Отличная идея! благодаря. Это предотвратит небольшое увеличение общего размера страницы.   -  person JoeGeeky    schedule 19.03.2012
comment
Является ли ShowSlideBars изначально строкой запроса?   -  person Dismissile    schedule 19.03.2012
comment
Я предполагаю, что вы завернули поле в форму с именем application и что вы передаете другие поля обратно в модель, которая заполняется?   -  person CAbbott    schedule 19.03.2012
comment
@Dismissile Нет, поэтому я устанавливаю его в контроллере. В конце концов, это будет определяться более динамичными процессами.   -  person JoeGeeky    schedule 19.03.2012
comment
@CAbbott Да, все свойства модели, которые не сопоставлены со скрытыми полями, возвращаются нормально. Это только кажется, что это Скрытые поля.   -  person JoeGeeky    schedule 19.03.2012
comment
Пожалуйста, попробуйте это на MVC 3 и сообщите о результатах. Если ваша проблема возникает в предварительной версии программного обеспечения (бета-версия), попробуйте воспроизвести проблему с выпущенным программным обеспечением. Как правило, вы можете воспроизвести проблему в выпущенном программном обеспечении. Сообщая, что вы используете бета-версию программного обеспечения, вы упускаете 95% потенциальной помощи и скрываете эту проблему. Если это воспроизводится только в бета-версии, укажите это, и вы получите быстрый ответ, потому что это жизненно важное нарушение, которое команда разработчиков будет заинтересована исправить.   -  person RickAndMSFT    schedule 19.03.2012


Ответы (7)


Я не могу воспроизвести проблему (бета-версия ASP.NET MVC 4 работает на VS 2010 .NET 4.0).

Модель:

public class Application
{
    public bool ShowSideBars { get; set; }
}

Контроллер:

public class HomeController : Controller
{
    public ActionResult Application()
    {
        var model = new Application();
        model.ShowSideBars = true;
        return View(model);
    }

    [HttpPost]
    public ActionResult Application(Application application)
    {
        return Content(application.ShowSideBars.ToString());
    }
}

Вид:

@model Application

@using (Html.BeginForm())
{
    @Html.HiddenFor(m => m.ShowSideBars)
    <button type="submit">OK</button>
}

Когда я отправляю форму, связыватель модели правильно присваивает свойству ShowSideBars в действии POST значение true.

Примечание. Мне очень хотелось бы знать, почему MVC решил добавить содержимое «... поле обязательно», когда я не пометил его как обязательное, но это для другого вопроса.

Это потому, что всегда требуются ненулевые типы, такие как логические. Вы можете запретить помощникам ASP.NET MVC выдавать атрибуты проверки HTML5 data-* на стороне клиента для них, поместив следующую строку в Application_Start:

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
person Darin Dimitrov    schedule 19.03.2012
comment
Не могу этого объяснить, но когда я применил изменения к моделям и представлению для поддержки типов, допускающих значение NULL, для скрытых полей, все заработало. Спасибо. - person JoeGeeky; 20.03.2012
comment
Я считаю, что MVC пометил поле как необходимое, потому что bool не является типом, допускающим значение NULL. Если вы хотите удалить требование, вам нужно будет использовать bool? как тип. - person Kevin; 26.10.2017

Если у вас есть свойство в вашей модели, украшенное ReadOnlyAttribute, значение не будет заполнено обратно в модель для вас. Ведь он только для чтения.

person Richard Beverly    schedule 12.10.2012
comment
я создал ту же ошибку, имея частный сеттер для поля - person Kieran; 26.02.2014
comment
у меня было свойство, которое было "внутренним" набором. да, это сделало это (помощник для добавления свойств из написанного кода добавил свойство как внутренний набор - person Chris Hayes; 02.08.2017

У меня была такая же проблема. Форма не отправила скрытое свойство, потому что в классе модели не было надлежащего геттера и установщика для этого свойства. Я знаю, что это не проблема, с которой вы столкнулись, просто подумал, что это может помочь другим людям, которые одолжат на этой странице.

person Ravid Goldenberg    schedule 31.03.2016
comment
Если мы используем internal set; для setter, значение не будет опубликовано. - person Shanid; 05.04.2018

Я думаю, что поля ДОЛЖНЫ быть внутри тегов html формы, чтобы скрытые были отправлены обратно, а не проигнорированы.

person diegosasw    schedule 11.04.2016
comment
Это правда. Помещение всего скрытого поля внутри тега формы решает мою проблему. - person Ariwibawa; 03.03.2017

попробуй это:

public class Model
{
    [ScaffoldColumn(false)]
    public bool InvisibleProperty { get; set; }
}

больше информации здесь (ScaffoldColumn(bool value) vs HiddenInput( DisplayValue = логическое значение) в MVC)

person Ludwo    schedule 21.04.2014

В моем случае это произошло потому, что я объявил поле вместо свойства:

public BaseController.Modes Mode;

не работает. Но:

public BaseController.Modes Mode { get; set; }

работает. Связыватель модели по умолчанию работает только со свойствами.

person toddmo    schedule 04.05.2017

Я не шучу, это еще одна причина, по которой это может произойти.

В моей форме дважды было одно и то же поле. Другого поля на самом деле не было в форме, но это не имеет значения.

Запустите этот jQuery в консоли разработчика, чтобы увидеть, сколько элементов возвращается:

$("[id$=PropertyName]"); // Search for ids ending with property name.

Пример:

введите здесь описание изображения

person Jess    schedule 09.08.2017