1

I am tring to pass a RouteValueDictionary to my aspx so that I can use it as the parameters for an Ajax.BeginForm method. I load it up like so:

 RouteValues = new System.Web.Routing.RouteValueDictionary();

 RouteValues.Add("FindingId", thisFinding.Id);
 RouteValues.Add("ReportId", thisFinding.ReportSection.ReportId);

and then add it to my model without issue. When I put it as the parameter to the BeginForm method it renders the action as this:

/SolidWaste/Finding/LoadSection?Count=3&Keys=System.Collections.Generic.Dictionary%602%2BKeyCollection%5BSystem.String%2CSystem.Object%5D&Values=System.Collections.Generic.Dictionary%602%2BValueCollection%5BSystem.String%2CSystem.Object%5D

Here is the aspx code:

(Ajax.BeginForm(Model.FormModel.Action,
    Model.FormModel.Controller, 
    Model.FormModel.RouteValues,
new AjaxOptions {
    HttpMethod = "Post",
    InsertionMode = System.Web.Mvc.Ajax.InsertionMode.Replace,
    UpdateTargetId = "WindowContent",
}, new { id = FormId })) { %>
<input name="submit" type="submit" class="button" value="" style="float: right;"/>
<%  } //End Form %>

Here is the View Model that represents Model.FormModel

    public class FormViewModel {

    public string Action { get; set; }

    public string Controller { get; set; }

    public string Method { get; set; }

    public RouteValueDictionary RouteValues { get; set; }
}

Any idea why it is not serializing the RouteValueDictionary into the proper URL on the action? I would like to use an object here rather than build the RouteValues by hand with new { field = vale }

SenseiHitokiri
  • 489
  • 1
  • 6
  • 22

1 Answers1

3

Ah, you are using the wrong overload. It's normal. The ASP.NET MVC team really made a mess out of this API. You gotta be careful which method you are invoking. Here's the overload that you need:

<% using (Ajax.BeginForm(
    Model.FormModel.Action,                                // actionName
    Model.FormModel.Controller,                            // controllerName
    Model.FormModel.RouteValues,                           // routeValues
    new AjaxOptions {                                      // ajaxOptions
        HttpMethod = "Post",
        InsertionMode = System.Web.Mvc.Ajax.InsertionMode.Replace,
        UpdateTargetId = "WindowContent",
    }, 
    new Dictionary<string, object> { { "id", FormId } })    // htmlAttributes
) { %>
    <input name="submit" type="submit" class="button" value="" style="float: right;"/>
<% } %>

Notice the correct overload? You were using the one that was taking routeValues and htmlAttributes as anonymous objects, except that you was passing Model.FormModel.RouteValues as a RouteValueDictionary which basically crapped your overload.

Hit F12 while hovering the cursor over the BeginForm and if you are lucky enough and Intellisense works fine for you in Razor views (which rarely happens) you will get redirected to the method you are actually invoking and realize your mistake.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Wow, what a flub. I can't believe it was really just down to specifying that the HTMLAttributes are of type Dictionary ... Thank you so much, especially for the speedy reply! I was able to replace new RouteValueDictionary() with the actual dictionary in the Model and it worked. – SenseiHitokiri Nov 28 '11 at 23:56