ASP.NET MVC - POST Action Method with Additional Parameters from URL
Asked Answered
T

5

11

With ASP.net MVC is it possible to POST a form to a controller action which includes parameters not in the form, but from the URL?

For example

The Action method in GroupController:

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create(int idOne, int idTwo, Model model)
    { ... }

The route:

"{controller}/{action}/{idOne}/{idTwo}"

Posted URL:

/Employee/Show/1/42

In this example, the form is being posted to a different controller, the model has the correct value, however the other parameters have default values 0.

The behavior I was expecting is that the ModelBinder would see that I have two parameters that match the given route, and assign the current values of 1 and 42 to the parameters in the same same way a GET operation works.

Is this behavior not supported, or am I missing something?

EDIT: To be clear, the form on the Show view for the controller Employee contains a form which is posting to a different controller. We can call it Group.

The form action URL looks like this

/Groups/Create/0/0

The form is declared as follows

Html.BeginForm("Create", "Groups")

After trying many different overloads for Html.BeginForm I have found that the parameters are only mapped when the form action URL matches the current URL in the browser address bar.

So if i navigate to the URL /Groups/Create/1/42 I will have a new form. If I then submit the form, the URL route values are passed to the POST action.

Teofilateosinte answered 17/3, 2010 at 20:5 Comment(1)
I would try defining the route to include the model and setting it as a default of null and see what happens. {controller}/{action}/{idOne}/{idTwo}/{Model}Bucher
A
10

If I understand your question correctly, you want the action of the rendered <form> element pointing to URL containing route values. This should be possible with one of the overloads of the HtmlHelper.BeginForm() extension method:

Html.BeginForm("action","controller", new { idOne=1, idTwo=2 }, FormMethod.Post);

Let me know if I got your question all wrong :)

Adigranth answered 17/3, 2010 at 20:14 Comment(1)
Sort of. As i stated in the question, the for action already contains a URL with the correct route values (1 and 42 from the example). The problem is when i step into the executing action, the two parameters have value 0. I tried your suggestion, but the values were still 0.Teofilateosinte
B
2

I'm pretty sure that you can only post form data from inputs inside the form. Have you considered rendering the view in such a way to create form input values off of the URL (perhaps with an HTML helper?).

UPDATE: If you don't want to use the form at all, use ControllerContext.RouteData.Values["idOne"] as opposed to passing it in through the method signature.

Burrell answered 18/3, 2010 at 14:14 Comment(7)
Within the form I made a query to the route values, ViewContext.RouteData.Values["idOne"], however on the final rendered page has a value of 0, not the value from the route. Is there another approach to get the current URL route values from within a View/Partial?Teofilateosinte
If you use an Html helper extension, you should be able to see it off of the helper instance itself. The syntax would look like helper.ViewContext.RouteData.Values["idOne"]. Alternately, you could store those ID values in a view model and pass it to the view that way.Burrell
+1 Same thoughts. Why not include the it in values as hidden fields within the Html.BeginForm("Create", "Groups")? Also, should you be 'Posting' to Create a new form?Pepperandsalt
What is the alternative to posting to create a new entity? I was trying to avoid placing hidden fields because it adds extra work for passing them between views/controllers. Especially since this functionality does work in other cases. At this point, it seems that is the only way to get past this issueTeofilateosinte
Karl - I played around with it a bit, and it looks like you can snag the values you're interested in through the ControllerContext object (see my update). Let me know if that works out!Burrell
@Teofilateosinte did you end up getting to the bottom of this one?Burrell
@Brandon What i ended up doing was including the id I wanted in the model itself, and passing it as a parameter to the form action. It isnt the cleanest way, but It is working for now. I tried your updated answer, however that did not return the correct value.Teofilateosinte
S
1

I had a similar problem, the configuration RouteConfig has solved this problem.

public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
             ...
             routes.MapRoute(
             "MyRoute",
             "{controller}/{action}/{idOne}/{idTwo}",
             new
             {
                 controller = "Employee", // as an example
                 action = "Show",
                 idOne = UrlParameter.Optional,
                 idTwo= UrlParameter.Optional
             }, new { idOne = @"\d{1,5}" });

        }
    }

...And... Html.BeginRouteForm()

@using (Html.BeginRouteForm("MyRoute", new { idOne = 1, idTwo= 2 }, FormMethod.Post))

Writes an opening tag to the response. When the user submits the form, the request will be processed by the route target. This member is overloaded. For complete information about this member, including syntax, usage, and examples, click a name in the overload list.

And all works

Sizeable answered 19/11, 2013 at 17:57 Comment(0)
T
0

I recently had this issue too, and because I had a different route, it was mapping to the default route, without taking into account the extra route params that I was passing in.

So to get it working quickly, I wrote the form using form tags instead, and used @Url.Action to create the required action.

Troyes answered 19/11, 2013 at 15:24 Comment(0)
D
0

Once you get to your Create view, your route values used to get there need to be re-posted to the post action.

So, one option is having a pair of hiddens, to hold the ids that came from the route. This way, once you post the formas, its values are posted along with the other inputs.

Deshabille answered 19/11, 2013 at 16:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.