MVC3 Html.BeginForm - передача аргументов при сбое RouteValueDictionary

У меня есть многоэтапный процесс установки, где я хотел бы передать аргументы строки запроса, добавленные к URL, только если они актуальны.

HTTP: // локальный: 6618 / Account / Профиль мастер = истинная и кошки = собака

@using( Html.BeginForm() )

работал отлично. Это дало: <form action="/Account/Profile?setup=true&amp;cats=dogs" method="post"> то есть он передал в действие POST любой из параметров исходной строки запроса, а затем в этом действии контроллера я мог выбрать, какие из них были бы уместны для перехода к моему следующему шагу или которые необходимо добавить, добавив в RouteValues ​​и RedirectToResult.

Тем не менее, мне нужно назначить класс для моей формы в целях стилизации.

Я старался:

@using( Html.BeginForm( "Profile", "Account", args, FormMethod.Post, new { @class = "mainForm" } ) )

который дает:

<form action="/Account/Profile?Count=1&amp;Keys=System.Collections.Generic.Dictionary%602%2BKeyCollection%5BSystem.String%2CSystem.Object%5D&amp;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&amp;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.

Другие вопросы по тегам