views:

27

answers:

1

IN my asp.net-mvc project I have an AccountController that upon logging in sets a cookie with user preferences to the Request.Response and then does a RedirectToAction. Upon redirecting, the cookies are reset so I loose my settings.

The only solution I can come up with is adding the data from the cookie in the tempdata and then fetching it again later in the RedirectToAction's target action. This is off course a little backwards...

Is this a common practice? Is there no better solution? Should I handle my cookies differently?

A: 

Yes, using TempData for this is a common practice, and this is quite in line with how TempData is supposed to be used - passing temporary data between two action methods separated only by a client redirect.

Since the redirect from the login page could be to any other action method, you could implement the functionality to set cookies from TempData in your base controller. This would make any action method cookies-via-TempData compliant. This is a common scenario when displaying notifications on pages, where the notification (like the notifications on this site) would usually travel from TempData to ViewData to the view automatically.

bzlm
I was hoping for a better implementation. If I implement it this way I will loose all my decoupling..
borisCallens
@boris What decoupling, specifically?
bzlm
I extracted my user session handling out of my controllers so cookies don't screw up my testing and with half a mind of trying to get rid of the non-rest part of sessions if I can find a way. Now my controllers need to know the implementation of my session again (get the cookie from tempdata) and my session needs to know about my controller (put it in tempdata).
borisCallens
@boris Depends on what you want to test. In your specific example, I would assert that `controller.TempData["NewCookie"]` is set after an action method has executed. Then, in a different test, I would assert that `request.Cookies.Add()` is called (via mocking, for example) when an action method executes when TempData["NewCookie"] is set - or that the controller's `ISessionStateProvider` (your own mockable implementation) `.AddCookie()` is called. This certainly doesn't need to break testing or decoupling. If it did, any other use of `TempData` would as well, right?
bzlm
@bzlm. Thus far I have never had the user of TempData for exactly this reason. I admit that it's possible and I will use this, but I feel that it has a bit of a code smell to it :(
borisCallens
@boris I think I'd need to see some code (test or otherwise) to understand your dislike. I'm using this (with testing and mocking), and my nose is usually pretty sensitive. :)
bzlm
The fact that I'm creating cookies twice (once before and once after the redirect) is an initial hint to me
borisCallens
@boris But you're *not*. In your Login() method, you're just telling your session state provider to persist the user's credentials (or whatever). Then in your action method executer, your session state provider notices that there's a pending cookie, and sets it. The cookie will then piggy-back on the action result. Could you show a sample implementation where cookies would be created more than once? Also, did you look at the tests for the `AccountController` from the NerdDinner tutorial, which does to some extent test this scenario?
bzlm