locked
Custom conditional validation RRS feed

  • Question

  • User1098690930 posted

    I want to implement some conditional validation logic on one of my entities. Basically, what I want to do is validate a field (using a regular expression) only if another field in my entity has a certain value. I'm using Dynamic Data + EF6.

    I looked at the CustomValidationAttribute, and tried to add one on my entity but I can't get it to work. After some research I saw that I could put that attribute on my field and get the other field's value using reflection but for some reason it doesn't work with Entity Framework, in both cases the ValidationContext parameter is null. (apparently it works if you use LINQ to SQL).

    I also tried overriding the ValidateEntity method in my DbContext but whenever I insert or edit something it doesn't get called.

    Any ideas on how I can do this ?

    Wednesday, September 30, 2015 4:06 AM

Answers

  • User-330204900 posted

    You can do this in the EF6 equivalent to Saving Changes event in  your business logic. if there is an error then you can throw a ValidationException this will be trapped but the UI and displayed. the only issue here is there is no way to highlight the individual field.

    the other way you could do this is to use a CustomValidator and then get the other fields using my FindControlReclusively and also my GetParentControl<FormView>()

    so you get the parent FormView then search that for the individual FieldTemplates you can then use the DataField property to get the displayed value.

    /// <summary>
    /// Finds the control recursive.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="root">The root.</param>
    /// <param name="Id">The id.</param>
    /// <returns></returns>
    public static T FindControlRecursive<T>(this Control root, string Id) where T : Control
    {
    	var control = root as T;
    	if (control != null && root.ID == Id)
    		return control;
    
    	foreach (Control Ctl in root.Controls)
    	{
    		T FoundCtl = Ctl.FindControlRecursive<T>(Id);
    
    		if (FoundCtl != null)
    			return FoundCtl;
    	}
    	return null;
    }
    
    /// <summary>
    /// Gets the parent control of type T.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="control">The control.</param>
    /// <returns></returns>
    public static T GetParentControl<T>(this Control control) where T : Control
    {
    	var parentControl = control.Parent;
    	while (parentControl != null)
    	{
    		var currentParentControl = parentControl as T;
    		if (currentParentControl != null)
    			return currentParentControl;
    
    		parentControl = parentControl.Parent;
    	}
    	return null;
    }

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, September 30, 2015 6:11 AM

All replies

  • User-330204900 posted

    You can do this in the EF6 equivalent to Saving Changes event in  your business logic. if there is an error then you can throw a ValidationException this will be trapped but the UI and displayed. the only issue here is there is no way to highlight the individual field.

    the other way you could do this is to use a CustomValidator and then get the other fields using my FindControlReclusively and also my GetParentControl<FormView>()

    so you get the parent FormView then search that for the individual FieldTemplates you can then use the DataField property to get the displayed value.

    /// <summary>
    /// Finds the control recursive.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="root">The root.</param>
    /// <param name="Id">The id.</param>
    /// <returns></returns>
    public static T FindControlRecursive<T>(this Control root, string Id) where T : Control
    {
    	var control = root as T;
    	if (control != null && root.ID == Id)
    		return control;
    
    	foreach (Control Ctl in root.Controls)
    	{
    		T FoundCtl = Ctl.FindControlRecursive<T>(Id);
    
    		if (FoundCtl != null)
    			return FoundCtl;
    	}
    	return null;
    }
    
    /// <summary>
    /// Gets the parent control of type T.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="control">The control.</param>
    /// <returns></returns>
    public static T GetParentControl<T>(this Control control) where T : Control
    {
    	var parentControl = control.Parent;
    	while (parentControl != null)
    	{
    		var currentParentControl = parentControl as T;
    		if (currentParentControl != null)
    			return currentParentControl;
    
    		parentControl = parentControl.Parent;
    	}
    	return null;
    }

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, September 30, 2015 6:11 AM
  • User1098690930 posted

    Thanks! Ended up going with the second way cause I just couldn't get the first one to work. But it's probably a little better since I can now throw a specific error.

    Thursday, October 1, 2015 2:49 AM
  • User-330204900 posted

    the first methods is the most complex, I still have issues every I try to implement afresh. I will be publishing my libraries soon with a project template, there just never seems enough hours in the day to get it done :)

    Thursday, October 1, 2015 5:02 AM