views:

59

answers:

2

Hello,

Here's the definition of the LogOn post action method

[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
  // more inside
}

I've a basic question. Does the framework supplies the string returnUrl? or I do have that responsibility?

Thanks for helping.

+2  A: 

It depends on who is calling this method and whether this parameter is supplied in the POST request. For example if the user tries to access a controller action decorated with the [Autorize] attribute and he is not authenticated the framework will automatically redirect to the LogOn action (the one that renders the form, not the one with [HttpPost]) and supply the returnUrl parameter. Then you could have a hidden field in the logon form to persist its value so that when the user enters his credentials and submits the form to the LogOn action, in case of successful login, he is redirected to the initially requested page.

Darin Dimitrov
@Darin Dimitrov: I see. So the returnUrl is provided by the framework only when the redirection to LogOn is a result of forcing a user to supply credentials. How about when the user just clicks an ActionLink to voluntary LogOn? should I add new { returnUrl = "whatever_action_displayed_the_View" }?
Richard77
Yes, correct, in case where the user clicks directly on the `LogOn` link, no returnUrl will be supplied. You could supply it either by `new { returnUrl = "whatever_action_displayed_the_View" }` or simply in your `LogOn` action check if there's a returnUrl defined and if not redirect to the default action if login succeeds.
Darin Dimitrov
Just one last thing. A view can be displayed by any action. So how do I get the action that displayed the view from the view? new { returnUrl = <%: ??? %>}
Richard77
By reading it from the `RouteData`: `new { returnUrl = RouteData.Values["action"] }`
Darin Dimitrov
Thanks @Darin: It took me more time to make it work because I was struggling with the Redirect() action result.
Richard77
+1  A: 

Well, as I do sometimes, I answer my own question to add more information on how I resolved a problem after getting other people answer (In this case, Darin Dimitrov).

Briefly, @Darin Dimitrov explained to me that I need to supply the returnUrl if the redirection to LogOn action method is not the result of forcing a user to supply credentials (when the method is trying to access is decorated with a [Authorize] attribute). I need to use new { returnUrl = RouteData.Values["action"] } to supply that value.

Here are some problems:

  1. Intellisense did not recognize `RouteData.Values["action"], I needed to usePage.RouteData.Values["action"]`

  2. I kept getting the following error: "the resource cannot be found", url showing http://example.com/Account/Whatever_action_is_in_the_returnUrl. That make sense because I did only supply the action string.

  3. I did this

    new
    {
        returnUrl = Page.RouteData.Values["controller"] + "/" + Page.RouteData.Values["action"]
    } 
    

    But I got the some error:"the resource cannot be found", url showing http://example.com/Account/myController/myAction. The account was still in the Url, causing the same error.

  4. Finally, I added an other slash in the beginning then it worked.

    new
    {
        returnUrl = "/" + Page.RouteData.Values["controller"] + "/" + Page.RouteData.Values["action"]
    } 
    

It looks like it's important to know many faces of the the redirections business. So far, I've mostly used RedirectToAction().

Thanks @Darin Dimitrov.

Richard77
@Richard77, always use helpers when dealing with urls: `new { returnUrl = Url.Action(Page.RouteData.Values["action"], Page.RouteData.Values["controller"]) }`, it's much cleaner and avoids you hardcoding your urls. Also I didn't understand what's with the `Page.` and Intellisense thing. You don't need this parameter. `System.Web.Mvc.ViewPage` already has a property called `RouteData` so all you have to do is `<%= this.RouteData.Values["xxx"] %>`. The fact that VS Intellisense doesn't recognize something doesn't mean at all that this something is wrong.
Darin Dimitrov
@Darin Dimitrov: I was just savoring my findings. I didn't meant to use "/" in a real scenario. But, as I said, I believe it's important for me and other new comers to read about redirecting businesses as they bear many faces. For instance, you just use Url.Action(). So far, I've used RedirectToAction, which's worked so well for me. Thanks again.
Richard77