Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Steve Morgan 1349 posts 4459 karma points c-trib
    Jun 05, 2014 @ 16:14
    Steve Morgan
    1

    Members via a SurfaceController - using custom properties

    HI,

    Using Umbraco 7.1.4 I've created myself a SurfaceController to test out the creation of new members and logging in. I've struggling a bit with picking through the various bits of documentation. It's hard to know what is obsolete as I've tried using what I think was the latest approach using the MemberShip Helper stuff and it didn't seem to work. 

    I've found using Members, I can create members and set a custom property "validateguid" I've added to the "Member" member type using:

     regModel.Name = model.Username;
                regModel.Password = model.Password;
                regModel.Email = model.Email;
                // Can set via index (messy)
                // myModel.MemberProperties[0].Value = "Set from code";
                // System.Diagnostics.Debug.WriteLine( myModel.MemberProperties[0].Value);
                // Better - via alias with a lambda?
                regModel.MemberProperties.Find(x => x.Alias == "validateguid").Value = newUserGuid;
    
    
                // Register (create) the member
                var member = Members.RegisterMember(regModel, out status, true);
                // set them to NOT be approved so we can implement a validate GUID email thang.
                member.IsApproved = false;

    I want the member NOT to be approved automatically as I'm going to implement an email check (hence the GUID). 

    I also add them to a group using:

    System.Web.Security.Roles.AddUserToRole(member.UserName, "WebsiteRegistrations"); 

    This all works but I can't help but feeling like I've hacked a few bits together. My question is wether my approach is correct? 

    In my next bit of code I try to validate the user's email - so I need to look up their email address and the validate GUID. I actually tried to do this via Members.GetbyUsername initially and that failed - perhaps because of the new email as username?

    The problem here is that I can't set the IsApproved attribute now - the Member seems to be read only. Am I missing something?

      // weird - Members.GetbyUsername(username) didn't work?!
                var member = Members.GetByEmail(email);
                string testGUID = "";
                testGUID = member.GetPropertyValue("validateguid").ToString().ToLower();
                if (testGUID == GUID)
                {
                    // This doesn't work!
                   // member.IsApproved = true;
  • Sebastiaan Janssen 5060 posts 15522 karma points MVP admin hq
    Jun 05, 2014 @ 17:23
    Sebastiaan Janssen
    105

    Ouch, looks like you're struggling, we should update documentation huh..!

    Try and play with this:

    using System.Web.Mvc;
    using Umbraco.Course.Models;
    using Umbraco.Web.Mvc;
    
    namespace Umbraco.Course.Controllers
    {
        public class RegisterController : SurfaceController
        {
            public ActionResult Register(RegisterModel model)
            {
                if (!ModelState.IsValid)
                    return CurrentUmbracoPage();
    
                var memberService = Services.MemberService;
                if (memberService.GetByEmail(model.Email) != null)
                {
                    ModelState.AddModelError("", "Member already exists. Aborting!");
                    return CurrentUmbracoPage();
                }
    
                // IntranetUser is the member type
                var member = memberService.CreateMember(model.Email, model.Email, model.Name, "IntranetUser");
    
                // Custom properties can easily be set, use this for your validation guid
                member.SetValue("biography", model.Biography);
                member.SetValue("avatar", model.Avatar);
    
                // Not yet allowed to log in!
                member.IsApproved = false;
    
                // Don't forget to save all these things
                memberService.Save(member);
    
                // save their password
                memberService.SavePassword(member, model.Password);
    
                // "regular" is the member group
                memberService.AssignRole(member.Id, "regular");
    
                // Redirect somewhere 
                return Redirect("/");
            }
        }
    }
    

    The model looks like this:

    using System.ComponentModel.DataAnnotations;
    using System.Web;
    
        namespace Umbraco.Course.Models
        {
            public class RegisterModel 
            {
    
                [Required]
                public string Name { get; set; }
    
                [Required]
                [EmailAddress]
                public string Email { get; set; }
    
                [Required]
                public string Password { get; set; }
    
                public string Biography { get; set; }
    
                public HttpPostedFileBase Avatar { get; set; }
    
            }
        }
    

    I can't say I've tried to set Approved to false but that should be possible somehow!

  • Osman Coskun 170 posts 404 karma points
    Feb 08, 2021 @ 09:59
    Osman Coskun
    0

    Hi Sebastiaan,

    I've used similar code on Umbraco 7.7.7 net framework 4.5. It was working.

    Now i need to adapt the same member registration surface controller to another site (Umbraco 7.15.6 net framework 4.7.2). Everything's working except

     var memberService = Services.MemberService;
     if (memberService.GetByEmail(model.Email) != null)
     {
         ModelState.AddModelError("", "Member already exists. Aborting!");
         return CurrentUmbracoPage();
     }
    

    It fails to check if there's a member registered with the email address.

    Do you have any idea?

  • Sebastiaan Janssen 5060 posts 15522 karma points MVP admin hq
    Jun 05, 2014 @ 17:26
    Sebastiaan Janssen
    1

    Oh and in your validation of the GUID, it doesn't work because you likely forgot to Save the member:

     if (testGUID == GUID)
     {
         member.IsApproved = true;
         Services.MemberService.Save(member);
     }
    
  • Steve Morgan 1349 posts 4459 karma points c-trib
    Jun 05, 2014 @ 18:20
    Steve Morgan
    0

    Yup - that cleared the fog - I think I got in a bit of mess there!

    I'll post my full code when I've got it working for anyone trying to do similar - I spotted a couple of Our Umbraco forum posts without a full solution so I don't think I was alone here! 

     

    Thanks Sebastian!

  • Steve Morgan 1349 posts 4459 karma points c-trib
    Jun 06, 2014 @ 19:57
    Steve Morgan
    0

    For checking the user's password on login do I really need to do this or is there a method I've missed?

                // Do I really need to hash the password myself - surely there is a helper method to validate user?
                HMACSHA1 hash = new HMACSHA1();
                hash.Key = Encoding.Unicode.GetBytes(model.Password);
                string hashedPassword = Convert.ToBase64String(hash.ComputeHash(Encoding.Unicode.GetBytes(model.Password)));
                if (member.RawPasswordValue == hashedPassword)
                {
                    FormsAuthentication.SetAuthCookie(model.Email, model.RememberMe);
                    return RedirectToCurrentUmbracoPage();
                }
                else 
                {
                    TempData["Status"] = "Invalid username or password";
                    return RedirectToCurrentUmbracoPage();
                }
  • Steve Morgan 1349 posts 4459 karma points c-trib
    Jun 06, 2014 @ 19:58
    Steve Morgan
    0

    I was looking for something like Membership.ValidateUser(m.Email, model.Password)

  • Sebastiaan Janssen 5060 posts 15522 karma points MVP admin hq
    Jun 07, 2014 @ 11:59
    Sebastiaan Janssen
    0

    Much easier :-)

    Just log them in, the Login method returns a boolean:

    if (Members.Login(model.Username, model.Password))
    {
       //Do something
    }
    
  • Steve Morgan 1349 posts 4459 karma points c-trib
    Jun 09, 2014 @ 19:12
    Steve Morgan
    2

    Doh! Not sure how I missed that.

    I've blogged my approach - and put my code on github. Would be interested to hear how other people get on with this. 

    http://siempresolutions.co.uk/blog/Umbraco_Members_Protected_Area_of_Website_Part_2_Using_MVCMembers_Controller

  • Charles Afford 1163 posts 1709 karma points
    Jun 09, 2014 @ 19:20
    Charles Afford
    0

    Hi I have been using the .net membership provider rather than Umbraco inbuilt methods.

    Steve re:For checking the user's password on login do I really need to do this or is there a method I've missed?

    You can use the inbuilt .net methods.  The method you need is VallidateUser() 

    what is the alias of the property you are trying to set on your member.  If it is lowercase change it to upper case and give that a try?

    I might be missing the orginal problem.

    Charlie :)

  • Steve Morgan 1349 posts 4459 karma points c-trib
    Jun 09, 2014 @ 19:45
    Steve Morgan
    0

    Hi Charles - I did initially start mixing the bits of the core .NET code and it started becoming a mess! 

    Sebastiaan's approach worked perfectly (using members) - if you're interested download the code from Git Hub - I hope it's all done in the Umbraco way.

    Cheers

    Steve 

  • Charles Afford 1163 posts 1709 karma points
    Jun 09, 2014 @ 19:51
    Charles Afford
    0

    Glad you got it working :)

  • Veronica Burd 76 posts 201 karma points
    Jun 18, 2014 @ 11:58
    Veronica Burd
    0

    Hi Steve,

    Just wanted to thank you for posting your code on GitHub.  Really helped me get my login/registrations pages up and running.

    Regards

    Ver


  • Steve Morgan 1349 posts 4459 karma points c-trib
    Jun 18, 2014 @ 14:31
    Steve Morgan
    0

    You're very welcome! 

    Cheers

    Steve

  • Chen 39 posts 68 karma points
    Jul 25, 2014 @ 15:43
    Chen
    0

    Hi Steve,

    Great work! Does your solution work directly with the built-in Umbraco members section or do I need to add them to a separate table in the database? I'm new to MVC just wondering if your (github) MvcMemberViewModel will interact directly with the built-in RegisterModel, ProfileModel, etc.

    Cheers!

    Chen

  • Steve Morgan 1349 posts 4459 karma points c-trib
    Jul 25, 2014 @ 16:39
    Steve Morgan
    0

    It works directly (if I'm understanding what you're asking!) with the members section. There are no custom tables but (as noted at the start of section 2.1 in my blog post ) you need to create some "generic properties" to match the pieces of information we create in addition to the standard ones. In Umbraco you can add properties easily in Members > Member Types > [your type] > Generic Properties tab.  

     

    HTH.

  • Chen 39 posts 68 karma points
    Jul 28, 2014 @ 12:25
    Chen
    0

    Hi Steve,

    I've followed your github code example and created the viewmodel,controller, and corresponding views. However, when I tried to submit the register form, I get a null reference.

    not sure I'm doing wrong there, will you be able to help please? Thank you in advance!

    Chen 

  • Charles Afford 1163 posts 1709 karma points
    Jul 28, 2014 @ 19:51
    Charles Afford
    0

    Hi Chen,

    I can see what the problem is can you post what you code you have for CreateMember?

    Charlie

  • Charles Afford 1163 posts 1709 karma points
    Jul 28, 2014 @ 20:09
    Charles Afford
    0

    Hi Chen your error is this line:

    var member = memberService.CreateMember(model.Email, model.Email, model.FirstName + " " + model.LastName, "Member");

    The 4th parameter "Member" is the UserType i believe and because that is not in your user types you are getting a null exception.

    To solve this:

    Go to the Users tab in umbraco

    Right click on UserTypes

    Click create

    Enter Member

    And your could should work.

    Charlie :)

  • Chen 39 posts 68 karma points
    Jul 29, 2014 @ 10:07
    Chen
    0

    Hi Charlie,

    Thank you for the quick reply. Actually I do have "Member" defined as a MemberType (see attachment). Not sure what else is wrong tho :(

    Thanks,

    Chen

  • Sebastiaan Janssen 5060 posts 15522 karma points MVP admin hq
    Jul 29, 2014 @ 10:09
    Sebastiaan Janssen
    0

    You need to figure out which property is null and why. Also, in order to not keep us guessing at what your problem could be, post some code.

  • Chen 39 posts 68 karma points
    Jul 29, 2014 @ 10:42
    Chen
    0

    Hi Sebatiaan/Charlie,

    Sorry didn't provide any details earlier. It's the same code from Steve's github repo, I've not modified it yet. Figured out what it is though, just as you suggested one of the property was empty. I added the following code and the problem went away.

    if (!this.ModelState.IsValid)
                {
                    return this.CurrentUmbracoPage();
                }

    Thank you both!

    Chen

  • Charles Afford 1163 posts 1709 karma points
    Jul 29, 2014 @ 19:46
    Charles Afford
    0

    No worries, must of been something you were passing in as null. Glad you fixed it. Could you maked it as complete please :)

  • Josh Olson 79 posts 207 karma points
    Sep 10, 2014 @ 14:52
    Josh Olson
    0

    I just made use of this and your blog post to get my membership system into gear! Thanks so much. #HFYR

  • Steve Morgan 1349 posts 4459 karma points c-trib
    Sep 10, 2014 @ 15:07
    Steve Morgan
    0

    You're very welcome - thanks to those that helped especially Sebastiaan Janssen! 

  • Sam Pearson 36 posts 89 karma points
    Mar 16, 2015 @ 11:48
    Sam Pearson
    0

    Hi all,

    I've been basing an Umbraco 7.2 membership system on this, great work Steve btw....got me out of trouble :-)

    One thing to note though; on your walkthrough site here it says you need to "Validate page with @Html.Action("MvcMemberValidateRenderForm", "MvcMemberSurface")". I don't know if this was your original code and it changed or it was a typo in your write-up, but there is no ActionResult called MvcMemberValidateRenderForm in your MvcMemberSurfaceController.cs on GitHub.

    For the benefit of others (mainly MVC newbs) using your build, you need to call the Action like this; @Html.Action("MvcMemberValidate", "MvcMemberSurface") . No need to create a custom  MvcMemberValidateRenderForm ActionResult! (Like I did haha).

    Cheers for all your work on this Steve!

    -Sam

  • Steve Morgan 1349 posts 4459 karma points c-trib
    Mar 16, 2015 @ 12:10
    Steve Morgan
    0

    Sam quite possibly a last minute rename ... I'll have a look at it and correct it when I get a chance. Thanks for the spot!

  • Robert J. Bullock 386 posts 405 karma points
    May 06, 2015 @ 22:39
    Robert J. Bullock
    0

    Fantastic! Just what I was looking for. Has anyone done anything similar with user profile page?

  • Rune Antonsen 29 posts 145 karma points
    May 10, 2017 @ 13:22
    Rune Antonsen
    0

    Just a little heads up from me:

    Remember to not go into the Dynamic trap! Always use Umbraco.Typed*

    I used Umbraco.Media to get an url for an image while using SetValue on a IMember. It all compiled nicely, but failed when running since the SetValue method wasn't found due to the entire thing had been turned into dynamic crap.

    From the slack channel:

    sniffdk:
    [2:46 PM] I think its simply that when you retrieve a media item as a 
              dynamic', everything turns dynamic
    [2:47 PM] and the RuntimeBinder tries to find a suitable method with a 
              suitable amount of parameters
    [2:47 PM] and it fails
    
Please Sign in or register to post replies

Write your reply to:

Draft