tags:

views:

93

answers:

3

I have 2 forms on a page, they are included in the masterpage like so:

Html.RenderAction("Form1", "Controller")

and

Html.RenderAction("Form2", "Controller")

The Controller has the following:

<ChildActionOnly()>
Function Form1() As ActionResult

    Return View("Form1", New ModelObject())

End Function

<ChildActionOnly()> <AcceptVerbs(HttpVerbs.Post)>
Function Form1(ByVal formCollection As FormCollection) As ActionResult

    Return View("Form1", New ModelObject())

End Function



<ChildActionOnly()>
Function Form2() As ActionResult

    Return View("Form2", New ModelObject())

End Function

<ChildActionOnly()> <AcceptVerbs(HttpVerbs.Post)>
Function Form2(ByVal formCollection As FormCollection) As ActionResult

    Return View("Form2", New ModelObject())

End Function

The forms markup in the ascx is as follows, they are essentially the same form so the markup is very similar:

<%  Using Html.BeginForm()%>
<%= Html.TextBoxFor(Function(model) model.Property1, New With {.class = "input"})%>
<input type="submit" class="submitbutton" value="" name="submit" />
<%  End Using%>

The problem is, when I submit either form, it runs both post methods.

So Form1 post and Form2 post, yet the values in the form collection are from which ever form was submitted.

My question is: Why is this submitting both forms with one set of form data? How can I make it call only the relevant action with the correct form data?

I am sure I am making a simple mistake, just cannot see it for looking.

Project that demonstrates the problem can be found here: TestMVC.zip

Thanks in advance.

A: 

I see that when you are rendering your forms, you are not naming them explicitly and you are also not mentioning form method. Can you please do something like this:

<% using (Html.BeginForm("ACTION", "CONTROLLER")) {%>

And if you are using child controls then why are you using "Html.RenderAction"? Shouldn't it be "Html.RenderPartial" like:

<% Html.RenderPartial("Search"); %>
Pradeep
no, as the forms should not be visible from the route on their own I am using <ChildActionOnly()> so have to use RenderAction. So cannot specify controller or action in the form as it will try and display that form on post at the form route, which I do not want. Unless I am missing something in how this should be done??
jimplode
I don't have discrete explanation but your Html.BeginForm() is the culprit. In that you are not specifying the action name. The result is that .net is automatically putting default action as "/" (check the view source). Having said that when you click either of the button, they are posting to same page and hence you are hitting "Post" of both the child forms. I am not sure why you don't want to go for RenderPartial? Is child route visible on URL is such a critical point?
Pradeep
Thank you for this explanation, and it makes sense. But what I want is these are effectively UserControls, self contained forms. I want to be able to include these anywhere in my site. If there is an easier or more correct way to achieve the same thing someone please educate me.
jimplode
An example of this is a "call me back" form for users to fill in regardless of the page they are on.
jimplode
If you want Call me back kind of functionality, then just as a suggestion you can implement that functionality in Ajax way. Post the data using JS and jQuery. That should work.
Pradeep
What about people who have JavaScript turned off??
jimplode
Can you use Request.IsAjaxRequest to provide different returns based on that? Might have to include a reference to the page in a View Model though, if this is in a usercontrol being used around different pages...
pete the pagan-gerbil
A: 

If you take [ChildActionOnly] off of your Post actions, it only submits to one action at a time.

So one way to consider it would be to try and find out how to return a partial view as the whole page. Maybe by storing the page's route in a ViewModel around your model, and using RedirectToAction on that route?

This link (http://dotnetslackers.com/articles/aspnet/ASP-NET-MVC-2-0-Using-Multiple-Actions.aspx) seems to suggest that removing ChildActionOnly is all you need to do, but doesn't work in your sample. Most confusing.

pete the pagan-gerbil
I have seen reference made to this being a bug in the MVC framework.... I can't believe this is something you cannot do in MVC!!
jimplode
+1  A: 

I have found a solution to the problem, was wondering if someone would like to comment on the correctness of this "work around".

ok... so step one, Remove the childonlyaction attribute from the post actions and add the controller/action to run when the form is submitted.

Html.BeginForm("Form1", "Form")

This makes sure that the correct post action is called.

The next step was to work out what I wanted to return.

So.. I need to return the custom model if there are validation errors etc. So thought I could do this using meta data or some other custom validation, add the model to TempData and then do a RedirectToAction making the action the page that I came from. i.e. /Home/Index or /Controller/Action

I get the controller/action from the referrer, that should always be set as this is coming from a post action.

Can anyone think of a better way of doing this?? As this is the only way I could find to give the results I want without using Ajax

jimplode