1

I hava a contact form, so that users can contact me. it is written in asp.net mvc, but the thing is that after submit without filled in any textbox, there comes no validation on the texboxes.

This is my form:

@using (Html.BeginForm("contact","Home", FormMethod.Post, new { @enctype = "multipart/form-data" }))
    {
        @Html.AntiForgeryToken()        
        @Html.ValidationSummary(true)

        <section id="contact" class="text-center">
            <div class="container">
                <div class="row">
                    <div class="col-md-12 wow fadeInDown" data-wow-delay="2000">
                        <h3>CONTACT Microrout.nl</h3>
                    </div>
                    <div class="col-md-2"></div>
                    <div class="col-md-8">

                        Microrout.nl
                        <br />frederik hendriklaan 253-b
                        <br />Den Haag
                        <br />0641697144


                    </div>
                    <div class="col-md-2"></div>
                    <hr />
                    <div class="form-group">

                        <div class="col-md-10">
                            @Html.TextBoxFor(m => m.FromName, new {placeholder = "Your Name", @class = "form-control" })
                            @Html.ValidationMessageFor(m => m.FromName)
                        </div>
                    </div>

                    <div class="form-group">

                        <div class="col-md-10">
                            @Html.TextBoxFor(m => m.subject, new {placeholder = "Subject of message", @class = "form-control" })
                            @Html.ValidationMessageFor(m => m.subject)
                        </div>
                    </div>

                    <div class="form-group">

                        <div class="col-md-10">
                            @Html.TextBoxFor(m => m.FromEmail, new {placeholder ="Your email", @class = "form-control" })
                            @Html.ValidationMessageFor(m => m.FromEmail)
                        </div>
                    </div>
                    <div class="form-group">

                        <div class="col-md-10">
                            @Html.TextAreaFor(m => m.Message, new {placeholder = "Your message", @class = "form-control" })
                            @Html.ValidationMessageFor(m => m.Message)
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-md-3">
                            <input type="submit" value="SHOOT MESSAGE" class="form-control">
                        </div>
                    </div>
                </div>
            </div>
            @*<div class="google_map">
                    <div id="map-canvas"></div>
                </div>*@


        </section>
    }






</section>

and this is my method in controller:

public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Contact(EmailFormModel model)
        {
            string message2 = "There are a few errors";
            if (ModelState.IsValid)
            {




                    var body = "<p>Email From: {0} ({1})</p><p>Message:</p><p>{2}</p>";
                    var message = new MailMessage();
                    message.To.Add(new MailAddress("nengelen@online.nl")); //replace with valid value
                    message.Subject = model.subject;
                    message.Body = string.Format(body, model.FromName, model.FromEmail, model.Message);
                    message.IsBodyHtml = true;

                    using (var smtp = new SmtpClient())
                    {
                        await smtp.SendMailAsync(message);

                    }

                    message2 = "Thanks! We'll get back to you soon.";






                    //Response.Write("Error sending email: " + error.Message + "<br /> StackTrace: " + error.StackTrace);

                //ViewBag.Message = "Thank you for contact us";
                //return new RedirectToActionAnchor("Contact", "", "#contact");

            }

            if (Request.IsAjaxRequest())
            {
                return new JsonResult { Data = new { success = true, message = message2 } };
            }

            TempData["Message"] = message2;


            return new RedirectResult(Url.Action("") + "#contact");
        }

I have it now like this:

public ActionResult Contact()
        {
            EmailFormModel model = TempData["EmailFormModel"] as EmailFormModel; 
            ViewBag.Message = "Your contact page.";


            return View();
        }

[HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Contact(EmailFormModel model)
        {
            TempData["EmailFormModel"] = model;
            string message2 = "There are a few errors";
            if (ModelState.IsValid)
            {




                var body = "<p>Email From: {0} ({1})</p><p>Message:</p><p>{2}</p>";
                var message = new MailMessage();
                message.To.Add(new MailAddress("nengelen@online.nl")); //replace with valid value
                message.Subject = model.subject;
                message.Body = string.Format(body, model.FromName, model.FromEmail, model.Message);
                message.IsBodyHtml = true;

                using (var smtp = new SmtpClient())
                {
                    await smtp.SendMailAsync(message);

                }

                return new RedirectResult(Url.Action("") + "#contact");
            }

            if (Request.IsAjaxRequest())
            {
                return new JsonResult { Data = new { succes = true, message = message2 } };
            }
            TempData["Message"] = message2;
            return View(model);

        }

and this is the model:

 public class EmailFormModel
    {
        [Required, Display(Name="subject")]
        public string subject { get; set; }
        [Required, Display(Name = "Your name")]
        public string FromName { get; set; }
        [Required, Display(Name = "Your email"), EmailAddress]
        public string FromEmail { get; set; }
        [Required]
        public string Message { get; set; }
    }

I am using smoothScroll navigation, like this:

<div class="collapse navbar-collapse">
                        <ul class="nav navbar-nav navbar-right">
                            <li><a href="#home" class="smoothScroll">HOME</a></li>
                            <li><a href="#about" class="smoothScroll">STUDIO</a></li>
                            <li><a href="#team" class="smoothScroll">TEAM</a></li>
                            <li><a href="#service" class="smoothScroll">SERVICES</a></li>
                            <li><a href="#work" class="smoothScroll">WORK</a></li>
                            <li><a href="#pricing" class="smoothScroll">PRICING</a></li>
                            <li><a href="#contact" class="smoothScroll">CONTACT</a></li>
                            @*<li>@Html.ActionLink("Contact", "Contact", "Home")
                            </li>*@
                        </ul>
                    </div>

so in the navigation it jumps to the correct area of the index page

I have it now like this:

[HttpGet]
        public ActionResult Contact(string uniqueUri)
        {
            EmailFormModel model = TempData["EmailFormModel"] as EmailFormModel;
            //ViewBag.Message = "Your contact page.";


            return View(model);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Contact(EmailFormModel model)
        {
            TempData["EmailFormModel"] = model;
            string message2 = "There are a few errors";
            if (ModelState.IsValid)
            {
                var body = "<p>Email From: {0} ({1})</p><p>Message:</p><p>{2}</p>";
                var message = new MailMessage();
                message.To.Add(new MailAddress("nengelen@online.nl")); //replace with valid value
                message.Subject = model.subject;
                message.Body = string.Format(body, model.FromName, model.FromEmail, model.Message);
                message.IsBodyHtml = true;

                using (var smtp = new SmtpClient())
                {
                    await smtp.SendMailAsync(message);

                }

                return new RedirectResult(Url.Action("") + "#contact");
            }
            else
            {
                ModelState.AddModelError("ReviewErrors", "some error occured");
                //return RedirectToAction("Create", new { uniqueUri = Request.RequestContext.RouteData.Values["uniqueUri"] });
                return new RedirectResult(Url.Action("") + "#contact");
            }


        }

I have it now like this:

        public ActionResult Contact()
        {
            EmailFormModel model = TempData["EmailFormModel"] == null ? new EmailFormModel() : (EmailFormModel)TempData["EmailFormModel"];
            ViewBag.Message = "Your contact page.";
            return View(model);



        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Contact(EmailFormModel model)
        {
            TempData["EmailFormModel"] = model;
            string message2 = "There are a few errors";
            if (ModelState.IsValid)
            {
                var body = "<p>Email From: {0} ({1})</p><p>Message:</p><p>{2}</p>";
                var message = new MailMessage();
                message.To.Add(new MailAddress("nengelen@online.nl")); //replace with valid value
                message.Subject = model.subject;
                message.Body = string.Format(body, model.FromName, model.FromEmail, model.Message);
                message.IsBodyHtml = true;

                using (var smtp = new SmtpClient())
                {
                    await smtp.SendMailAsync(message);

                }

                return new RedirectResult(Url.Action("") + "#contact");
            }
            else
            {
                ModelState.AddModelError("ReviewErrors", "some error occured");
                //return RedirectToAction("Create", new { uniqueUri = Request.RequestContext.RouteData.Values["uniqueUri"] });
                return new RedirectResult(Url.Action("") + "#contact");
            }


        }

and in debug mode, if I dont fill in the fields, it comes in this:

else
                {
                    ModelState.AddModelError("ReviewErrors", "some error occured");
                    //return RedirectToAction("Create", new { uniqueUri = Request.RequestContext.RouteData.Values["uniqueUri"] });
                    return new RedirectResult(Url.Action("") + "#contact");
                }

but the validation is not visible

Thank you all for your efforts. But I just made an new contact page and now it works correct. Just have to figure out, with the correct linking in the navigation, but there for I just made new question. I just marked DaWood as the best solution, becuase you can' t make multiple marks as answare.

So thank you All!!

InfinityGoesAround
  • 1,011
  • 4
  • 17
  • 31
  • What do you have `if (Request.IsAjaxRequest())` in your POST method? Are you submitting the form using ajax (in which case no validation errors will be show) or doing a normal submit? –  May 07 '15 at 00:56
  • It looks like it is doing full post, after submit – InfinityGoesAround May 07 '15 at 07:35

3 Answers3

2

You are missing:

if (!ModelState.IsValid)
{
    return View(model);
}

You need to render the view with the problem. The framework will then pick up the validation errors and display them.

beautifulcoder
  • 10,832
  • 3
  • 19
  • 29
1

After

if(ModelState.IsValid)

You are calling:

 return new RedirectResult(Url.Action("") + "#contact");

Which refreshes the Page and clears the ModelState.

If you need to call RedirectResult follow this link

ASP.NET MVC - How to Preserve ModelState Errors Across RedirectToAction?

OR

You need to return View(model) to get the Validation Errors.

if(ModelState.IsValid)
{
 // ...........Other Code:
 return new RedirectResult(Url.Action("") + "#contact");
}
if (Request.IsAjaxRequest())
{
return new JsonResult { Data = new { success = true, message = message2 } };
}

TempData["Message"] = message2;    
return View(model);

EDIT:

public ActionResult Contact()
{
  EmailFormModel model = TempData["EmailFormModel"] == null ? new EmailFormModel() : (EmailFormModel) TempData["EmailFormModel"]; 
  ViewBag.Message = "Your contact page.";
  return View(model);
}
Community
  • 1
  • 1
Dawood Awan
  • 7,051
  • 10
  • 56
  • 119
  • Comments are not for extended discussion; this conversation has been [moved to chat](http://chat.stackoverflow.com/rooms/77302/discussion-on-answer-by-dawood-awan-validation-is-not-visible). – Taryn May 08 '15 at 12:16
0

You need to add the else when the model state is not valid. And move your return inside the if so that when the model state is valid you return inside the positive check of the model. The view is returned when the model state is not valid which will preserve your model state data.

if (ModelState.IsValid)
        {
                var body = "<p>Email From: {0} ({1})</p><p>Message:</p><p>{2}</p>";
                var message = new MailMessage();
                message.To.Add(new MailAddress("nengelen@online.nl")); //replace with valid value
                message.Subject = model.subject;
                message.Body = string.Format(body, model.FromName, model.FromEmail, model.Message);
                message.IsBodyHtml = true;

                using (var smtp = new SmtpClient())
                {
                    await smtp.SendMailAsync(message);

                }

                message2 = "Thanks! We'll get back to you soon.";






                //Response.Write("Error sending email: " + error.Message + "<br /> StackTrace: " + error.StackTrace);

            //ViewBag.Message = "Thank you for contact us";
            //return new RedirectToActionAnchor("Contact", "", "#contact");
            TempData["Message"] = message2;
        if (Request.IsAjaxRequest())
        {
            return new JsonResult { Data = new { success = true, message = message2 } };
        }

            return new RedirectResult(Url.Action("") + "#contact");
        }
        else
        {
            return View();
        }

Also, you may want to enable the built in client side validation to save the round trip to the server if the model is not valid.

Trucktech
  • 328
  • 1
  • 11
  • Your **if (Request.IsAjaxRequest())** Will never get executed – Dawood Awan May 06 '15 at 15:08
  • but now the if() will not be called – InfinityGoesAround May 06 '15 at 15:35
  • Oops. Edited my answer – Trucktech May 06 '15 at 22:20
  • Hi Truk, thank you for your edit, but here is also the problem: return View() goes to: http://localhost:53534/Home/contact, but the link of contact is: http://localhost:53534/#contact – InfinityGoesAround May 07 '15 at 07:43
  • You simply want to return the View that the post came from so that the validation messages can be seen by the user. Leaving the `View()` empty will return the view named the same as the controller action you are in. If you want to call a specific view you can call it explicitly such as `return View("your view name here")` . You don't want to call a controller action at this point, just returning a view with the error messages. If you call the action it will return a new view that will not include your error messages. – Trucktech May 07 '15 at 14:18