none
How to make use of Custom Validation in code behind (.xaml.cs)

    Question

  • metadata.cs

     

    [CustomValidation(typeof(TestBA.Web.GenderValidation), "IsGenderValid")]
                //[Required]
                public string MALE_OR_FEMALE;

     

    test.shared.cs

    [Shared]
        public static class GenderValidation
        {
            public static bool IsGenderValid(string gender, ValidationContext context, out ValidationResult valResult)
            {
                if (gender == "M" || gender == "m" || gender == "F" || gender == "f")
                {
                    valResult = null;
                    return true;
                }
                else
                {
                    valResult = new ValidationResult("The two valid values are 'M'/'F'");
                    return false;
                }

            }

     

     

    [CustomValidation(typeof(GenderValidation), "IsGenderValid")]
            [DataMember()]
            [StringLength(30)]
            public string MALE_OR_FEMALE
            {
                get
                {
                    return this._male_or_female;
                }
                set
                {
                    if ((this._male_or_female != value))
                    {
                        this.ValidateProperty("MALE_OR_FEMALE", value);
                        this.RaiseDataMemberChanging("MALE_OR_FEMALE");
                        this._mil_spec = value;
                        this.RaiseDataMemberChanged("MALE_OR_FEMALE");
                    }
                }
            }

     

     

    On the dataform this validation works perfectly.

    On click of validate button on the child window (using dataform), I run a validation routine, a stored procedure - which returns a dictionary of errors. Considering the above example(assuming that stored procedure gives an error if lower case "m" or "f" is entered or some other combination invalidates MALE_OR_FEMALE dataform field). How can I make use dictionary(KEY = MALE_OR_FEMALE, VALUE = "Value should be in upper case or something like this error message") in the code behind of this .xaml(dataform) and achieve exact same display result(the field is highlighted in red, an error message is displayed next to the dataformfield).

    Is it possible to do something SIMILAR   on the code behind (do I have to write a method similar to the one in test.shared.cs)

    this.ValidateProperty("MALE_OR_FEMALE", value);
                        this.RaiseDataMemberChanging("MALE_OR_FEMALE");
                        this._mil_spec = value;
                        this.RaiseDataMemberChanged("MALE_OR_FEMALE");

    Any help is appreciated.

    Sunday, June 28, 2009 3:09 PM

Answers

All replies

  • If you mean trigger the control validation manually and get validate result list, this post would be useful

    http://silverlight.net/forums/p/100112/230400.aspx#230400

    Thursday, July 02, 2009 3:25 AM
  •  Thanks for your response Mog Liang. You have pointed me the right direction, but I am not yet there to resolve the issue I am having.

     My validations are defined in the metadata.cs (a different project TestBA.web). The .shared validations are defined in this project( a static Method IsFormLevelDataValid has all the validations for each of the each of the fields of the database.

    I have a client project(TestBA) and I have done validation by calling stored procedure, which has returned a list of errors. I want to make use of this list and populate the errorsummary.

    How do I call the validation(that is in TestBA.web) from .xaml.cs (in project TestBA) and send the list of errors(which has elements also) and context).

     Thanks in advance. 

    Thursday, July 02, 2009 10:20 PM
  • create a never valid validation with preset error message on entity, then trigger it manually.

    I admit it's an ugly approach.Tongue Tied

    Thursday, July 02, 2009 11:33 PM
  • Hi Maud,

    The issue is I do not know the validation error before hand. Only the stored procedure would know what data is valid. In practical business application, it is true that the business rules would change(enhancements). The business rules in stored procedure could be modified and I should not be changing any code on the front end. I do not want to put too much of business logic on the view.

    How do I call the entity level validation from the code behind(.xaml.cs)? I have the errors returned by the store procedure in an observable collection. How do I call the entity level validation, which should accept observable collection, context, entity as parameteres.

    Once again, any help is appreciated.

     

    Monday, July 06, 2009 2:38 AM
  • So just to summarize the issue, you can validate your entity using a procedure stored in the database and a validation method (like the sample) on the server. Your question is how to do the same thing on the client, right?

    If you haven't done so already, for the first step you should create a CustomValidationAttribute an use it at the entity level (instead of the property).

    [CustomValidation(typeof(MyValidator), "IsMyEntityValid")]
    public class MyEntity { /* ... */ }

    Your IsMyEntityValid method can call the stored procedure directly (on the server). However, you'll find this approach will not translate well to the client. Since the stored procedure can only be accessed using a service, this means it can only be invoked asynchronously from the client. I have not seen any solutions (or even best practices) for asynchronous validation on the client.

    One alternative (which you may be alluding to) is to make some of the rules and errors used in the stored procedure available as metadata. This metadata could be shared between the client and server. The full stored procedure validation could be performed on the server to ensure validity and an approximation could be run on the client for immediate, user-friendly feedback.

    Kyle

    Monday, July 06, 2009 11:30 AM
  •  Kyle, Thanks for your response. Here is how far I have reached. On the client, on button click, I was able to call stored procedure (invoked a service) and have the errors in an observable collection (the property and error message).

    I think (I may be wrong), all I need to do is somehow send this observable collection(errors), context and entity (ent) to the custom validation (.shared.cs, which  could be at the entity level as suggested by you..

    [CustomValidation(typeof(MyValidator), "IsMyEntityValid")]
    public class MyEntity {Entity ent, ValidationContext context, out ValidationResult valResult, ObservableCollection<errors>)
     
     this is how my parent page looks like (just a reminder  am trying to do validation from child window, where I can add records.
     So the context of the parent and child window are the same, am I right?)
     
    Here is the parent context 
    public partial class Prod : Page
    {
    public Prod()
    {
    ProdContext _ProdContext = new ProdContext();
    InitializeComponent();

    this.ProdGrid.ItemsSource = _ProdContext.ITEMs;
    _ProdContext.LoadSelectedITEM();


    }
    } ....
     
    Note : If it is easier to deal with a LIST<T> or DICTIONARY<STRING, STRING> than an  Observable collection, I can do that. 
    All I am waiting for is send this list/dictionary/collection of errors, with proper context to the (shared.cs), where the custom validation exists.
     
    Thanks again, I would appreciate any help/suggestion. 

     
    I 
    Tuesday, July 07, 2009 2:34 AM

  • My validations are defined in the metadata.cs (a different project TestBA.web). The .shared validations are defined in this project( a static Method IsFormLevelDataValid has all the validations for each of the each of the fields of the database.

    I have a client project(TestBA) and I have done validation by calling stored procedure, which has returned a list of errors. I want to make use of this list and populate the errorsummary.

    You can't use a shared code for this, since all the shared method is able to call on the client is Silverlight .Net classes. There is no way you can call a stored procedure. So you have to add a custom method to the DomainService, which you should call explicitly.  See the DiscountProduct example in the ".NET RIA Services Overview for Mix 2009 Preview" (http://download.microsoft.com/download/F/B/8/FB8CA635-296B-487F-965C-8148F08B5319/riaservicesoverviewpreview.pdf)

     

    Tuesday, July 07, 2009 3:03 AM
  • SilverlightRIA,

    I am working on a solution for this which seems to work pretty well.  It will probably be another couple of days before I can get the post published though.

    I did have a couple questions regarding your DataForm usage though.  Are you having it auto-generate your fields?  Are you using the standard command buttons, or are you hiding the DataForm buttons and using your own buttons (to save and cancel)?

    Also, I presume that you are using WCF to invoke your stored procedure and get the ObservableCollection of results back, with something similar to FieldName, Message in the result object.  And are you just passing all of the properties from your object into the WCF method?

    I am basing my solution on the following WCF call:

    this._validationService.ValidateEmployeeAsync(employee.Gender, employee.MaritalStatus);

    And then the result being:

    ObservableCollection<ValidationService.GetEmployeeValidationErrorsResult>

    Where GetEmployeeValidationErrorsResult has:
    - string ErrorMessage
    - string FieldName

    Does this sound consistent with what you're doing?

    Thanks,
    Jeff Handley

    Wednesday, July 08, 2009 2:53 AM
  • Please see http://blog.jeffhandley.com/archive/2009/07/11/asyncvalidation.aspx for my solution to this.  It works with Silverlight 3 RTW and .NET RIA Services July 2009 Preview.

    I'd love to hear how this works for you.

    -Jeff Handley

    Saturday, July 11, 2009 8:24 AM
  • Thanks Jeffery for your efforts. I would go through your code and try to implement in my application. I would post my results on this forum. Just bear with me, it might take few days.

     

    Sunday, July 12, 2009 2:44 AM
  • Sounds great -- just let me know whenever you get to give it a try. I'm collecting some other feedback on the solution as well.
    Tuesday, July 14, 2009 6:50 AM
  • http://uiatoms.neurospeech.com/products/form-controls/ , AtomForm is capable of doing lot of validation methods, in custom as well as codebehind as well as data annotations. Works well with WPF as well as Silverlight

    Saturday, April 03, 2010 7:19 AM
  • Please see http://blog.jeffhandley.com/archive/2009/07/11/asyncvalidation.aspx for my solution to this.  It works with Silverlight 3 RTW and .NET RIA Services July 2009 Preview.

    I'd love to hear how this works for you.

    -Jeff Handley

     

     

    Would be really great if we could get to this site.

    Tuesday, August 24, 2010 2:10 PM
  • My blog seems to be broken at the moment.  I'll dig into it tonight. 

    Tuesday, August 24, 2010 2:48 PM
  • My blog is working again.  Unfortunately, I don't know what made it start to have the errors, nor do I know why it started working again. :-(

    Wednesday, August 25, 2010 12:12 AM