public void TryValidateModel_TestAJAXLikeValidation() { TestWidget model = new TestWidget(); Type modelType = model.GetType(); List <string> errors = null; WFModelMetaData metadata = new WFModelMetaData(); WFModelMetaData metadataExpected = new WFModelMetaData(); bool actual; Dictionary <string, string> values = new Dictionary <string, string>(); values.Add("model_RequiredName", "reqname"); values.Add("model_MaxLengthName", "toolongofaname"); values.Add("model_Sprockets", "4"); //bad sprocket value values.Add("model_Email", "bademail"); //bad email values.Add("model_Price", "999"); //bad price // NoErrorMessage property is NOT added and should NOT be present actual = WFUtilities.TryValidateModel(model, "model_", new WFDictionaryValueProvider(values), metadata, new WFTypeRuleProvider(modelType)); errors = metadata.Errors; Assert.AreEqual(errors.Count, 4); Assert.AreEqual(errors[0], "Max length 10 characters"); Assert.AreEqual(errors[1], "Invalid number of sprockets."); Assert.AreEqual(errors[2], "Widget must have valid e-mail"); //Generated error message on custom annotation Assert.AreEqual(errors[3], "Invalid price"); Assert.AreEqual(actual, false); }
/// <summary> /// This method should only be called by Html.<control>For() methods. /// It registers metadata for model properties if they do not exist for controls on the form and informs the control if there is an error. /// </summary> /// <param name="metadata"></param> /// <param name="Model"></param> /// <param name="tag"></param> /// <param name="markupName"></param> /// <param name="expressionBody"></param> /// <returns></returns> public HtmlTag PreRenderProcess(HtmlTag tag, ref WFModelMetaData metadata, TagTypes tagType, string markupName, PropertyInfo targetProperty, object model) { //Ignore tag types that are not tied to a property if (!validationTypes.Contains(tagType)) { return(tag); } if (model == null || String.IsNullOrEmpty(markupName) || tag == null || metadata == null) { return(tag); } WFModelMetaProperty metaprop = null; string lcName = markupName.ToLower(); for (int i = 0; i < metadata.Properties.Count; i++) { if (metadata.Properties[i].MarkupName.ToLower() == lcName) { metaprop = metadata.Properties[i]; break; } } if (metaprop == null) { metaprop = CreateMetaProperty(markupName, targetProperty, metadata, metaprop, model, HttpContext.Current); metadata.Properties.Add(metaprop); } if (metaprop.HasError) { tag.AddClass(WFUtilities.InputValidationErrorClass); } return(tag); }
public void TryValidateModel_TestAgainstModelSuccess() { TestWidget model = new TestWidget(); Type modelType = model.GetType(); WFModelMetaData metadata = new WFModelMetaData(); WFModelMetaData metadataExpected = new WFModelMetaData(); bool actual; model.Email = "*****@*****.**"; model.MaxLengthName = "goodname"; model.RequiredName = "reqname"; //Required model.Sprockets = 6; //Good sprocket count model.Price = 0.99d; //Good price model.NoErrorMessage = "reqmsg"; //Required - no error message defined actual = WFUtilities.TryValidateModel(model, "", new WFObjectValueProvider(model, ""), metadata, new WFTypeRuleProvider(modelType)); //No Errors Assert.AreEqual(metadata.Errors.Count, 0); //Properties are not collected when an error does not exist //The reason is because there is no page to collect them for Assert.AreEqual(metadata.Properties.Count, 0); Assert.AreEqual(actual, true); }
public void TryValidateModel_TestAgainstModelClassAttribute() { ClassAttributeTestWidget model = new ClassAttributeTestWidget(); Type modelType = model.GetType(); WFModelMetaData metadata = new WFModelMetaData(); WFModelMetaData metadataExpected = new WFModelMetaData(); bool actual; model.Email = "*****@*****.**"; model.MaxLengthName = "goodname"; model.RequiredName = "reqname"; //Required model.Sprockets = 6; //Good sprocket count model.Price = 0.99d; //Good price model.NoErrorMessage = "reqmsg"; //Required - no error message defined model.Password = "******"; model.ConfirmPassword = "******"; actual = WFUtilities.TryValidateModel(model, "", new WFObjectValueProvider(model, ""), metadata, new WFTypeRuleProvider(modelType)); //There should be one error from the model attribute Assert.AreEqual(metadata.Errors.Count, 1); //Properties are not collected when an error does not exist //The reason is because there is no page to collect them for Assert.AreEqual(metadata.Properties.Count, 0); Assert.AreEqual(actual, false); }
protected void Page_Load(object sender, EventArgs e) { Customer = new Customer(); CustomerAddress = new CustomerAddress(); MetaData = new WFModelMetaData(); if (Page.IsPostBack) { WFPageUtilities.UpdateModel(Request, Customer); WFPageUtilities.UpdateModel(Request, CustomerAddress); WFPageUtilities.TryValidateModel(MetaData, typeof(CustomerAddress), HttpContext.Current); WFPageUtilities.TryValidateModel(MetaData, typeof(Customer), HttpContext.Current); } }
public void RegisterXMLValidationConfiguration_TestClassLevelValidators() { WFUtilities.RegisterXMLValidationConfiguration(Environment.CurrentDirectory + "\\Validator3.config"); TestParticipantClass tpc = new TestParticipantClass(); tpc.Password = "******"; tpc.ConfirmPassword = "******"; WFModelMetaData metadata = new WFModelMetaData(); WFUtilities.TryValidateModel(tpc, "", new WFObjectValueProvider(tpc, ""), metadata, new WFXmlRuleSetRuleProvider("ClassLevelAttributes")); Assert.AreEqual("Password fields must match.", metadata.Errors[0]); }
/// <summary> /// This method is used internally to find or create meta properties in validation data. /// </summary> /// <param name="metadata">The metadata object.</param> /// <param name="markupName">The name of the property in markup.</param> /// <param name="model">The model object in memory the property belongs to.</param> /// <param name="reflectName">The reflected property name.</param> /// <param name="context">The current HTTP context.</param> /// <returns>Returns a WFModelMetaProperty class.</returns> public WFModelMetaProperty GetMetaProperty(WFModelMetaData metadata, string markupName, object model, string reflectName, HttpContext context) { Type tx = model.GetType(); PropertyInfo foundProperty = null; WFModelMetaProperty metaprop = null; foreach (PropertyInfo pi in tx.GetProperties()) { if (pi.Name == reflectName) { foundProperty = pi; metaprop = CreateMetaProperty(markupName, pi, metadata, metaprop, model, context); } } return(metaprop); }
public void TryValidateModel_TestProxyClassValidation() { FriendlyClass fc = new FriendlyClass(); fc.LastName = "onereallybiglongstringthatkeepsgoing"; // break validation List <string> errors = null; WFModelMetaData metadata = new WFModelMetaData(); bool didValidate = WFUtilities.TryValidateModel(fc, "", new WFObjectValueProvider(fc, ""), metadata, new WFTypeRuleProvider(typeof(FriendlyClass))); errors = metadata.Errors; Assert.AreEqual(false, didValidate); Assert.AreEqual(2, errors.Count); Assert.AreEqual("The FirstName field is required.", errors[0]); Assert.AreEqual("The field LastName must be a string with a maximum length of 10.", errors[1]); Assert.AreEqual(2, metadata.Properties.Count); }
public void TryValidateModel_ErrorMessageTests() { string resourceErrorMessage = Resources.FirstName_ErrorMessage_Test1; TestParticipantClass tpc = new TestParticipantClass(); WFModelMetaData metadata = new WFModelMetaData(); WFUtilities.TryValidateModel(tpc, "", new WFObjectValueProvider(tpc, ""), metadata, new WFTypeRuleProvider(typeof(ProxyMessageFromValidator))); Assert.AreEqual("The FirstName field is required.", metadata.Errors[0]); metadata = new WFModelMetaData(); WFUtilities.TryValidateModel(tpc, "", new WFObjectValueProvider(tpc, ""), metadata, new WFTypeRuleProvider(typeof(ProxyMessageFromConstant))); Assert.AreEqual("This is a constant error.", metadata.Errors[0]); metadata = new WFModelMetaData(); WFUtilities.TryValidateModel(tpc, "", new WFObjectValueProvider(tpc, ""), metadata, new WFTypeRuleProvider(typeof(ProxyMessageFromResource))); Assert.AreEqual("This value from resource.", metadata.Errors[0]); metadata = new WFModelMetaData(); }
public HtmlTag PreRenderProcess(HtmlTag tag, ref WFModelMetaData metadata, TagTypes tagType, string propertyName, System.Reflection.PropertyInfo targetProperty, object model) { if (tagType == TagTypes.Span || tagType == TagTypes.TextArea || tagType == TagTypes.Label || tagType == TagTypes.ValidationMessage || tagType == TagTypes.ValidationItem) { if (!String.IsNullOrEmpty(tag.InnerText)) { tag.InnerText = HttpUtility.HtmlEncode(tag.InnerText); } } else if (new TagTypes[] { TagTypes.Checkbox, TagTypes.Hidden, TagTypes.InputBox, TagTypes.RadioButton, }.Contains(tagType)) { if (!String.IsNullOrEmpty(tag.Attr("value"))) { tag.Attr("value", HttpUtility.HtmlEncode(tag.Attr("value"))); } } else if (tagType == TagTypes.Select) { foreach (HtmlTag child in tag.Children) { if (!String.IsNullOrEmpty(child.HTMLTagName) && child.HTMLTagName.ToLower() == "option") { //<option value="encode">encode</option> child.InnerText = HttpUtility.HtmlEncode(child.InnerText); if (!String.IsNullOrEmpty(child.Attr("value"))) { child.Attr("value", HttpUtility.HtmlEncode(child.Attr("value"))); } } } } return(tag); }
public void TryValidateModel_TestAgainstModel() { TestWidget model = new TestWidget(); Type modelType = model.GetType(); List <string> errors = null; List <string> errorsExpected = new List <string>(); WFModelMetaData metadata = new WFModelMetaData(); WFModelMetaData metadataExpected = new WFModelMetaData(); bool expected = false; bool actual; model.Email = "bademail"; model.MaxLengthName = "toolongofaname"; model.RequiredName = ""; //Required model.Sprockets = 4; //Invalid sprocket count model.Price = 999; //Invalid price model.NoErrorMessage = ""; //Required - no error message defined actual = WFUtilities.TryValidateModel(model, "", new WFObjectValueProvider(model, ""), metadata, new WFTypeRuleProvider(modelType)); errors = metadata.Errors; Assert.AreEqual(errors.Count, 6); //Generated error messages on standard annotations Assert.AreEqual(errors[0], "Widget name required"); Assert.AreEqual(errors[1], "Max length 10 characters"); Assert.AreEqual(errors[2], "Invalid number of sprockets."); Assert.AreEqual(errors[3], "Widget must have valid e-mail"); //Generated error message on custom annotation Assert.AreEqual(errors[4], "Invalid price"); //Auto-generated error message Assert.AreEqual(errors[5], "The NoErrorMessage field is required."); Assert.AreEqual(metadata.Properties.Count, 6); Assert.AreEqual(metadata.Properties[0].PropertyName, "RequiredName"); Assert.AreEqual(metadata.Properties[1].PropertyName, "MaxLengthName"); Assert.AreEqual(metadata.Properties[2].PropertyName, "Sprockets"); Assert.AreEqual(metadata.Properties[3].PropertyName, "Email"); Assert.AreEqual(metadata.Properties[4].PropertyName, "Price"); Assert.AreEqual(metadata.Properties[5].PropertyName, "NoErrorMessage"); Assert.AreEqual(actual, false); }
public HtmlTag PreRenderProcess(HtmlTag tag, ref WFModelMetaData metadata, TagTypes tagType, string markupName, string reflectName, object Model) { //Ignore tag types that are not tied to a property if (!validationTypes.Contains(tagType)) { return(tag); } if (reflectName == "") { reflectName = markupName; } if (Model == null || String.IsNullOrEmpty(markupName) || tag == null || metadata == null) { return(tag); } WFModelMetaProperty metaprop = null; string lcName = markupName.ToLower(); for (int i = 0; i < metadata.Properties.Count; i++) { //if (metadata.Properties[i].ModelObject == Model && metadata.Properties[i].MarkupName.ToLower() == lcName) if (metadata.Properties[i].MarkupName.ToLower() == lcName) { metaprop = metadata.Properties[i]; break; } } if (metaprop == null) { //Create a meta property if it does not exist metaprop = GetMetaProperty(metadata, markupName, Model, reflectName, null); metadata.Properties.Add(metaprop); } if (metaprop.HasError) { tag.AddClass(WFUtilities.InputValidationErrorClass); } return(tag); }
protected override void RenderContents(HtmlTextWriter output) { WFModelMetaData metadata = new WFModelMetaData(); foreach (DataAnnotationValidatorControl dvc in WebControlUtilities.FindValidators(this.Page)) { WFModelMetaProperty metaprop = WebControlUtilities.GetMetaPropertyFromValidator(this.Page, dvc, metadata); metaprop.OverriddenSpanID = dvc.UniqueID; if (!String.IsNullOrEmpty(dvc.Text)) { metaprop.OverriddenErrorMessage = dvc.Text; } metadata.Properties.Add(metaprop); } if (Unobtrusive) { output.Write(WFScriptGenerator.SetupClientUnobtrusiveValidationScriptHtmlTag().Render()); } else { output.Write(WFScriptGenerator.SetupClientValidationScriptHtmlTag().Render()); string targetid = ""; if (String.IsNullOrEmpty(TargetFormClientID)) { targetid = this.Page.Form.ClientID; } else { targetid = TargetFormClientID; } output.Write(new HtmlTag("script", new { type = "text/javascript", language = "javascript" }) { InnerText = WFScriptGenerator.EnableClientValidationScript(metadata, targetid) }.Render()); } }
/// <summary> /// Create a meta property from the specified PropertyInfo object, run validation on it against the current value and return it.<br/> /// If a WFModelMetaProperty is supplied, it will be validated/modified and then returned. /// </summary> /// <param name="markupName">The HTML markup name of the control rendering the property.<param> /// <param name="pi">The PropertyInfo object to retrieve DataAnnotations from.</param> /// <param name="metadata">The metadata for the model.</param> /// <param name="metaprop">The metadata for this particular property. (optional)</param> /// <param name="model">The particular model instance that owns this property.</param> /// <param name="context">The HttpContext supplying the value to validate against.</param> /// <returns></returns> private WFModelMetaProperty CreateMetaProperty(string markupName, PropertyInfo pi, WFModelMetaData metadata, WFModelMetaProperty metaprop, object model, HttpContext context) { object[] attribs = pi.GetCustomAttributes(false); var displayNameAttr = pi.GetCustomAttributes(typeof(DisplayNameAttribute), true).OfType <DisplayNameAttribute>().FirstOrDefault(); string displayName = displayNameAttr == null ? pi.Name : displayNameAttr.DisplayName; foreach (object o in attribs) { Type oType = o.GetType(); if (oType.IsSubclassOf(typeof(ValidationAttribute))) { var oVal = (ValidationAttribute)o; if (metaprop == null) // Try to find it ... { foreach (WFModelMetaProperty mx in metadata.Properties) { if (mx.ModelObject == model && pi.Name.ToLower() == mx.PropertyName.ToLower()) { metaprop = mx; break; } } } if (metaprop == null) // Make a new one ... { metaprop = new WFModelMetaProperty(); } metaprop.ModelObject = model; metaprop.PropertyName = pi.Name; metaprop.DisplayName = displayName; metaprop.MarkupName = markupName; metaprop.ValidationAttributes.Add(oVal); //if (context != null && !oVal.IsValid(context.Request[markupName])) { // metaprop.HasError = true; // metaprop.Errors.Add(oVal.FormatErrorMessage(displayName)); //} } } if (metaprop == null && pi != null) //No attributes were found for this property { metaprop = new WFModelMetaProperty(); metaprop.ModelObject = model; metaprop.PropertyName = pi.Name; metaprop.DisplayName = pi.Name; //No attributes, so no displayname metaprop.MarkupName = markupName; } return(metaprop); }
public void RegisterXMLValidationConfiguration_TestXMLErrorMessage() { WFUtilities.RegisterXMLValidationConfiguration(Environment.CurrentDirectory + "\\Validator2.config"); string resourceErrorMessage = Resources.FirstName_ErrorMessage_Test1; TestParticipantClass tpc = new TestParticipantClass(); WFModelMetaData metadata = new WFModelMetaData(); //============================= WEB FORMS SERVER CONTROL VALIDATION ================================= Page p = new Page(); p.Controls.Add(new TextBox() { ID = "FirstName" }); p.Controls.Add(new DataAnnotationValidatorControl() { PropertyName = "FirstName", ControlToValidate = "FirstName", XmlRuleSetName = "MessageFromValidator", ErrorMessage = "This message from control itself." }); p.Validators.Add(p.Controls[1] as IValidator); (p.Controls[1] as BaseValidator).Validate(); Assert.AreEqual("This message from control itself.", (p.Controls[1] as DataAnnotationValidatorControl).ErrorMessage); p = new Page(); p.Controls.Add(new TextBox() { ID = "FirstName" }); p.Controls.Add(new DataAnnotationValidatorControl() { PropertyName = "FirstName", ControlToValidate = "FirstName", XmlRuleSetName = "MessageFromXML", }); p.Validators.Add(p.Controls[1] as IValidator); (p.Controls[1] as BaseValidator).Validate(); Assert.AreEqual("The First Name field cannot be empty.", (p.Controls[1] as DataAnnotationValidatorControl).ErrorMessage); p = new Page(); p.Controls.Add(new TextBox() { ID = "FirstName" }); p.Controls.Add(new DataAnnotationValidatorControl() { PropertyName = "FirstName", ControlToValidate = "FirstName", XmlRuleSetName = "MessageFromResource", }); p.Validators.Add(p.Controls[1] as IValidator); (p.Controls[1] as BaseValidator).Validate(); Assert.AreEqual("This value from resource.", (p.Controls[1] as DataAnnotationValidatorControl).ErrorMessage); //====================== TryValidateModel ============================== WFUtilities.TryValidateModel(tpc, "", new WFObjectValueProvider(tpc, ""), metadata, new WFXmlRuleSetRuleProvider("MessageFromValidator")); Assert.AreEqual("The FirstName field is required.", metadata.Errors[0]); metadata = new WFModelMetaData(); WFUtilities.TryValidateModel(tpc, "", new WFObjectValueProvider(tpc, ""), metadata, new WFXmlRuleSetRuleProvider("MessageFromXML")); Assert.AreEqual("The First Name field cannot be empty.", metadata.Errors[0]); metadata = new WFModelMetaData(); WFUtilities.TryValidateModel(tpc, "", new WFObjectValueProvider(tpc, ""), metadata, new WFXmlRuleSetRuleProvider("MessageFromResource")); Assert.AreEqual("This value from resource.", metadata.Errors[0]); metadata = new WFModelMetaData(); }
/// <summary> /// Build and return script and JSON objects to enable client validation. /// This should be called from WFPageBase or WFUserControlBase /// </summary> /// <param name="metadata"></param> /// <returns></returns> public static string EnableClientValidationScript(WFModelMetaData metadata, string formId) { StringBuilder sb = new StringBuilder(); sb.Append("if(!window.wfuClientValidationMetadata) { window.wfuClientValidationMetadata = []; }\r\n"); sb.Append("window.wfuClientValidationMetadata.push("); List <JSONObject> fields = new List <JSONObject>(); foreach (WFModelMetaProperty prop in metadata.Properties) { JSONObject field = new JSONObject(); field.Attr("FieldName", prop.MarkupName); field.Attr("ReplaceValidationMessageContents", true); //Remove $'s which jQuery doesn't like in ID's string spanID = ""; if (!String.IsNullOrEmpty(prop.OverriddenSpanID)) { spanID = prop.OverriddenSpanID; } else { spanID = prop.MarkupName + "_validationMessage"; } spanID = spanID.Replace("$", @"\\$"); field.Attr("ValidationMessageId", spanID); List <JSONObject> validationRules = new List <JSONObject>(); foreach (object oVal in prop.ValidationAttributes) { ValidationAttribute val = oVal as ValidationAttribute; JSONObject valRule = new JSONObject(); JSONObject valParms = new JSONObject(); Type valType = oVal.GetType(); if (!String.IsNullOrEmpty(prop.OverriddenErrorMessage)) { valRule.Attr("ErrorMessage", prop.OverriddenErrorMessage); } else { valRule.Attr("ErrorMessage", val.FormatErrorMessage(prop.DisplayName)); } if (valType == typeof(StringLengthAttribute) || valType.IsSubclassOf(typeof(StringLengthAttribute))) { valParms.Attr("maximumLength", ((StringLengthAttribute)oVal).MaximumLength); valParms.Attr("minimumLength", 0); valRule.Attr("ValidationType", "stringLength"); valRule.Attr("ValidationParameters", valParms); } else if (valType == typeof(RequiredAttribute) || valType.IsSubclassOf(typeof(RequiredAttribute))) { valRule.Attr("ValidationType", "required"); valRule.Attr("ValidationParameters", new JSONObjectEmpty()); } else if (valType == typeof(RangeAttribute) || valType.IsSubclassOf(typeof(RangeAttribute))) { valParms.Attr("minimum", ((RangeAttribute)oVal).Minimum); valParms.Attr("maximum", ((RangeAttribute)oVal).Maximum); valRule.Attr("ValidationType", "range"); valRule.Attr("ValidationParameters", valParms); //Create an additional 'number' validation JSONObject numRule = new JSONObject(); JSONObject numParms = new JSONObject(); numRule.Attr("ErrorMessage", "The field " + prop.DisplayName + " must be a number."); numRule.Attr("ValidationParameters", new JSONObjectEmpty()); numRule.Attr("ValidationType", "number"); validationRules.Add(numRule); } else if (valType == typeof(RegularExpressionAttribute) || valType.IsSubclassOf((typeof(RegularExpressionAttribute)))) { valRule.Attr("ValidationType", "regularExpression"); valRule.Attr("ValidationParameters", new JSONObject(new { pattern = ((RegularExpressionAttribute)oVal).Pattern .Replace("\\", "\\\\") .Replace("\"", "\\\"") })); } else //Custom Validator { if (val as IWFClientValidatable != null) { IWFClientValidatable valAttr = (IWFClientValidatable)val; var cvrs = valAttr.GetClientValidationRules(); if (cvrs != null) { bool firstRule = true; foreach (var cvr in cvrs) { if (firstRule) { valRule.Attr("ValidationType", cvr.ValidationType); if (cvr.ValidationParameters != null) { foreach (KeyValuePair <string, object> kvp in cvr.ValidationParameters) { valParms.Attr(kvp.Key, kvp.Value); } } valRule.Attr("ValidationParameters", valParms); firstRule = false; } else { JSONObject vrx = new JSONObject(); JSONObject vrxParms = new JSONObject(); vrx.Attr("ErrorMessage", cvr.ErrorMessage); vrx.Attr("ValidationType", cvr.ValidationType); if (cvr.ValidationParameters != null) { foreach (KeyValuePair <string, object> kvp in cvr.ValidationParameters) { vrxParms.Attr(kvp.Key, kvp.Value); } } vrx.Attr("ValidationParameters", vrxParms); validationRules.Add(vrx); } } } } } validationRules.Add(valRule); } field.Attr("ValidationRules", validationRules); fields.Add(field); } JSONObject jo = new JSONObject(new { Fields = fields, FormId = formId, ReplaceValidationSummary = false }); sb.Append(jo.Render()); sb.Append(");"); return(sb.ToString()); }