Скритите полета на формуляри не се показват в MVC модела след обратното публикуване

Имам ново приложение MVC 4 с доста основен изглед/контролер. Свързаният модел съдържа няколко свойства, които съм съпоставил към Скрити полета на формуляр. Когато страницата се визуализира за първи път (напр. чрез действието HttpGet), всичко изглежда добре. Но когато формулярът се публикува чрез избиране на бутона Изпращане, полученият модел, представен на действието, вече няма зададени стойности на скрити полета. Ето преглед на подробностите.

Ето примерен модел:

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

Ето първоначалното Контролер *Действие* (което изглежда работи добре):

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

    return View(model);
}

Това се съпоставя с Изглед, както следва:

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

Понастоящем няма персонализирани Binders за модели. Освен това тествах някои други типове данни и виждам същото.

Може ли някой да обясни защо скритите стойности на формуляра не се връщат? Дали просто правя всичко това погрешно?


person JoeGeeky    schedule 19.03.2012    source източник
comment
data-val-required се изобразява, защото типът на модела е bool. Bools по подразбиране са задължителни, те трябва да са true или false. Ако не искате да виждате data-val-required, направете свойството bool?.   -  person danludwig    schedule 19.03.2012
comment
Като настрана, Data Annotations добавя „задължително“ към всеки ненулев тип. 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
Предполагам, че сте увили полето във формуляр с име приложение и че предавате други полета обратно на модела, които се попълват?   -  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% от потенциалната помощ и прикривате този проблем. Ако възпроизвеждането е само в Beta, посочете това и ще получите бърз отговор, защото това е жизненоважна повреда, която продуктовият екип ще бъде мотивиран да поправи.   -  person RickAndMSFT    schedule 19.03.2012


Отговори (7)


Не мога да възпроизведа проблема (ASP.NET MVC 4 Beta, работещ на 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 реши да добави съдържанието на '...полето е задължително', когато не го маркирах като задължително, но това е за друг въпрос

Това е така, защото типовете без null, като например булеви стойности, винаги са необходими. Можете да спрете помощниците на ASP.NET MVC да излъчват HTML5 data-* атрибути за проверка от страна на клиента за тях, като поставите следния ред в Application_Start:

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
person Darin Dimitrov    schedule 19.03.2012
comment
Не мога да го обясня, но когато приложих промените в моделите и изгледа, за да поддържам nullable типове за скритите полета, всичко започна да работи. Благодаря. - person JoeGeeky; 20.03.2012
comment
Вярвам, че MVC маркира полето, както се изисква, тъй като bool не е nullable тип. Ако искате да премахнете изискването, ще трябва да използвате 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) срещу HiddenInput( DisplayValue = bool стойност) в 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