Copied to clipboard

Flag this post as spam?

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


  • Ole Kristian Losvik 22 posts 73 karma points
    Aug 23, 2016 @ 21:47
    Ole Kristian Losvik
    0

    Remote validation in surface controller (member registration controller)

    Based heavily on a project by Warren Buckley, I am trying to write a new membership controller in Umbraco 7.5.2.

    However, my first challenge is that I cannot get the remote validation to work.

    The error message states (sorry about the norwegian in between there):

    No url for remote validation could be found.
    
    Beskrivelse: Det oppstod et ubehandlet unntak under kjøring av gjeldende webforespørsel. Gå gjennom stakksporingen hvis du vil ha mer informasjon om feilen og hvor den oppstod i koden. 
    
    Unntaksdetaljer: System.InvalidOperationException: No url for remote validation could be found.
    

    This is my model:

     public class RegisterViewModel
    {
        [Required(ErrorMessage = "Please enter yourname")]
        public string Name { get; set; }
    
        [DisplayName("Email address")]
        [Required(ErrorMessage = "Please enter your email address")]
        [EmailAddress(ErrorMessage = "Please enter a valid email address")]
        [Remote("CheckEmailIsUsed", "MyMembersController", "MyMembers" ,ErrorMessage = "The email address has already been registered")]
        public string EmailAddress { get; set; }
    
        [UIHint("Password")]
        [Required(ErrorMessage = "Please enter your password")]
        public string Password { get; set; }
    
        [UIHint("Password")]
        [DisplayName("Confirm Password")]
        [Required(ErrorMessage = "Please enter your password")]
        [System.ComponentModel.DataAnnotations.Compare("Password", ErrorMessage = "Your passwords do not match")]
        public string ConfirmPassword { get; set; }
    }
    

    This is my controller:

      [PluginController("MyMembers")]
    public class MyMembersController : SurfaceController
    {
    (...)
    
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult HandleMemberRegister(RegisterViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return PartialView("Register", model);
            }
    
            var verifyEmailGuid = Guid.NewGuid();
    
            //Model valid let's create the member
            try
            {
                // Create new member
                var newMember = ApplicationContext.Services.MemberService.CreateMember(model.EmailAddress, model.EmailAddress, model.Name, "Member");
                ApplicationContext.Services.MemberService.Save(newMember);
    
                // Save the password
                ApplicationContext.Services.MemberService.SavePassword(newMember, model.Password);
    
                // Set hasVerifiedEmail to false
                newMember.SetValue("hasVerifiedEmail", false);
    
                // Set GUID to user for email verification
                newMember.SetValue("verifyEmailGuid", verifyEmailGuid.ToString());
    
                // Save the new member
                ApplicationContext.Services.MemberService.Save(newMember);
            }
            catch (Exception ex)
            {
                throw ex;
            }
    
            //Send out verification email, with GUID in it
            var emailToSend = new StringBuilder();
            emailToSend.AppendFormat("<p>Welcome to our site. Please click this link to verify your email.</p>");
            emailToSend.AppendFormat("<p><a href='test.com/{0}>test.com/{0}</a></p>", verifyEmailGuid);
    
            // Send password in email
            SendEmail(adminEmail, model.EmailAddress, "Verify your email", emailToSend.ToString());
    
            //Return  view...
            return PartialView("Register", new RegisterViewModel());
        }
    

    And the view:

     @inherits Umbraco.Web.Macros.PartialViewMacroPage
    
    
    @using System.Web.Mvc.Html
    @using ClientDependency.Core.Mvc
    @using Umbraco.Web
    @using losol.CMS.Controllers
    
    
    
    @{
        var regModel = new losol.CMS.Models.RegisterViewModel();
    
        Html.EnableClientValidation();
        Html.EnableUnobtrusiveJavaScript();
        Html.RequiresJs("/umbraco_client/ui/jquery.js");
        Html.RequiresJs("/umbraco_client/Application/JQuery/jquery.validate.min.js");
        Html.RequiresJs("/umbraco_client/Application/JQuery/jquery.validate.unobtrusive.min.js");
    
        var success = TempData["FormSuccess"] != null;
    }
    
    @*NOTE: This RenderJsHere code should be put on your main template page where the rest of your script tags are placed*@
    @Html.RenderJsHere()
    
    @if (success) 
    { 
        @* This message will show if RedirectOnSucces is set to false (default) *@
        <p>Registration succeeeded.</p>
    }
    else
    {
        using (Html.BeginUmbracoForm<MyMembersController>("HandleMemberRegister"))
        {
            <fieldset>
                <legend>Register Member</legend>
    
                @Html.ValidationSummary("registerModel", true)
    
                @Html.LabelFor(m => regModel.Name)
                @Html.TextBoxFor(m => regModel.Name)
                @Html.ValidationMessageFor(m => regModel.Name)
                <br />
    
                @Html.LabelFor(m => regModel.EmailAddress)
                @Html.TextBoxFor(m => regModel.EmailAddress)
                @Html.ValidationMessageFor(m => regModel.EmailAddress)
                <br />
    
                @Html.LabelFor(m => regModel.Password)
                @Html.PasswordFor(m => regModel.Password)
                @Html.ValidationMessageFor(m => regModel.Password)
                <br />
    
    
                <button>Register</button>
            </fieldset>
        }
    }
    
  • Ole Kristian Losvik 22 posts 73 karma points
    Aug 24, 2016 @ 06:11
    Ole Kristian Losvik
    0

    Sorry, and the remote validation...

            [PluginController("MyMembers")]
    public class MyMembersController : SurfaceController
    {
    (...)
        //REMOTE Validation
        /// <summary>
        /// Used with jQuery Validate to check when user registers that email address not already used
        /// </summary>
        /// <param name="emailAddress"></param>
        /// <returns></returns>
        [HttpPost]
        public JsonResult CheckEmailIsUsed(string emailAddress)
        {
            //Try and get member by email typed in
            var checkEmail = Members.GetByEmail(emailAddress);
    
            if (checkEmail != null)
            {
                return Json(String.Format("The email address '{0}' is already in use.", emailAddress), JsonRequestBehavior.AllowGet);
            }
    
            return Json(true, JsonRequestBehavior.AllowGet);
        }
    
  • David Brendel 792 posts 2970 karma points MVP 3x c-trib
    Aug 24, 2016 @ 06:40
    David Brendel
    0

    Hi Ole,

    I'm not familiar with the rmeote attribute but maybe it's because you referenced your controller with "MyMemberController" instead of "MyMember". Normally MVC appends the "Controller" part automatically.

    If that happens it tries to find the method using MyMeber/MyMemberControllerController/CheckEmailIsUsed and thus can't find the controller method.

    Hope that helps.

    Regards David

Please Sign in or register to post replies

Write your reply to:

Draft