I'm using MVC and Razor for the first time and have what is hopefully a really easy question. I have two pages on the site. The first page (Page A) has a very small form on it which has an input for an email address. when the user enters their email address and clicks submit they are sent to page B using HttpPost, like so:
@using (Html.BeginForm("NewsletterSignup","Common", FormMethod.Post))
{
<p>
<input type="text" class="text" value="Enter your email address" id="email" name="email" />
<input type="submit" class="submit" value="Sign Up" />
</p>
}
On Page B there is the main form which allows the user to also enter their name and mobile number. The controller for the main form looks like so:
//newsletter signup page
public ActionResult NewsletterSignup()
{
var model = new NewsletterSignupModel();
return View(model);
}
[HttpPost, ActionName("NewsletterSignup")]
public ActionResult NewsletterSignupSend(NewsletterSignupModel model)
{
if (ModelState.IsValid)
{
//register the user here
}
return View(model);
}
On the main form I have a Validationsummary and validation for each of the fields. The problem is that my contoller states that the NewsletterSignupSend action can only be executed using HttpPost. Because the form on Page A uses HttpPost when the user arrives on Page B the validation has already been run - i.e. before the user has submitted the form on Page b.
I know I'm missing a basic here - can someone steer me in the right direction?
Thanks in advance Al
UPDATE: To resolve this question I have done the following.
Form A is rendered using:
@Html.Action("MiniNewsletterSignup")
Form A has a controller method:
//mini newsletter view
public ActionResult MiniNewsletterSignup()
{
var model = new MiniNewsletterSignupModel();
return View(model);
}
And the content of the view is:
@model Nop.Web.Models.Common.MiniNewsletterSignupModel
@using (Html.BeginForm("NewsletterSignup", "Common"))
{
<p>
<input type="text" class="text" value="Enter your email address" id="email" name="email" />
<input type="submit" class="submit" value="Sign Up" />
</p>
}
This submits the form using HttpPost off to Page B.
Page B has 2 controller methods:
//newsletter signup page
public ActionResult NewsletterSignup()
{
var model = new NewsletterSignupModel();
if (Request["email"] != null)
model.Email = Request["email"];
return View(model);
}
And:
[HttpPost, **WhenRequestContainsKey("FullName")**]
public ActionResult NewsletterSignup(NewsletterSignupModel model)
{
if (ModelState.IsValid)
{
//process here
}
return View(model);
}
You will notice I have added the Selector WhenRequestContainsKey which I found at http://softwaredevelopmentsolutions.blogspot.co.uk/2011/06/aspnet-mvc-3-partial-form-validation-on.html. This means this code is only called when there is a field in the Request called FullName, which on our site only exists on Page B.
This seems to work as I wanted it, but Im not sure why - why for example does this stop the validation taking place until the form is posted back on Page B - there is nothing in the method that calls a validate method???
Is there anything wrong with the way Ive implemented this?
Thanks Al
I think you are missing a post action - if you try to follow the pattern GET-POST-Redirect you should avoid these issues (i.e. every post should redirect to a GET action):
FirstAction()
{
return View();
}
[HttpPost]
FirstAction()
{
//Save email address
return Redirect("NewsletterSignup","Common");
}
And your first form becomes:
@using (Html.BeginForm())
{
<p>
<input type="text" class="text" value="Enter your email address" id="email" name="email" />
<input type="submit" class="submit" value="Sign Up" />
</p>
}
Put a [HttpGet]
on the first one:
[HttpGet]
public ActionResult NewsletterSignup()
{
var model = new NewsletterSignupModel();
return View(model);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With