views:

156

answers:

3

I'm trying to do an invitation system, and if my solution is looking weird even to myself something gotta be wrong.

A user call an URL for an invitation

site.com/Account/Invitation/invitationGUID

public ActionResult Invitation(Guid invitationGUID)
{
    //Check for the existence of the invitation id
    if(true)
        return RedirectToAction("Account","Register")
    return View("InvalidInvite");
}

I need to pass the invitationGUID to the Register action

public ActionResult Register()
{
    //this is the registration form
    return View();
}

And I still need the invitationGUID at the post, to save this information

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Register(string email, string password, string confirmPassword,
                                 string firstName, string lastName, string cep)
{
    //register user
    return View();
}

What should I be doing to pass this information along?
I tried passing the data from Invitation -> Register

return RedirectToAction("Account","Register",invitationGUID)

Calling the Register view with the invitationGUID

return View("Register",invitationGUID);

And Using a hidden input at the Register View to get it back to Register with POST

<%= Html.Hidden("invitationGUID",(Guid)Model %>

It looks too interweaving to my taste, and I'm probably breaking a lot of good practices regarding view/controller isolation.
Should I just be replicating the Register code at Invitation?
I'm tending to just replicating the Register POST action at an Invitation POST right now.
Any idea what I should be doing differently?

+1  A: 
return RedirectToAction("Account", "Register", new { invitation = invitationGUID });

invitationGUID will be a part of querystring:

public ActionResult Register(Guid invitation)
{
    //this is the registration form
    return View();
}

Use Html.BeginForm() and it will be posted to itself:

<% using (Html.BeginForm()) { %>
...
<% } %>

invitationGUID is still in querystring:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Register(string email, string password, string confirmPassword,
    string firstName, string lastName, string cep, Guid invitation)
{
    //register user
    return View();
}
eu-ge-ne
+1  A: 

I don't think your breaking any best practices. Step back and think of what you want to do. You want a user with an open invitation to be able to register.

The user posting a registration must supply their inviteID. So, the Register action must be passed an inviteID. You have this.

If your expecting your users to use a browser as their client to register - they'll need to be given a form allowing them to register. You probably don't want them typing in their inviteIDs - so this should be filled out for them. Thus, your register view needs to be given an inviteID to property render the form. You have this.

The only thing I might suggest is skipping the whole Invitation action. Its not really needed. Instead just do the error checking in the Register action.

Its fine to pass required route data around when you're redirecting. If you can't resolve a route with out some data then how else would you do it? In this case, the route is dependent on the inviteId (since its needed to render the form). Pass it and be happy :)

So, in summary. What you're doing isn't that convoluted. Think of each step as if you knew nothing about the others. Also, I'd recommend having the users HTTP GET a route that looks like this:

site.com/Account/Register/invitationGUID

or

site.com/Account/Register?invite=invitationGUID

The choice between above is dependent on whether you want to explicitly have the invite id in the action's signature (and require it for the route to be resolved) or if you want to look at the QueryString from within the action. I might lean toward query string on this one since the invite is not the entity being altered here - its the gateway allowing a user entity to be created. Users with no inviteID should probably end up at this action as well.

TheDeeno
The logic for the invitation is so simple that ignoring the invitation action is probably the best bet. Thanks.
Tadeu Maia
A: 

If you don't want the invite IDs in the query string, you could use TempData. Here is a good write up on it. It's basically a one-shot session mechanism.

Jab
Didn't knew about the TempData, sounds good when you know there will be no AJAX request in the middle.
Tadeu Maia