0
votes

What would you use in place of TempData in the following code snippet to achieve the same desired results - redirect in the case of an invalid ModelState and pass login errors?

public ActionResult Welcome(string returnUrl, int accountTypeId = 0)
    {
        //this is logic from the original login page. not sure if this would ever occur. we may be able to remove this.
        if (string.IsNullOrEmpty(returnUrl) == false && returnUrl.Contains("?route="))
        {
            var split = returnUrl.Split(new[] {"?route="}, StringSplitOptions.None);
            var route = Server.UrlDecode(split[1]);
            returnUrl = split[0] + "#" + route;
        }

        object model;
        if (TempData.TryGetValue("LogOnModel", out model) == false)
        {
            model = new LogOnModel
            {
                ReturnUrl = returnUrl,
                AccountTypeId = accountTypeId
            };
        }

        object errors;
        if (TempData.TryGetValue("Errors", out errors))
        {
            ModelState.Merge(errors as ModelStateDictionary);
        }

        return View(model);
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Welcome(LogOnModel model)
    {
        Func<ActionResult> invalid = () =>
        {
            TempData.Add("Errors", ModelState);
            TempData.Add("LogOnModel", model);
            return RedirectToAction("Welcome");
        };

        if (ModelState.IsValid == false)
        {
            return invalid();
        }

As it stands now, the code creates an error if the user clicks the back button and attempts to log in a second time. The error message, "An item with the same key has already been entered" I'm trying to avoid this error. I tried using ViewData in the place of TempData, but that broke my login error message in the case of someone entering the wrong password. I'm new at MVC, so I'm seeking input from others.

1

1 Answers

0
votes

It doesn't look like you're doing any ajax so you don't need to redirect on an error in this case. When the model state is invalid you have a collection populated for you called model state errors. You just need to return the welcome view again and add an @Html.ValidationSummary to the welcome page cshtml.

Html.ValidationSummary reads the model state errors and then determines if it needs to show an error box or not. Here's what I would do.

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Welcome(LogOnModel model)
{
    if (ModelState.IsValid == false)
    {//We have model state errors populated here for us
        return View(model);
    }
    //Do Work
}