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>
}
}
[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);
}
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.
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):
This is my model:
This is my controller:
And the view:
Sorry, and the remote validation...
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
is working on a reply...