1

I know that maybe the title sounds a bit weird but I believe that my problem is weird indeed. I have an ASP.NET MVC 4 application (this is my first MVC real-world application) with Razor view-engine.

I have a layout view where I'm rendering two partial views like this:

 <!-- Login -->
@Html.Action("RenderLoginPopup", "Login")

<!-- Registration -->
@Html.Action("RenderRegisterPopup", "Login")

Each of those actions from the Login controller just renders a partial view:

    [ChildActionOnly]
    public ActionResult RenderLoginPopup()
    {
        return PartialView("Partial/_LoginPopupPartial");
    }

Just for exemplification sake (both are built the same way), the login partial view contains an ajax form like this:

@using (Ajax.BeginForm("Login", "Login", new AjaxOptions()
    {
        HttpMethod = "POST",
        OnSuccess = "loginResponseReceived"
    }, new { @id = "loginForm" }))

The Login action from the Login controller (the target of the form) is signed with the following attributes (worth to mention and notice the HttpPost one):

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public JsonResult Login(LoginModel model)
    { }

So far, so good... Everything works perfect - both the login and the register actions are working without any issues.

The issue that I want to speak about shows-up when I have a @Html.BeginForm() in a view that is loaded along with the main layout. For example, if I have a pure and simple form like this:

    @using (Html.BeginForm())
    {
       <input type="hidden" name="name"/>
       <input type="submit" value="Send"/>
    }

along with the controller CaptionExtendedController:

    [HttpPost]
    public ActionResult Index(string nume)
    {
        return View();
    }

So, in the end, in my final html generated file I will have 3 forms - 2 for login and register (ajax) and one simple form generated from the last view. Please keep in mind that all three forms are independent (meaning that they are not one in another).

The issue is that everytime I'm pressing the button "Send" from the last form all controllers that are signed with the [HttpPost] attribute from my view (Login, Register from LoginController and Index from CaptionExtendedController) gets called.

WHY??? In order to have a temporary fix, I've removed the [HttpPost] attribute from the Login and Register actions and now it's working but I don't think this is correct.

Please, there is someone who can explain me why this is happening and eventually point me to the right direction in fixing this issue?

Thank you in advance.

Edi
  • 660
  • 9
  • 22
  • I would assign an ID to each form and handle them with jQuery like [here](http://stackoverflow.com/a/5410121/956051) – Lars Apr 02 '13 at 14:00
  • The first 2 are already made with jquery through Ajax.BeginForm but I need to have the 3rd one to be normal form. Also, if I would do it like this, it will mean that all forms from now on, from my website should be done using Ajax.BeginForm or jquery, right? This doesn't sound like an option for now. Thank you for your time. – Edi Apr 02 '13 at 14:24

3 Answers3

0

Try specifying the controller and action with your Html.BeginForm and we can start from there. Also, you can utilize @Html.RenderPartial to render your partials which would get rid of some of your unneeded actions/controllers, making it a bit more manageable.

  • That is a good idea. Another consideration which I can't tell from your posted code: Is it possible that the closing of the using blocks for the async forms are missing or misplaced somehow? I would guess not, but if you have
    that might explain it.
    – Michael Kennedy Apr 02 '13 at 15:37
  • Thank you all. Step by Step: @MichaelKennedy - there is no overlapping of the form open / close / using statements; I also checked the HTML generated file and all forms are opening and closing perfectly OK. – Edi Apr 02 '13 at 16:33
  • The example with the Html.BeginForm was from a simple page created just for test, but always all my Html.BeginForm or Ajax.BeginForm receives the action and controller as parameter. Regarding the Html.RenderPartial instead of Html.Action - I've used the later version because I wanted for my partial views (Login and Register) their own context and their own models; I know that I can pass an empty (new) model using RenderPartial (which is OK for login) but for Register I need to populate some data (DDLs, etc) in its own controller. – Edi Apr 02 '13 at 16:35
  • Not sure if this makes any difference but I did see a spelling error on your Index action - string nume. If this was copy and pasted, that may also be a possible reason. – Mike Henderson Apr 02 '13 at 18:06
  • "Nume" it is but just for "english" sake I translated to name but maybe I haven't did it on all places. On the other hand, I've entered into debug mode (vs 2012) and I've put breakpoints on all httppost actions from my page (login, register and index) and all 3 breakpoints are reached. – Edi Apr 02 '13 at 18:37
0

This doesn't address the root problem, but might be a work-around which is all you need anyway. :)

You could write some jQuery which catches the button click and then submits the form directly by name. For example, if you add the id below:

@using (Html.BeginForm())
{
   <input type="hidden" name="name"/>
   <input type="submit" id="regularSubmitButton" value="Send"/>
}

Then you could write:

$(document).ready(function() {
   $("#regularSubmitButton").click(function(e) {
       e.preventDefault();

       $(this).parent("form").submit();

       return false;
   });
});

I'm not sure it would work without seeing everything, but seems to be worth a try.

Cheers, Michael

Michael Kennedy
  • 3,202
  • 2
  • 25
  • 34
  • Hmmm... This leads me to another idea - to put some "breakpoints" (console.log) to those forms' submit events but earlier today I've watched what is happening in Fiddler and only one form submits actually... – Edi Apr 02 '13 at 16:39
  • It seems that I found a similar issue but still no response... :( http://stackoverflow.com/questions/11662852/submiting-one-form-posting-all-other-forms-in-the-page/15769866# – Edi Apr 02 '13 at 16:58
0

It doesn't make sense anymore... Starting from the comments and answers, I've mapped 3 functions to the submits on those tricky forms: login, register and index (also I've put back the HttpPost attribute to the Login and Register actions). In those jquery functions I've just put an alert with a string (name of the form); in order to be able to write a jquery id-based selector, I've declared also the last form with an id (it didn't had it; only login and register had one), like this (an example taken from another form with the same issue):

@using (Html.BeginForm("Index", "PersonalizeCard", new {data = Model.EncryptedDataQueryStringValue}, FormMethod.Post, new {@id = "personalizeCardForm"})) { }

(what has been added - last two parameters - form method and html id).

After this, I've run the application and no exception anymore... I've put breakpoints on the login and register actions - nothing... I've even removed those 2 extra parameters from the BeginForm - still nothing...

WHY???? Again, why??? I mean, I'm not upset that it's fixed but I don't understand why it's fixed by itself...

THANK YOU FOR ALL YOUR TIME AND COMMENTS / ANSWERS.

Edi
  • 660
  • 9
  • 22