knocte
knocte

Reputation: 17929

StateModel.AddModelError() but on a redirect?

So I have this logic in my LoginController to show an error to the user after a bad login attempt:

[<HandleError>]
type LoginController() =
    inherit Controller()

    [<HttpPost>]
    member this.Index
        (user: string, password: string) =
            if (WebDbAccess.IsValidUser user password) then
                this.Session.["user"] <- user
                RedirectResult("lobby") :> ActionResult
            else
                this.ModelState.AddModelError ("login", "The user or password is incorrect.")
                this.Index()

To show this error, I just add this in the view:

@Html.ValidationMessage("login")

Now, when the session expires, I would like to show the Login page but with an error message about the session expiration, however the ModelState gets ignored once I use the RedirectResult() method:

[<HandleError>]
type LobbyController() =
    inherit Controller()

    member this.Index() =
        if not (FsWeb.Global.IsUserLoggedIn(this.Session)) then
            this.ModelState.AddModelError ("session", "Invalid or expired session")
            RedirectResult("/") :> ActionResult
        else
            this.View("Chart", model) :> ActionResult

How could I send an error to a modelState of a redirect?

Upvotes: 2

Views: 419

Answers (3)

Honorable Chow
Honorable Chow

Reputation: 3153

Don't use TempData, that is basically session and will fail in a web farm that is configured with affinities. Redirect with a value in the RouteValueDictionary and check for it on the recieving end.

if you return RedirectToAction() one of the parameters is the route value dictionary. You can do a

return RedirectToAction("SomeView", "SomeController", new {
  SomeProperty = SomeValue,
  //more stuff if you want
});

If the action you redirected to has either a matching property on the model or a matching parameter in the controller method parameter list it will get populated as long as the name matches. This way you can pass the value and keep things stateless.

Upvotes: 1

Ehsan Sajjad
Ehsan Sajjad

Reputation: 62488

Use TempData like this:

if not (FsWeb.Global.IsUserLoggedIn(this.Session)) then
    this.ModelState.AddModelError ("session", "Invalid or expired session")
    TempData.["Error"] <- "Invalid or expired session"
    RedirectResult("/") :> ActionResult

In view of redirected action:

@{
    if(TempData["Error"] != null)
    {
        string Message = TempData["Error"] as string;
    }
}

Upvotes: 1

Andy T
Andy T

Reputation: 9881

Use TempData since it was designed for passing single-use data between controllers

Upvotes: 0

Related Questions