2012-01-27 20 views
7

Mam wieloetapowy proces instalacji, w którym chciałbym przekazać argumenty ciągu zapytania dołączone do adresu URL, tylko jeśli są one odpowiednie.MVC3 Html.BeginForm - przekazywanie argumentów jako RouteValueDictionary kończy się niepowodzeniem

http://localhost:6618/Account/Profile?wizard=true&cats=dogs

@using(Html.BeginForm())

działał świetnie. Dało to: <form action="/Account/Profile?setup=true&amp;cats=dogs" method="post"> tj. Przekazało do akcji POST dowolny z oryginalnych parametrów ciągu zapytania, a następnie w tej akcji kontrolera mogłem wybrać, które z nich były istotne, aby przejść do następnego kroku, lub konieczne do dodania, poprzez dodanie do parametrów RouteValues ​​i a RedirectToResult.

Jednak do celów stylizacyjnych muszę przypisać klasę do mojego formularza.

że próbował:

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

co daje:

<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 wytworzono przez filtr i jest RouteValueDictionary). Specyfikacja http://msdn.microsoft.com/en-us/library/dd505151.aspx wskazuje, że można przekazywać argumenty za pomocą System.Web.Routing.RouteValueDictionary.

Co chcę jest <form action="/Account/Profile?setup=true&amp;cats=dogs" class="mainForm" method="post">

należy wspomnieć, wolałbym nie robić coś przekazując new {key = value} Zamiast tego, ponieważ jest tam sporo logiki, aby ustalić, co będę przekazując do następnego kroku.

Wszelkie sugestie dotyczące tego, co należy tutaj zrobić?

Jestem zahamowany tym pozornie prostym zadaniem i na pewno brakuje mi czegoś strasznie oczywistego.

+0

Może odpowiedź w tym drugim poście może trochę pomóc? http://stackoverflow.com/questions/1219223/asp-net-mvc-getting-html-beginform-to-remember-querystring-params-when-submi – summea

Odpowiedz

10

args została wygenerowana przez filtr, i jest RouteValueDictionary

to kluczowy punkt tutaj. W takim przypadku upewnij się, że używasz correct overload metody BeginForm:

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

Zawiadomienie ostatni argument? Musi to być IDictionary<string, object>, aby to działało.

W twoim przykładzie jest to this overload, które zostanie pobrane. Ale ponieważ przekazujesz RouteValueDictionary dla parametru routeValues ​​zamiast anonimowego obiektu, zostaje on pomieszany.

Powinieneś więc mieć zarówno parametry routeValues, jak i htmlAttributes jako słowniki lub oba jako obiekty anonimowe.

+0

@Darin Dimitrov Czy możesz sprawdzić moje pytanie, istnieje pewne podobieństwo: http://stackoverflow.com/questions/12142356/send-an-object-as-a-parametr-to-post-action-in-asp-net -mvc3 – Saeid

+0

Twoje rozwiązanie zadziałało w mojej sytuacji, ale nie rozumiem, dlaczego znak @ jest używany przed zmienną klasy. Czy ktoś może wyjaśnić, co tu się dzieje? Dziękuję Ci. – northben

+0

@ northben, jest używany, ponieważ 'class' jest zastrzeżonym słowem kluczowym w języku C#. Możesz przeczytać więcej na ten temat w specyfikacji C#: http://msdn.microsoft.com/en-us/library/aa664670.aspx –

0

Po prostu myśl, ale nawet w przypadku wielostopniowej formy, czy nie chciałbyś wybrać, aby wszystko było GET lub POST? W powyższym przykładzie ... wygląda na to, że używasz POST z formularzem ... ale nadal próbujesz użyć GET po drodze.

Dlaczego po prostu nie używać po drodze ukrytych wartości POST (używając HTML INPUT)?

W przeciwnym razie użytkownicy mogliby łatwiej zmienić wartości, prawda? (Chociaż, że może nie ma znaczenia w tej aplikacji i jest to najczęściej tylko do myślenia.).

0

więc używasz tej przeciążeniem:

http://msdn.microsoft.com/en-us/library/dd460542.aspx

Czy to możliwe, aby args prosty obiekt z kluczami i wartościami? Myślę, że to rozwiąże twój problem.

Według dokumentów:

Parametry są pobierane poprzez odbicie przez badanie właściwości obiektu. Ten obiekt jest zwykle tworzony za pomocą składni inicjatora obiektu. - wydaje się, że to się dzieje - używa refleksów, aby uzyskać właściwości słownika trasy - właściwości będące kluczami (kolekcja ciągów) i wartości (kolekcja obiektów). html helper i ręcznie utwórz tag formularza - chociaż byłoby to wbrew celowi posiadania pomocników html.

+0

Powinienem wspomnieć wcześniej w moim poście - zajmuje to trochę logika, aby określić, co dokładnie chcę zachować/odkażać/dodać do argumentów. Może powinienem dążyć do niestandardowego HtmlHelper? – Erica

+0

Nie jestem pewien, co kupuje tu niestandardowy HtmlHelper - logika musi gdzieś iść. –

4

Następujący będzie działać.

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

wartość trasa jest tworzony przez obiekt inicjalizacji składni czyli nowy {key = wartość}

+0

Powinienem wspomnieć, że wolałbym nie używać bezpośredniego inicjowania składni obiektu, tj. Nowego {klucz = wartość}, ponieważ wymaga trochę logiki w moim kodzie, aby określić, co chciałbym przekazać dalej. – Erica

Powiązane problemy