The custom remote validation is the method IsUID_Available.
I use the new remote attribute to decorate the create view model.
[MetadataType(typeof(UserModelMD))]
public class UserModelCreate : UserModel {
public class UserModelMD {
[Required]
[StringLength(6, MinimumLength = 3)]
[Remote("IsUID_Available", "Validation")]
[RegularExpression(@"(\S)+", ErrorMessage = "White space is not allowed")]
public string UserName { get; set; }
}
}
I have one more question..or more like a problem..
I go the whole "validation-call" working..so the ajax runs just fine and such, but I cant get the value of the, in this case textbox, to get sent as a parameter to the C# vakidation function..its just null each time..
Here is my code:
The Model:
public class BlogPostModel
{
[Required]
public Int64 ID { get; set; }
[Required]
[Remote("IsDateTimeFormat", "Validation")]
public DateTime Published { get; set; }
[Remote("IsDateTimeFormat", "Validation")]
public DateTime Updated { get; set; }
[Required]
[DataType(DataType.Text)]
public string Title { get; set; }
[Required]
[DataType(DataType.MultilineText)]
public string HtmlContent { get; set; }
protected bool ValidateDateTime(object value)
{
if (((string)value).Length > 1)
return false;
return true;
}
}
The Validator-class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.UI;
namespace MvcApplication4.Controllers
{
[OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
public class ValidationController : Controller
{
public JsonResult IsDateTimeFormat(string datetime)
{
DateTime newdatetime;
bool success = DateTime.TryParse(datetime,out newdatetime);
if (success)
return Json(true,JsonRequestBehavior.AllowGet);
else
return Json("The Date format you enterd is invalid!", JsonRequestBehavior.AllowGet);
}
}
}
try regularexpression validation with a date time format have you ever tried that ??
Yeah..for just validating the format of a string I could use regex, but since Im trying to do this for learning purposes..I whould realy like to learn how to do a custom validation(remote validation)..another problem in this case is that I also whould like
to validate if the entered time is before or after or equals the current time..(Published <= DateTime.Now)..which as far as I know whould be hard to accomplish with regex..if not even impossible in this case..
I wrote the below attribute for validation the usernames on registratioon process. you could get an idea from that about how you implement a custom validation;
here is the code;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using Application1.Models;
namespace Application1.Attributes
{
/// <summary>
/// Specifies that a data field value is not a restricted username of the system !
/// </summary>
[Description("Specifies that a data field value is not a restricted username of the system !")]
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public sealed class ValidateAuthorNameAttribute : ValidationAttribute
{
RestrictedUserNameRepository repo = new RestrictedUserNameRepository();
private const string _defaultErrorMessage = "'{0}' is a restricted username and it cannot be chosen. Please try another username !";
private readonly int _defaultInteger = 0;
public ValidateAuthorNameAttribute()
: base(_defaultErrorMessage)
{
}
public override string FormatErrorMessage(string name) {
return String.Format(CultureInfo.CurrentCulture, ErrorMessageString, name);
}
public override bool IsValid(object value)
{
string valueAsString = value as string;
var query = repo.GetAllActive(valueAsString);
int restrictedUserNameCount = 0;
if(query != null)
restrictedUserNameCount = query.Count();
return (valueAsString != null && restrictedUserNameCount == _defaultInteger);
}
}
}
here is the account model ;
[PropertiesMustMatch("Password", "ConfirmPassword", ErrorMessage = "The password and confirmation password do not match.")]
public class RegisterModel
{
[Required]
//As you see here, I am using it like a new validation control...
[ValidateAuthorName]
[DisplayName("User name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
[DisplayName("Email address")]
public string Email { get; set; }
[Required]
[ValidatePasswordLength]
[DataType(DataType.Password)]
[DisplayName("Password")]
public string Password { get; set; }
[Required]
[DataType(DataType.Password)]
[DisplayName("Confirm password")]
public string ConfirmPassword { get; set; }
}
then you will be all set. it works fine but if you would like to use it as client validation, you need a further work to do.
Thanks man :)..even if I think I actually will try to use the Remote-validation attribute, since its kind of nice and also gives me a client-side validation at the same time :)..
I did get it all working now...I were just beeing plain stuid and didnt check the QueryString thats sent with the request of the ajax-call..anyway...I do get the princip now of the RemoteValidation attribute, but one thing I cant figure out is...what if
I have two properties/fields that uses the same validation function..then the parameter-name sent to the function whould differ..so is there anyway to solve that?...
I could in this case just set two parameters one for the Published property and then one for the Updated property, but that whouldnt be such a nice solution in my opinion..so what Im asking for is a more generall solution..so I simply can apply this attribute
to any field..without haveing to modify the validation function..
If you want to compare two properties, look at the Compare attribute.
Build a new MVC 3 project and look at the account controller/model for reqistering a new user. The confirmPassword much match.
If you want to compare two properties, look at the Compare attribute. Build
a new MVC 3 project and look at the account controller/model for reqistering a new user. The confirmPassword much match.
Well..I dont want to compare two properties..I want two properties to use the same Remote validation..
for instance like this:
Model:
public class BlogPostModel
{
[Required]
public Int64 ID { get; set; }
[Required]
[Remote("IsDateTimeFormat", "Validation", Fields = "Published")]
public DateTime Published { get; set; }
[Remote("IsDateTimeFormat", "Validation", Fields = "Updated")]
public DateTime Updated { get; set; }
[Required]
[DataType(DataType.Text)]
public string Title { get; set; }
[Required]
[DataType(DataType.MultilineText)]
public string HtmlContent { get; set; }
protected bool ValidateDateTime(object value)
{
if (((string)value).Length > 1)
return false;
return true;
}
}
The view:
[OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
public class ValidationController : Controller
{
public JsonResult IsDateTimeFormat(string Published)
{
DateTime newdatetime;
bool success = DateTime.TryParse(Published, out newdatetime);
if (success)
return Json(true,JsonRequestBehavior.AllowGet);
else
return Json("The Date format you enterd is invalid!", JsonRequestBehavior.AllowGet);
}
}
In this case the called validation function only takes a parameter namned "Published", which meens that once Im validating the field with the name "Published" the validation will go through like it should and the parameter Published will get the value of the
field Published.
But if the field Updated tries to call this function then the parameter Published wont get set, since the only parameter that gets set/sent by the request is a parameter namned Updated..so is there any way to make this more generall?..so the parameters name
wont matter..
Another thing I also found out is that for some reason it seems that once Im entering something in the Published field(the textbox of the site) and then blur it(unfocus it) the validation function gets called for this field and all the other fields that
has this validation on them aswell..
Kind a hard to explain..but if you didnt get it at the above description of the problem then let me know and I will try to explain it abit more in details :)
ricka6
All-Star
15070 Points
2272 Posts
Microsoft
Moderator
Re: CustomValidation?
Nov 23, 2010 10:36 PM|LINK
The custom remote validation is the method IsUID_Available.
I use the new remote attribute to decorate the create view model.
[MetadataType(typeof(UserModelMD))] public class UserModelCreate : UserModel { public class UserModelMD { [Required] [StringLength(6, MinimumLength = 3)] [Remote("IsUID_Available", "Validation")] [RegularExpression(@"(\S)+", ErrorMessage = "White space is not allowed")] public string UserName { get; set; } } }ricka6
All-Star
15070 Points
2272 Posts
Microsoft
Moderator
Re: CustomValidation?
Nov 24, 2010 04:24 AM|LINK
I updated the sample (simplified it).
http://code.msdn.microsoft.com/aspnetmvcsamples/Release/ProjectReleases.aspx?ReleaseId=5114
Inx
Member
53 Points
217 Posts
Re: CustomValidation?
Nov 25, 2010 09:48 PM|LINK
Thanks alot, the sample helped me alot
!
I have one more question..or more like a problem..
I go the whole "validation-call" working..so the ajax runs just fine and such, but I cant get the value of the, in this case textbox, to get sent as a parameter to the C# vakidation function..its just null each time..
Here is my code:
The Model:
public class BlogPostModel { [Required] public Int64 ID { get; set; } [Required] [Remote("IsDateTimeFormat", "Validation")] public DateTime Published { get; set; } [Remote("IsDateTimeFormat", "Validation")] public DateTime Updated { get; set; } [Required] [DataType(DataType.Text)] public string Title { get; set; } [Required] [DataType(DataType.MultilineText)] public string HtmlContent { get; set; } protected bool ValidateDateTime(object value) { if (((string)value).Length > 1) return false; return true; } }The Validator-class:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.UI; namespace MvcApplication4.Controllers { [OutputCache(Location = OutputCacheLocation.None, NoStore = true)] public class ValidationController : Controller { public JsonResult IsDateTimeFormat(string datetime) { DateTime newdatetime; bool success = DateTime.TryParse(datetime,out newdatetime); if (success) return Json(true,JsonRequestBehavior.AllowGet); else return Json("The Date format you enterd is invalid!", JsonRequestBehavior.AllowGet); } } }and the View:
@model MvcApplication4.Models.BlogPostModel @{ View.Title = "Edit"; Layout = "~/Views/Shared/_Layout.cshtml"; } <h2>Edit</h2> @using (Html.BeginForm()) { @Html.ValidationSummary(true) <fieldset> <legend>Fields</legend> @Html.HiddenFor(model => model.ID) <div class="editor-label"> @Html.LabelFor(model => model.Published) </div> <div class="editor-field"> @Html.EditorFor(model => model.Published) @Html.ValidationMessageFor(model => model.Published) </div> <div class="editor-label"> @Html.LabelFor(model => model.Updated) </div> <div class="editor-field"> @Html.EditorFor(model => model.Updated) @Html.ValidationMessageFor(model => model.Updated) </div> <div class="editor-label"> @Html.LabelFor(model => model.Title) </div> <div class="editor-field"> @Html.EditorFor(model => model.Title) @Html.ValidationMessageFor(model => model.Title) </div> <div class="editor-label"> @Html.LabelFor(model => model.HtmlContent) </div> <div class="editor-field"> @Html.EditorFor(model => model.HtmlContent) @Html.ValidationMessageFor(model => model.HtmlContent) </div> <p> <input type="submit" value="Save" /> </p> </fieldset> } <div> @Html.ActionLink("Back to List", "Index") </div>I might just aswell post the Web.config aswell and then you have all you need for helping me I guess :)..so here it comes:
<?xml version="1.0"?> <!-- For more information on how to configure your ASP.NET application, please visit http://go.microsoft.com/fwlink/?LinkId=152368 --> <configuration> <appSettings> <add key="ClientValidationEnabled" value="true"/> <add key="UnobtrusiveJavaScriptEnabled" value="true"/> </appSettings> <system.web> <compilation debug="true" targetFramework="4.0"> <assemblies> <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> </assemblies> </compilation> <authentication mode="Forms"> <forms loginUrl="~/Account/LogOn" timeout="2880" /> </authentication> <pages> <namespaces> <add namespace="System.Web.Helpers" /> <add namespace="System.Web.Mvc" /> <add namespace="System.Web.Mvc.Ajax" /> <add namespace="System.Web.Mvc.Html" /> <add namespace="System.Web.Routing" /> <add namespace="System.Web.WebPages"/> </namespaces> </pages> </system.web> <system.webServer> <validation validateIntegratedModeConfiguration="false"/> <modules runAllManagedModulesForAllRequests="true"/> </system.webServer> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration>What am I doing wrong?
tugberk_ugur...
Participant
1944 Points
1344 Posts
MVP
Re: CustomValidation?
Nov 26, 2010 06:42 AM|LINK
try regularexpression validation with a date time format
have you ever tried that ??
tweets as @tourismgeek
Inx
Member
53 Points
217 Posts
Re: CustomValidation?
Nov 26, 2010 07:29 AM|LINK
Yeah..for just validating the format of a string I could use regex, but since Im trying to do this for learning purposes..I whould realy like to learn how to do a custom validation(remote validation)..another problem in this case is that I also whould like to validate if the entered time is before or after or equals the current time..(Published <= DateTime.Now)..which as far as I know whould be hard to accomplish with regex..if not even impossible in this case..
but thanks for trying to help
tugberk_ugur...
Participant
1944 Points
1344 Posts
MVP
Re: CustomValidation?
Nov 26, 2010 07:59 AM|LINK
hmm. then I could give you some example of mine.
I wrote the below attribute for validation the usernames on registratioon process. you could get an idea from that about how you implement a custom validation;
here is the code;
using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Globalization; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Security; using Application1.Models; namespace Application1.Attributes { /// <summary> /// Specifies that a data field value is not a restricted username of the system ! /// </summary> [Description("Specifies that a data field value is not a restricted username of the system !")] [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public sealed class ValidateAuthorNameAttribute : ValidationAttribute { RestrictedUserNameRepository repo = new RestrictedUserNameRepository(); private const string _defaultErrorMessage = "'{0}' is a restricted username and it cannot be chosen. Please try another username !"; private readonly int _defaultInteger = 0; public ValidateAuthorNameAttribute() : base(_defaultErrorMessage) { } public override string FormatErrorMessage(string name) { return String.Format(CultureInfo.CurrentCulture, ErrorMessageString, name); } public override bool IsValid(object value) { string valueAsString = value as string; var query = repo.GetAllActive(valueAsString); int restrictedUserNameCount = 0; if(query != null) restrictedUserNameCount = query.Count(); return (valueAsString != null && restrictedUserNameCount == _defaultInteger); } } }here is the account model ;
[PropertiesMustMatch("Password", "ConfirmPassword", ErrorMessage = "The password and confirmation password do not match.")] public class RegisterModel { [Required] //As you see here, I am using it like a new validation control... [ValidateAuthorName] [DisplayName("User name")] public string UserName { get; set; } [Required] [DataType(DataType.EmailAddress)] [DisplayName("Email address")] public string Email { get; set; } [Required] [ValidatePasswordLength] [DataType(DataType.Password)] [DisplayName("Password")] public string Password { get; set; } [Required] [DataType(DataType.Password)] [DisplayName("Confirm password")] public string ConfirmPassword { get; set; } }then you will be all set. it works fine but if you would like to use it as client validation, you need a further work to do.
tweets as @tourismgeek
Inx
Member
53 Points
217 Posts
Re: CustomValidation?
Nov 26, 2010 02:44 PM|LINK
Thanks man :)..even if I think I actually will try to use the Remote-validation attribute, since its kind of nice and also gives me a client-side validation at the same time :)..
I did get it all working now...I were just beeing plain stuid and didnt check the QueryString thats sent with the request of the ajax-call..anyway...I do get the princip now of the RemoteValidation attribute, but one thing I cant figure out is...what if I have two properties/fields that uses the same validation function..then the parameter-name sent to the function whould differ..so is there anyway to solve that?...
Inx
Member
53 Points
217 Posts
Re: CustomValidation?
Nov 26, 2010 02:49 PM|LINK
I could in this case just set two parameters one for the Published property and then one for the Updated property, but that whouldnt be such a nice solution in my opinion..so what Im asking for is a more generall solution..so I simply can apply this attribute to any field..without haveing to modify the validation function..
ricka6
All-Star
15070 Points
2272 Posts
Microsoft
Moderator
Re: CustomValidation?
Nov 26, 2010 05:23 PM|LINK
If you want to compare two properties, look at the Compare attribute. Build a new MVC 3 project and look at the account controller/model for reqistering a new user. The confirmPassword much match.
Inx
Member
53 Points
217 Posts
Re: CustomValidation?
Nov 26, 2010 06:07 PM|LINK
Well..I dont want to compare two properties..I want two properties to use the same Remote validation..
for instance like this:
Model:
public class BlogPostModel { [Required] public Int64 ID { get; set; } [Required] [Remote("IsDateTimeFormat", "Validation", Fields = "Published")] public DateTime Published { get; set; } [Remote("IsDateTimeFormat", "Validation", Fields = "Updated")] public DateTime Updated { get; set; } [Required] [DataType(DataType.Text)] public string Title { get; set; } [Required] [DataType(DataType.MultilineText)] public string HtmlContent { get; set; } protected bool ValidateDateTime(object value) { if (((string)value).Length > 1) return false; return true; } }The view:
[OutputCache(Location = OutputCacheLocation.None, NoStore = true)] public class ValidationController : Controller { public JsonResult IsDateTimeFormat(string Published) { DateTime newdatetime; bool success = DateTime.TryParse(Published, out newdatetime); if (success) return Json(true,JsonRequestBehavior.AllowGet); else return Json("The Date format you enterd is invalid!", JsonRequestBehavior.AllowGet); } }In this case the called validation function only takes a parameter namned "Published", which meens that once Im validating the field with the name "Published" the validation will go through like it should and the parameter Published will get the value of the field Published.
But if the field Updated tries to call this function then the parameter Published wont get set, since the only parameter that gets set/sent by the request is a parameter namned Updated..so is there any way to make this more generall?..so the parameters name wont matter..
Another thing I also found out is that for some reason it seems that once Im entering something in the Published field(the textbox of the site) and then blur it(unfocus it) the validation function gets called for this field and all the other fields that has this validation on them aswell..
Kind a hard to explain..but if you didnt get it at the above description of the problem then let me know and I will try to explain it abit more in details :)