1

I'm beggining to learn Asp.net and C# for about a week. Until now, I've been developing in PHP and Symfony so this is quite a big transition for me. I'm learning Asp.net from a book ASP.NET MVC 4 in Action.

I'm trying to validate a model but I can't find anything online that will help a newbie like me. A model validates a contact form with name, email and a message. Simple, right?. Not for me.

This is the model...

public class ContactModel
{
    [Required(ErrorMessage = "The name has to be provided, even a fictional one")]
    public string Name { set; get; }

    [Required(ErrorMessage = "Email address has to be provided, even a invalid one")]
    [DataType(DataType.EmailAddress)]
    public string Email { set; get; }

    [Required(ErrorMessage = "Don't be lazy. Write a message")]
    [DataType(DataType.MultilineText)]
    public string Message { set; get; }
}

I have a controller called ContactController. It has these actions...

public ActionResult Contact()
{
    ContactModel contactModel = new ContactModel();
    return View(contactModel);
}

[HttpPost]
public ViewResult SaveModel(ContactModel model)
{
    return View(model);
}

Also, here is a Razor template that shows the model in the UI.

<div class="UI__Main  Main__Contact">
<h1 class="UI__Main--SectionHeader">Contact the administrators of Life</h1>

    @using (Html.BeginForm("SaveModel", "Contact", FormMethod.Post, new { @class="Form  Form__Contact" }))
    {
        <div class="Form__Row">
            @Html.LabelFor(model => model.Name, new { @class="Form__Label" })
            @Html.TextBoxFor(model => model.Name, new { @class="Form__TextType  Form__TextInput" })
            @Html.ValidationMessageFor(model => model.Name)
        </div>

        <div class="Form__Row">
            @Html.LabelFor(model => model.Email, new { @class = "Form__Label" })
            @Html.TextBoxFor(model => model.Email, new { @class = "Form__TextType  Form__TextInput" })
        </div>

            <div class="Form__Row">
                @Html.LabelFor(model => model.Message, new { @class="Form__Label" })
                @Html.TextArea("Message", new { @class = "Form__TextType  Form__TextArea" })
            </div>

        <div class="Form__Row  Submit__Row">
            <input id="Submit__Button" type="submit" value="Send" />
        </div>
    }

When the user submits the form, the form would have to go to SaveModel action in ContactController but action attribute of <form> is blank action="" so i don't think it's even going to Save Model. Also, validation messages are not displayed. I tried the @Html.ValidationMessageFor but that only displays text even when i don't submit the form.

I don't even know what the problem is here let alone find it.

If anyone has any suggestions, tutorials, articles or something like that about creating form in asp.net mvc 4 and razor, please give it to me.

I've read this article but that doesn't solve my problem. I also found this Stack question and this Stack question but as i said, I'm a newbie and I really don't understand the problems in those questions.

EDIT:

Here are the routes of the app...

routes.MapRoute(
    name: null,
    url: "",
    defaults: new { controller = "Home", action="Index" }
);

routes.MapRoute(
    name: null,
    url: "contact",
    defaults: new { controller = "Contact", action = "Contact" }
);
2
  • Have you implemented any extra routes, besides the default one? Commented Nov 7, 2014 at 13:48
  • I've made an edit. ContactController/ContactAction is called with a static route but , my guess is that model validation has to go to another action, which is SaveModel action in ContactController. Commented Nov 7, 2014 at 13:53

1 Answer 1

1

your action stays empty because the MVC framework can not resolve an url for the given controller+action. You have to explicitly define an url in the routing table:

routes.MapRoute(
    name: null,
    url: "contact/send-form",
    defaults: new { controller = "Contact", action = "SaveModel" }
);

Or you can alternatively generate a generic fallback route

routes.MapRoute(
    name: null,
    url: "{controller}/{action}",
    defaults: new { controller = "Home", action = "Index" }
);

which will result in that all your controller/actions are available as direct urls.

Alternatively; you can also use attribute routing so your routes are defined directly at the actions, less looking here & there. To do so you have to:

  • add routes.MapMvcAttributeRoutes(); in the RegisterRoutes.cs
  • append attributes to your actions [Route("contact")]

You can also re-use the same route if the http method differs:

[HttpGet]
[Route("contact"}
public ActionResult Contact()
{
    ContactModel contactModel = new ContactModel();
    return View(contactModel);
}

[HttpPost]
[Route("contact")]
public ViewResult Contact(ContactModel model)
{
  if(ModelState.IsValid){
    //persist your contact form, redirect somewhere
  }
  return View(model);//re-render the form with error messages
}
Sign up to request clarification or add additional context in comments.

2 Comments

YES. That was it. Thank you very much. The error message displayes nicely.
Usage a route attributes are only essential if you have to use in a case when url must have other form than wrote in Route map. Otherwise is reccomended to avoid this parameter. This way determines rigorous an approach to your project.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.