0

I have the following helpers:

public static MvcForm BeginFormEx(this HtmlHelper htmlHelper, string actionName, string controllerName, FormMethod method, object htmlAttributes)
{
  return htmlHelper.BeginForm(actionName, controllerName, new { environment = "test" }, method, htmlAttributes);
}

public static MvcForm BeginFormEx(this HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues, FormMethod method, object htmlAttributes)
{
  if (routeValues == null)
  {
    return htmlHelper.BeginFormEx(actionName, controllerName, method, htmlAttributes);
  }

  routeValues["environment"] = "test";
  return htmlHelper.BeginForm(actionName, controllerName, routeValues, method, htmlAttributes);
}

public static MvcForm BeginFormEx(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues, FormMethod method, object htmlAttributes)
{
  if (routeValues == null)
  {
    return htmlHelper.BeginFormEx(actionName, controllerName, method, htmlAttributes);
  }

  return htmlHelper.BeginFormEx(actionName, controllerName, new RouteValueDictionary(routeValues), method, htmlAttributes);
}

I call it like:

@using (Html.BeginFormEx("myAction", "myController", new { returnUrl = ... }, FormMethod.Post, new { role = "form" }))

It renders form like:

<form action="/myController/myAction?Count=2&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" method="post" role="form">

Why ?

I expected to get

<form action="/myController/myAction?returnUrl=...&environment=test" ... >

Why is not working ?

If use

@using(Html.BeginForm(.., ..., new { environment = "test" }, ....)

it works fine. Only if is called as extension is not working.

Also works fine if

@using (Html.BeginFormEx("myAction", "myController", null, FormMethod.Post, new { role = "form" }))

Seems that not working the extending/adding new property to already existing routeValues. How to fix that ?

I made similar with ActionLink and it works fine, I mean that I see environment in query string.

8
  • The ActionLink in a controller parses the response body. You have a request with parameters after the question mark in the URL. The parameters are queries that return results. Your two URLs have different parameters so you are getting two different type of response. You controller has to be able to recognize more than one type of response. Commented Apr 28, 2021 at 14:57
  • 1
    What beginforn has to do with controller? is about form html rendering with unusual action url. Commented Apr 28, 2021 at 14:59
  • The begin form and the response have to be consistent. If you have a form with 5 text boxes the response also need to contain the data to fill those textboxes. So you would have to send a request with the right parameters to get a response with the data for the 5 textboxes. Commented Apr 28, 2021 at 15:25
  • 1
    What form and what response ? I'm asking about weird url rendering when use BeginFormEx which calls BeginForm ... why happens that ? Commented Apr 28, 2021 at 15:29
  • 1
    And other strange situation: If I use @using (Html.BeginFormEx("myAction", "myController", null, FormMethod.Post, new { role = "form" })), null for routeValues, seems that url is working by adding correct query string. So extending routeValues object cause the problem, don't know how to solve it Commented Apr 28, 2021 at 15:42

1 Answer 1

1

The

return htmlHelper.BeginForm(actionName, controllerName, routeValues, method, htmlAttributes);

calls the (HtmlHelper, String, String, Object, FormMethod, Object) overload, passing the RouteValueDictionary routeValues for object routeValues, which serializes the properties of the dictionary as if it was an anonymous object.

There isn't an overload of BeginForm that accepts RouteValueDictionary routeValues and object htmlAttributes at the same time. It's either object+object or Dictionary+Dictionary.

You can make a dictionary out of your object htmlAttributes to end up calling the right overload:

routeValues["environment"] = "test";
return htmlHelper.BeginForm(actionName, controllerName, routeValues, method, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
Sign up to request clarification or add additional context in comments.

1 Comment

Yes, that was my mistake, combining parameter's type occur strange serialization. Thanks alot !

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.