Mathias F
Mathias F

Reputation: 15901

Begin.Form with overload that accepts routeValues and htmlAttributes

I use an overload of Begin.Form that accepts routeValues

    <% 
        RouteValueDictionary routeValues = ViewContext.RouteData.Values;
        routeValues.Add("TestRoute1", "test");

        using (Html.BeginForm(
            "Category", 
            "Home",
              routeValues,
              FormMethod.Post

      ))
       { %>  

        <input type="submit" value="submit" name="subform" />
<% }%>

This works nice and renders the formtag as:

<form method="post" action="/Home/Category?TestRoute1=test">

I need to change htmlAttributes, thats why I used:

    <% 
        RouteValueDictionary routeValues = ViewContext.RouteData.Values;
        routeValues.Add("TestRoute1", "test");

        using (Html.BeginForm(
            "Category", 
            "Home",
              routeValues,
              FormMethod.Post,
              new {id="frmCategory"}

      ))
       { %>  

        <input type="submit" value="submit" name="subform" />
<% }%>

The result is completely wrong:

<form method="post" id="frmTyreBySizeCar" action="/de/TyreSize.mvc/List?Count=12&amp;Keys=System.Collections.Generic.Dictionary%....

I can see in the source of the Formhelper what the reason is.

There are 2 overloads that apply to my given parameters:

public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues, FormMethod method, object htmlAttributes)

public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues, FormMethod method, IDictionary<string, object> htmlAttributes)

It goes wrong, because the first method is picked up. If I dont supply htmlAttributes, then there is no overload with object as a parameter and everyrthing works as expected.

I need a workaround that accepts a Dictionary of RouteValues and htmlAttributes. I see that there are overloads that have an additional routeName, but thats not what I want.

EDIT: eugene showed the right usage of BeginForm.

Html.BeginForm("Category", "Home",
new RouteValueDictionary { {"TestRoute1", "test"} },
FormMethod.Post,
new Dictionary<string, object> { {"id", "frmCategory"} }

)

Upvotes: 19

Views: 35682

Answers (3)

Reza
Reza

Reputation: 426

you can write

<% using (Html.BeginForm("Category", "Home", new {TestRoute1=HttpContext.Current.Request.QueryString["TestRoute1"] }, FormMethod.Post, new {id = "MainForm" })) { %>

Upvotes: 2

eu-ge-ne
eu-ge-ne

Reputation: 28153

Use (both RouteValues and HtmlAttributes are objects):

Html.BeginForm("Category", "Home",
    new { TestRoute1 = "test" },
    FormMethod.Post,
    new { id = "frmCategory" }
)

or (both RouteValues and HtmlAttributes are dictionaries):

Html.BeginForm("Category", "Home",
    new RouteValueDictionary { {"TestRoute1", "test"} },
    FormMethod.Post,
    new Dictionary<string, object> { {"id", "frmCategory"} }
)

Upvotes: 33

David
David

Reputation: 15360

using (Html.BeginForm("Category", "Home", new { TestRoute1="test"}, 
       FormMethod.Post, new {id="frmCategory"})) {

renders to

<form action="/accountchecker/Home/Category?TestRoute1=test" 
    id="frmCategory" method="post">
    <input type="submit" value="submit" name="subform" />
</form>

Upvotes: 2

Related Questions