Unnie
Unnie

Reputation: 937

MVC 5 AJax.Beginform Routevalues are generated wrongly

I am trying to post to action the current querystring. So i have created the below extension method :

public static RouteValueDictionary ToRouteValues(this NameValueCollection col, Object obj = null)
        {
            var values = obj != null ? new RouteValueDictionary(obj) : new RouteValueDictionary();
            if (col == null) return values;
            foreach (string key in col)
            {
                //values passed in object are already in collection
                if (!values.ContainsKey(key)) values[key] = col[key];
            }
            return values;
        }

And in my view i am using the routvalues as below:

 using (Ajax.BeginForm(actionName: "Post", routeValues:Request.QueryString.ToRouteValues(), controllerName: "Request", ajaxOptions: new AjaxOptions { HttpMethod = "Post", OnSuccess = "SuccessCallBack", UpdateTargetId = "successDiv", InsertionMode = InsertionMode.InsertAfter }, htmlAttributes: new { @data_toggle = "validator" }))
        {
        }

But strangely when the html markup is generated the form tag action does not have the actual querystring values but instead has a string version of the object metadata.

<form action="/Request/Post?Count=5&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" data-ajax="true" data-ajax-method="Post" data-ajax-mode="after" data-ajax-success="SuccessCallBack" data-ajax-update="#successDiv" data-toggle="validator" id="form0" method="post" novalidate="true">

Upvotes: 0

Views: 1313

Answers (2)

Andrei Olariu
Andrei Olariu

Reputation: 556

This works for me:

@using (Ajax.BeginForm(
    actionName: "AddOns",
    controllerName: "Basket",
    routeValues: Request.QueryString.ToRouteValues(),
    ajaxOptions: new AjaxOptions { HttpMethod = "Post", OnSuccess = "SuccessCallBack", UpdateTargetId = "successDiv", InsertionMode = InsertionMode.InsertAfter },
    htmlAttributes: new Dictionary<string, object> { { "class", "mainForm" } }))
{
    @:Blah
}

It outputs:

<form action="/Basket/AddOns?test=test" class="mainForm" data-ajax="true" data-ajax-method="Post" data-ajax-mode="after" data-ajax-success="SuccessCallBack" data-ajax-update="#successDiv" id="form0" method="post">
    Blah
</form>

Please note the last parameter which is a Dictionary<string, object>.

Used this post as source: MVC3 Html.BeginForm - passing arguments as RouteValueDictionary fails

Upvotes: 2

user3559349
user3559349

Reputation:

The issue is that your using named parameters and there are overloads of Ajax.BeginForm() that accept both object routeValues and RouteValueDictionary routeValues.

In your case its using object routeValues and your generating a route value for each property of RouteValueDictionary (Count, Keys, etc). I'm assuming that's because the overload with object routeValues is defined first (but have yet to find anything documenting the behavior)

You can solve this by omitting the names and using

@using (Ajax.BeginForm("Post", "Request", Request.QueryString.ToRouteValues(), new AjaxOptions { HttpMethod = "Post", OnSuccess = "SuccessCallBack", UpdateTargetId = "successDiv", InsertionMode = InsertionMode.InsertAfter }, new { @data_toggle = "validator" }))
{
}

Upvotes: 1

Related Questions