Search code examples
ajaxasp.net-mvcroutesajax.beginform

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">

Solution

  • 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