Following on from my last post - Umbraco v7 Members' Area with Protected Content Without Coding? I went off to try and create a custom Members' Surface Controller in MVC so that I could add some functionality like the ability to send the user an email to authorise the address they've given and to collect some custom information (such as their name and whether they want to join a mailing list).
Due to the recent changes in the Members API and some confusing documentation I ended up with a bit of a spider mess of code, using some obsolete Umbraco classes. Umbraco's Sebastiaan Janssen came to my rescue in the Our Umbraco forums and building on what he suggested I'm posting it here as a starter for ten / tutorial to help others (it's not production ready - but it's not far off!). I'd appreciate any comments or suggestions for improvements.
Should probably note here - this is technically a step up from the last tutorial, you need a copy of Visual Studio (Express is fine) and some C# knowledge.
Download my source code from GitHub - you need to copy the files into the Controllers, Models and Views/Partials folders in your Umbraco solution and then include them in the solution - this needs to be an Umbraco solution in Visual Studio (follow the Nuget notes here and then install) - it's also useful to install JQuery Unobtrusive Validation.
Next add the following keys to your web.config to enable the client side validation - they go in the appsettings section - around line 49.
<add key="ClientValidationEnabled" value="true" /> <add key="UnobtrusiveJavaScriptEnabled" value="true" />
I've created members under the standard Member type and added some custom properties - go to Members / Member Types and select Member from the tree. Add properties like you would to a document type.
IMPORTANT Umbraco will set the alias for you - ensure it's lowercase (e.g. not firstName), this will cause you issues later otherwise.
We need templates for Login, Register and Validate. We need these to use our MVC controller rather than the macros like we did in Part 1 (if you're converting your solution from part 1 I'd recommend you delete the macros so they don't confuse somebody in the future). Instead of the insert macro tag we use an Action tag to tell Umbraco to call the relevant render form action method in the MVCMemberSurfaceController e.g. @Html.Action("MvcMemberLogin", "MvcMemberSurface") will match up to public ActionResult MvcMemberLoginGet(MvcMemberModel model) { ..}.
Note - we don't use the same action name for the Rendering of the form as we do for handling the post. If you're interested why read this: http://our.umbraco.org/forum/developers/api-questions/37547-SurfaceController-Form-Post-with-feedback
So we need
The new Document type and template called "Validate" will be used to service the link from the user's email - this will basically set the member to Approved allowing them to log in. Remember this sample code doesn't send the email for you - I'll leave that as a reader exercise - it outputs a link you can copy and paste to test it. I'd imagine you'd want this page excluded from any sitemaps etc.
There you are - a MVC Surface Controller for Website registrations and the members area. You should hopefully now be able to add any custom properties you'd like and control how you approve users.
If you included the login status macro in the footer then you've got the beginnings of a full members area solution.
This code isn't production ready - you'd need to improve the error handling (for example if properties don't exist) - there is also a desperate need to add some CSS to format the forms properly, show a better confirmation message when you've successfully registered and the solution is also lacking a member edit - at the very least you'd need people to be able to opt back out of the mailing list at a later date (we all hate spam right)! Please avoid spamming people without giving them a get out - that's the thing that makes me the most mad when I can't find the option on a website :)
If you spot any typos or issues with this tutorial please leave a comment below or email me steve@SiempreSolutions.co.uk
Name: Philoom
Date: 1442hrs 25/06/2014
Website:
Thanks Steve, this is an excellent article.
I just wish my local umbraco would recognise my controllers/models directory to keep this tidy!
I can only get this running from app_code. I am on 7.1.4.
Name: Tim Base
Date: 1357hrs 16/12/2014
Website: http://www.webhostwhat.com
This is a great idea. Are you planning to release a 'production ready' version?
Name: Steve
Date: 0859hrs 17/12/2014
I've not had the need to work on this area of Umbraco since this blog post I'm afraid so don't have anything to hand. There's not much left to do though I'd hope.
Steve
Name: Micha Somers
Date: 1414hrs 06/06/2016
Website: http://www.somers-ict.nl/
Hi Steve,
Just read your blog about “Umbraco v7 Members' Area with Protected Content - Part 2 - Writing a Custom MVC Members Surface Controller Tutorial”.
Interesting article and a good start for understanding what's needed to validate members.
One comment in order to get the article text in line with the current source code.
In the source code the action for validation is named MvcMemberValidate:
[HttpGet] [ActionName("MvcMemberValidate")] public ActionResult MvcMemberValidateGet(string email, string GUID) ...
For the template this would mean that instead of
Validate page with @Html.Action("MvcMemberValidateRenderForm", "MvcMemberSurface")
we should use
Validate page with @Html.Action("MvcMemberValidate", "MvcMemberSurface")
(or the other way around adjust the ActionName in the source code)
Best regards, Micha Somers
Name: Steve
Date: 1707hrs 12/04/2016
Good spot - I've changed the template code as the validate doesn't render a form - it just "reads" the get variable and valdiates the user.
Steve
Siempre Solutions Limited is a company registered in England and Wales with company number 09019307
Name: Steve
Date: 2129hrs 25/06/2014
Sounds strange - are you using Visual Studio and have you ensured all files are "included" in the project? I tend to like to work outside of VS when moving and copying files and this causes issues.
Good luck! Steve