views:

970

answers:

2

I'm trying to find a good way to handle the following scenario (I'm still kinda new to this):

A user can register through my site using an RPX/OpenId provider.

Step 1: The user authenticates through a provider. The provider returns a temporary token to one of my action methods.

Step 2: I use the token to grab the user's profile information and load a view which allows them to enter any missing required fields and optional fields.

I use 2 action methods in Step 2: One to handle the grabbing of information using the token. A second action which takes the authorization information and loads the missing/optional fields view.

I am passing the authorization info via TempData to the second action. The second action can handle validation so there's a chance I will need to hold on to the authorization object for more than just 1 request. I can't use the token to regenerate the authorization info because it's technically a one-use token, and it would be silly to regenerate the request since it is using network resources.

How could I persist the objects in my TempData for any subsequent requests to the same action, but remove the objects for any redirects? And since this may be a repeatable pattern in my application should I create a Filter to automatically handle this situation?

For example, I imagine a filter attribute which will merge TempData (if any) into ViewData - But how would I persist my data into future calls to the same action? Throw it into TempData again? And if I detect a redirect empty the TempData?

Thanks

A: 

I've had the same problem, but approached it a slightly different way - I've used a Forms Authentication method which works solely with OpenID... if my provider returns Authenticated, I do the following

                var fields = openid.Response.GetExtension(typeof(ClaimsResponse)) as ClaimsResponse;

                if (fields != null)
                {
                    TempData["Email"] = fields.Email;
                    TempData["Nickname"] = fields.Nickname;
                }

                FormsAuthentication.RedirectFromLoginPage(openid.Response.ClaimedIdentifier, false);

                break;

This means that I don't need to pass any kind of Authentication token around - after this code executes I know my user is authenticated.

Therefore, the action that this passes control to will simply copy the TempData fields, if populated, into ViewData and pass them onto the view.

Validation is handled after this - I don't care what comes back from OpenID (i.e. is it valid or not), I let the user edit this and then save, and then perform my validation.

Jamie
After fiddling around for a few hours I just decided to re-add the data to TempData. I found that you cannot use TempData.Add again because the collection already contains the key. So I created my own extension method to re-add the key.
DennyDotNet
+1  A: 

I ended up re-adding the data to TempData if necessary. Since TempData does not allow you to add duplicate keys I created my own helper method to remove and then re-add the key:

public static void AddNew(this TempDataDictionary tempData, string key, object obj)
{
 if ( tempData.ContainsKey( key ) ) tempData.Remove( key );

 tempData.Add( key, obj );
}
DennyDotNet