4

I am using ASP.net core razor engine. I am trying to display my error in my html. Not sure how to go about fixing my code. How do I display the errors from ModelState.Values in my cshtml page?

Here is my controller

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using quotingDojo.Models;

namespace quotingDojo.Controllers
{
    public class HomeController : Controller
    {
        // GET: /Home/
        [HttpGet]
        [Route("")]
        public IActionResult Index()
        {
            return View();
        }

        [HttpPost]
        [Route("quotes")]
        public IActionResult Quotes(string Name, string Quote)
        {
            Home NewHome = new Home
            {
                Name = Name,
                Quote = Quote
            };

            if(TryValidateModel(NewHome) == false) {
                ViewBag.errors = ModelState.Values;
                System.Console.WriteLine("??????????????"); 
                System.Console.WriteLine(ModelState.ErrorCount);         
                System.Console.WriteLine("??????????????"); 
            }

            return RedirectToAction("Index");
        }
    }
}

ModelState.ErrorCount prints out the correct number of errors.

Here is my model

using System.ComponentModel.DataAnnotations;


namespace quotingDojo.Models
{
    public class Home
    {
        [Required(ErrorMessage ="Please enter your name")]
        [Display(Name="*username")]
        [DataType(DataType.Text)]
        [MinLength(3)]
        public string Name {get; set;}

        [Required]
        [MinLength(5)]
        public string Quote{get; set;}
    }
}

Here is my cshtml page

<div id="wrapper">  
    <h1>Welcome to the Quoting Dojo</h1>
    <form action="quotes" method="post">
        <p>
            <label>Your Name</label>
            <input type="text" name="Name"/>
        </p>
        <p>
            <label>Your Quote</label>
            <textarea name="Quote" id="quote" cols="30" rows="10"></textarea>
        </p>
        <input type="submit" name="submit" value="Add my quote!"/>
        <form action="quotes" method="get">
            <input type="submit" name="submit" value="Skip to quotes!"/>
        </form>
    </form>

 </div>

<div>
    <p> Test</p>
    @{
        if(ViewBag.errors != null)
        {
            foreach(var error in ViewBag.errors)
            {
                //If there are any errors for a field...
                if(@error.errors.Count > 0)
                {
                    // We show the first error for that field
                    <p>@error.errors[0].ErrorMessage</p>
                }
            }
        }

    }
</div>

I am using Visual Studio Code so anything build into regular Visual Studio I do not have access build in.

2 Answers 2

8

There is no need to pass errors explicitly by using ViewBag. The model state dictionary will have the errors when model validation fails. All you have to do is to execute your code when the model validation passes.

Also, since you already have a class, you can use that as the parameter of your http post action method. The default model binder will be able to map the form values to the properties of this class's object.

[HttpPost]
[Route("quotes")]
public IActionResult Quotes(Home model)
{
  if(!ModelState.IsValid)
  {
    return View(model);
  }
  //continue your code to save
  return RedirectToAction("Index");
}

And in the view you may use the validation helper methods to display the validation errors

@Html.ValidationSummary(false)

Also , i noticed you have nested forms in the view. Nested forms are not valid markup. So i suggest you fix that as well.

<h1>Welcome to the Quoting Dojo</h1>
@using(Html.BeginForm("Quote","Home"))
{
    <p>@Html.ValidationSummary(false)</p>
    <p>
        <label>Your Name</label>
        @Html.TextBoxFor(s=>s.Name)
    </p>
    <p>
        <label>Your Quote</label>
        @Html.TextAreaFor(d=>d.Quote)
    </p>
    <input type="submit" name="submit" value="Add my quote!"/>

}
<form action="quotes" method="get">
    <input type="submit" name="submit" value="Skip to quotes!"/>
</form>
4
  • Sorry ! My if condition was wrong :( Please take a look at the updated post
    – Shyju
    Commented Dec 30, 2016 at 19:53
  • The if condition was correct. If the modelState is valid return to the view else redirect to index
    – Aaron
    Commented Dec 30, 2016 at 19:56
  • No ! If the Model state is valid, continue saving and then redirect, If model state is not valid, return to the same view where we will show the validation error messages
    – Shyju
    Commented Dec 30, 2016 at 20:00
  • Got it, now I have to figure out how to get them to display on the Index.cshtml page
    – Aaron
    Commented Dec 30, 2016 at 20:06
1

Explicit Model Validation – This is the traditional way to validate the model data by using IF..Else..IF statement. In this way, you need to check your model property values one by one for your desired result. If model property values are unexpected, inject error messages within ModelState. see example below

public class HomeController : Controller
{
 [HttpPost]
  public ActionResult ExplicitServer(UserViewModel model)
     {
   //Write custom logic to validate UserViewModel
   if (string.IsNullOrEmpty(model.UserName))
   {
     ModelState.AddModelError("UserName", "Please enter your
  name");
 }
  if (!string.IsNullOrEmpty(model.UserName))
  {
    Regex emailRegex = new Regex(".+@.+\\..+");
     if (!emailRegex.IsMatch(model.UserName))

       ModelState.AddModelError("UserName", "Please enter correct
        email address");
   }

   if (ModelState.IsValid) //Check model state
  {
      //TO DO:
   }
  }
  }
2
  • 1
    I know this is an old answer but how would you go about displaying the errors in the view based on the key?
    – Mkalafut
    Commented Jun 5, 2019 at 13:44
  • @Mkalafut You can use something like this: @Html.ValidationMessageFor(m => m.UserName)
    – zak
    Commented Sep 7, 2022 at 14:12

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.