简体   繁体   中英

Display error message on the view from controller asp.net mvc 5

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(nameof(ForgotPasswordMV.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.

If anyone is looking for a simple fix and NOTHING PERMANENT than feel free to use this answer as this helped me out. DO NOT use this fix if you have to worry about security within your application.

In your controller:

TempData["Message"] = "This is my Error";

In your Error.cshtml file:

<h3><strong>@TempData["Message"]</strong></h3>

Result:

在此处输入图像描述

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)

I spent a lot of time to find the best solution for this too. It's very simple. In your Controller you can send an message like this.

        if (UnitCount >= 1000)
        {
            TempData["MsgChangeStatus"] = "Only 1000 units are allowed to modify at the same time!";
            return RedirectToAction("ChangeStatus");
        }

It's very important, after you use the TempData command you have to use an Return View() or return RedirectToAction() immediately, because these commands can send your message to the View.

In the View , you have to add the following part.

 @{
ViewBag.Title = "UnitState Change";
Layout = "~/Views/Shared/_Layout.cshtml";
var message = TempData["MsgChangeUS"] ?? string.Empty;
}


<script type="text/javascript">
var message = '@message';
if(message)
    alert(message);
</script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM