MVC3 Html.BeginForm - передача аргументов при сбое RouteValueDictionary
У меня есть многоэтапный процесс установки, где я хотел бы передать аргументы строки запроса, добавленные к URL, только если они актуальны.
HTTP: // локальный: 6618 / Account / Профиль мастер = истинная и кошки = собака
@using( Html.BeginForm() )
работал отлично. Это дало: <form action="/Account/Profile?setup=true&cats=dogs" method="post">
то есть он передал в действие POST любой из параметров исходной строки запроса, а затем в этом действии контроллера я мог выбрать, какие из них были бы уместны для перехода к моему следующему шагу или которые необходимо добавить, добавив в RouteValues и RedirectToResult.
Тем не менее, мне нужно назначить класс для моей формы в целях стилизации.
Я старался:
@using( Html.BeginForm( "Profile", "Account", args, FormMethod.Post, new { @class = "mainForm" } ) )
который дает:
<form action="/Account/Profile?Count=1&Keys=System.Collections.Generic.Dictionary%602%2BKeyCollection%5BSystem.String%2CSystem.Object%5D&Values=System.Collections.Generic.Dictionary%602%2BValueCollection%5BSystem.String%2CSystem.Object%5D" class="mainForm" method="post">
(args
был сгенерирован фильтром и является RouteValueDictionary). Спецификация http://msdn.microsoft.com/en-us/library/dd505151.aspx указывает, что вы можете передавать аргументы с помощью System.Web.Routing.RouteValueDictionary.
Что я хочу это <form action="/Account/Profile?setup=true&cats=dogs" class="mainForm" method="post">
Я должен упомянуть, что предпочел бы не делать что-то вроде прохождения new {key = value}
вместо этого, поскольку есть достаточное количество логики, чтобы определить, что я буду передавать на следующий шаг.
Любые предложения о том, что здесь делать?
Я застрял в этом, казалось бы, простом задании, и наверняка упускаю нечто ужасно очевидное.
4 ответа
args был сгенерирован фильтром и является RouteValueDictionary
Это ключевой момент здесь. В этом случае убедитесь, что вы используете правильную перегрузку метода BeginForm:
@using(Html.BeginForm(
"Profile",
"Account",
args,
FormMethod.Post,
new RouteValueDictionary(new { @class = "mainForm" })
))
{
...
}
Обратите внимание на последний аргумент? Это должно быть IDictionary<string, object>
чтобы это работало.
В вашем примере именно эта перегрузка улавливается. Но так как вы передаете RouteValueDictionary
для параметра routeValues вместо анонимного объекта он портится.
Таким образом, у вас должны быть и routeValues, и htmlAttributes в качестве словарей, или оба в качестве анонимных объектов.
Следующий будет работать.
@using (Html.BeginForm("Profile", "Account", new { id=122}, FormMethod.Post, new { @class = "mainForm" }))
значение маршрута создается с помощью синтаксиса инициализации объекта, т.е. нового {ключ = значение}
Просто мысль, но, даже для многоэтапной формы, не хотите ли вы выбрать, сделать все это GET или POST? В приведенном выше примере... похоже, что вы используете POST с формой... но все еще пытаетесь использовать GET на этом пути.
Почему бы просто не использовать скрытые значения POST (используя HTML INPUTs)?
В противном случае пользователи могли бы легче изменить значения, верно? (Хотя, это может не иметь значения в этом приложении. И это в основном просто пища для размышлений.)
Итак, вы используете эту перегрузку:
http://msdn.microsoft.com/en-us/library/dd460542.aspx
Можно ли сделать args простым объектом с ключами и значениями? Я думаю, что это может решить вашу проблему.
Согласно документам:
Параметры извлекаются путем отражения путем изучения свойств объекта. Этот объект обычно создается с использованием синтаксиса инициализатора объекта. - кажется, это то, что происходит - он использует отражения, чтобы получить свойства словаря маршрутов - это ключи (коллекция строк) и значения (коллекция объектов)
Другой вариант - не использовать помощник html и не создавать тег формы вручную, хотя это может отчасти побороть цель иметь помощников html.