ASP.NET MVC 5 Form Validation

44,298

There is one error in your code, I didn't notice first. In the get method you are using -

return View();

Which means your view does not allow parameter but when there is an error you are using -

return View(lead);

In this case MVC is looking for the view with the same name but which also accepts a parameter of Lead type and it fails since there is no view with that option and the only one that is found does not accept parameter as seen from the Get method. When there is no error, you are redirecting to -

return RedirectToAction("SubmissionConfirmed", lead);

and the View with the parameter is never needed to be searched and thus no error.

So, change the view to accept a parameter of Lead and change your get method accordingly.

May be this would help. -

[HttpGet]
public ActionResult ContactSubmit()
{
    var lead = new Lead();
    return View(lead);
}

and in the view add

@model Lead

at the top

EDIT : In case since you are redirecting you should know that ModelState gets initialized in each request, so redirecting clears it automatically. You have to use some other means to pass modelstate or better if you use client side validation.

Share:
44,298
BoredOfBinary
Author by

BoredOfBinary

Updated on June 09, 2020

Comments

  • BoredOfBinary
    BoredOfBinary almost 4 years

    I am new to ASP.NET MVC and using version 5. I created a form that is in the layout, and I cannot cannot get it to show validation errors on the view. It will post to the action correctly, and if the model is valid, it will execute. If the model is invalid I will get the following error.

    I am hoping someone can point me in the right direction. Thank you in advance!

    Server Error in '/' Application.
    
    The view 'ContactSubmit' or its master was not found or no view engine supports the searched locations. The following locations were searched:
    ~/Views/Home/ContactSubmit.aspx
    ~/Views/Home/ContactSubmit.ascx
    ~/Views/Shared/ContactSubmit.aspx
    ~/Views/Shared/ContactSubmit.ascx
    ~/Views/Home/ContactSubmit.cshtml
    ~/Views/Home/ContactSubmit.vbhtml
    ~/Views/Shared/ContactSubmit.cshtml
    ~/Views/Shared/ContactSubmit.vbhtml
    

    This is my model I am using:

    public partial class Lead
    {
        [Key]
        public int LeadId { get; set; }
    
        [Required]
        [StringLength(50, MinimumLength=2, ErrorMessage="* A valid first name is required.")]
        [Display(Name="First Name")]
        public string FirstName { get; set; }
    
        [Required]
        [StringLength(50, MinimumLength=2, ErrorMessage="* A valid last name is required.")]
        [Display(Name="Last Name")]
        public string LastName { get; set; }
    
        [Required]
        [StringLength(50, MinimumLength=2, ErrorMessage="* A valid company is required.")]
        public string Company { get; set; }
    
        [Required]
        [StringLength(50)]
        [EmailAddress(ErrorMessage="* A valid email address is required.")]
        public string Email { get; set; }
    
        [Required]
        [StringLength(15, MinimumLength=9, ErrorMessage="* A valid phone nunber is required.")]
        [Phone(ErrorMessage="Please enter a valid phone number.")]
        public string Phone { get; set; }
    }
    

    This is the code I have in my Home controller:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult ContactSubmit(
        [Bind(Include = "FirstName, LastName, Company, Email, Phone")]
        Lead lead)
    {
        try
        {
            if (ModelState.IsValid)
            {
                lead.Tenant = SessionManager.Get<Tenant>(Constants.SessionTenant);
                lead.Refferer = SessionManager.Get<string>(Constants.SessionRefferal);
                DataStoreManager.AddLead(lead);
                return RedirectToAction("SubmissionConfirmed", lead);
            }
        }
        catch (DataException /* dex */)
        {
            ModelState.AddModelError("", "Unable to perform action. Please contact us.");
            return RedirectToAction("SubmissionFailed", lead);
        }
    
        return View(lead);
    }
    
    [HttpGet]
    public ActionResult ContactSubmit()
    {
        return View();
    }
    

    This is the form that I have in my layout:

                   @using (Html.BeginForm("ContactSubmit", "Home", FormMethod.Post))
                        {
                            @Html.AntiForgeryToken()
                            <fieldset>
                                <div class="editor-label">
                                    @Html.LabelFor(m => m.FirstName)
                                </div>
                                <div class="editor-field">
                                    @Html.EditorFor(m => m.FirstName)
                                    @Html.ValidationMessageFor(m => m.FirstName)
                                </div>
    
                                <div class="editor-label">
                                    @Html.LabelFor(m => m.LastName)
                                </div>
                                <div class="editor-field">
                                    @Html.EditorFor(m => m.LastName)
                                    @Html.ValidationMessageFor(m => m.LastName)
                                </div>
    
                                <div class="editor-label">
                                    @Html.LabelFor(m => m.Company)
                                </div>
                                <div class="editor-field">
                                    @Html.EditorFor(m => m.Company)
                                    @Html.ValidationMessageFor(m => m.Company)
                                </div>
    
                                <div class="editor-label">
                                    @Html.LabelFor(m => m.Email)
                                </div>
                                <div class="editor-field">
                                    @Html.EditorFor(m => m.Email)
                                    @Html.ValidationMessageFor(m => m.Email)
                                </div>
    
                                <div class="editor-label">
                                    @Html.LabelFor(m => m.Phone)
                                </div>
                                <div class="editor-field">
                                    @Html.EditorFor(m => m.Phone)
                                    @Html.ValidationMessageFor(m => m.Phone)
                                </div>
                                <div class="masthead-button-wrapper">
                                    <input class="btn btn-warning" type="submit" value="Submit" />
                                </div>
                            </fieldset>
                        }
    
  • BoredOfBinary
    BoredOfBinary almost 10 years
    Yes, I have both of those set
  • BoredOfBinary
    BoredOfBinary almost 10 years
    Tried that and still doesn't work. Just to make sure that your aware, the form in in a layout template, so if I am on index it should go back to the index form with the validation errors.
  • brainless coder
    brainless coder almost 10 years
    Nope it won't, when you redirect, validation errors are cleared.
  • BoredOfBinary
    BoredOfBinary almost 10 years
    Are you saying that I need to use client validation?
  • brainless coder
    brainless coder almost 10 years
    Yep that's better. Because ModelState gets initialized in each request, so redirecting clears it automatically. You have to use some other means to pass modelstate or better if you use client side validation.
  • BoredOfBinary
    BoredOfBinary almost 10 years
    Actually that was way too easy, thank you. I only wasted an entire day because of my ignorance :)
  • brainless coder
    brainless coder almost 10 years
    Glad it helped. Make sure to mark it as the answer, someone might also wasting the day for it.. :)