I am new to web development and trying to learn ASP.Net MVC 5. I am looking for one record in database if the record is not found then I want to display an error message to the user. Below is my attempt:
Controller
[HttpGet]
public ActionResult Search()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Search(ForgotPasswordMV viewModel)
{
if (Temp.Check(viewModel.Email))
return RedirectToAction("VerifyToken", new { query = viewModel.Email });
else
{
ViewBag.ErrorMessage = "Email not found or matched";
return View();
}
}
View:
<p>@ViewBag.ErrorMessage</p>
ViewModel
public class ForgotPasswordMV
{
[Display(Name = "Enter your email"), Required]
public string Email { get; set; }
}
But I read somewhere that I should put one property in my view model and set the error message on that property. I am confused now, how to achieve that and how to display the error in View then? And which one is the recommended/best practice?
But I read somewhere that I should put one property in my view model
and set the error message on that property. I am confused now, how to
achieve that and how to display the error in View then? And which one
is the recommended/best practice?
The best practice is to alter the ModelState
dictionary property of your controller like this:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Search(ForgotPasswordMV viewModel)
{
// ...
else
{
ModelState.AddModelError("Email", "Email not found or matched");
return View(viewModel);
}
}
Then in your view add the line below next to your email field;
@Html.ValidationMessageFor(m => m.Email)
But I read somewhere that I should put one property in my view model and set the error message on that property.
That's correct. You could add the error message to your view model:
public class ForgotPasswordMV
{
[Display(Name = "Enter your email"), Required]
public string Email { get; set; }
public string ErrorMessage { get; set; }
}
and then set this property on your view model and pass the view model to the view:
...
else
{
viewModel.ErrorMessage = "Email not found or matched";
return View(viewModel);
}
and finally in your strongly typed view use the property on your model:
@model ForgotPasswordMV
...
<p>@Model.ErrorMessage</p>
So basically here we are replacing the use of ViewBag
with a strongly typed view model.
As for me accepted anwser is not the best practice. We can handle all errors in annotations.
In our ViewModel we specify ErrorMessage
s for our properites.
public class UserLoginViewModel
{
[Required(ErrorMessage = "User name is required")]
[Display(Name = "User name")]
[StringLength(500, ErrorMessage = "User name is too short", MinimumLength = 3)]
public string Login { get; set; }
[Required(ErrorMessage = "Password is required")]
[Display(Name = "Password")]
public string Password { get; set; }
}
In our controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(UserLoginViewModel model)
{
if (!this.ModelState.IsValid)
{
return this.View();
}
...
}
And our view
@Html.ValidationMessageFor(model => model.Login)
@Html.EditorFor(model => model.Login)
@Html.ValidationMessageFor(model => model.Password)
@Html.EditorFor(model => model.Password)