Re: Validation on my own

From: Peter Müller (peter.mueller193..mx.net)
Date: Wed May 04 2011 - 05:46:35 UTC

  • Next message: Michael Hast: "Super Class Per Entity for _Auto Classes"

    Hello to all,
    thank you for your descriptions. I'll study that. They are probably the better solutions for validation than my "quick-fix" is. Because I needed a fast solution for the moment, I did it that way:

    On my component, I added a NSMutableArray "_errorKeyPath" and fill that in my overriden method "validationFailedWithException":

    @Override
            public void validationFailedWithException(Throwable t, Object value,
                            String keyPath) {
                    _errorKeyPaths.addObject(keyPath);
                    super.validationFailedWithException(t, value, keyPath);
            }

    If my method "save" will be called (by click on submitbutton), the array is already filled, with the keypath of the "problem"-attributes. So I've only to check, if keyPath is in it. If there is, set alertMessage and "cancel save action".

    public WOComponent save() {
                    alertMessage=null;
                    if(_errorKeyPaths.containsObject("selectedUser.lastname")) {
                            alertMessage="Lastname of user must be set!";
                            _errorKeyPaths=new NSMutableArray<String>();
                            return null;
                    }
                    if(_errorKeyPaths.containsObject("selectedUser.firstname")) {
                            alertMessage="Firstname of user must be set!";
                            _errorKeyPaths=new NSMutableArray<String>();
                            return null;
                    }
                    if(_errorKeyPaths.containsObject("selectedUser.username")) {
                            alertMessage="Username of user must be set!";
                            _errorKeyPaths=new NSMutableArray<String>();
                            return null;
                    }
                    if(_errorKeyPaths.containsObject("selectedUser.password")) {
                            alertMessage="Password of user must be set.";
                            _errorKeyPaths=new NSMutableArray<String>();
                            return null;
                    }
                    if(selectedUser.password().length()<5) {
                            alertMessage="Password of user must have at least a length of 5 signs.";
                            _errorKeyPaths=new NSMutableArray<String>();
                            return null;
                    }
                    
                    
                    session.defaultEditingContext().saveChanges();
                    selectedUser = null;
                    return null;
            }

    I know, this is probably not the best way, but for the moment the fastest way for me, without adding for every attribut an own variable, and set it manually to the object.

    all the best,
    Peter M.

    -------- Original-Nachricht --------
    > Datum: Tue, 3 May 2011 10:24:48 -0700
    > Von: Ramsey Gurley <rgurle..marthealth.com>
    > An: woproject-de..bjectstyle.org
    > CC: "Peter Müller" <peter.mueller193..mx.net>
    > Betreff: Re: Validation on my own

    >
    > On May 3, 2011, at 9:27 AM, Kieran Kelleher wrote:
    >
    > > There are a few different approaches. It seems everyone has to create
    > one when they start programming WebObjects.
    >
    > Unless you use ERD2W... then you get it for free (^_^)
    >
    > ...
    >
    > > On May 3, 2011, at 9:40 AM, Peter Müller wrote:
    > >
    > >>
    > >> But what can I do, until the book reach me? How can I display the
    > messages, Wonder generates for me?
    >
    >
    > Wonder generates localized validation messages. The pretty messages are
    > stored in Project/Resources/Lang.lproj/ValidationTemplate.strings files in
    > all projects and frameworks. For instance, if you look in
    > ERExtensions/Resources/English.lproj/ValidationTemplate.strings you'll see
    >
    > "NullPropertyException" = "Please provide a
    > <b..displayNameForProperty@@</b>.";
    >
    > Which will be templated into "Please provide a <b>username</b>."
    > automatically for you by wonder. You'll notice wonder already has templates for 7
    > different languages. When you decide to add more languages to your app, you
    > just add a Localizable.strings file to your app for each language and
    > define your display name like
    >
    > "PropertyKey.username" = "Login ID";
    >
    > Or whatever in each language you support. I believe the message is
    > already available and translated into your appropriate session.language()
    > whenever it arrives in your WOComponent's validationFailedWithException(Throwable
    > th, Object value, String key). So all you need to do to get the pretty
    > message is return th.getMessage() somewhere.
    >
    > If you have custom validation that you would like to implement for this
    > object, then you need to first decide if this validation *should* be in your
    > model. If it is display logic, then bind to a component variable and put
    > the validation method in you component. If it is model logic (ex. username
    > must be minimum of 8 characters) then you can bind to your object and
    > implement a validation method on your model object. Either way, the method
    > signature looks the same. Example:
    >
    > public String validateUsername(String username) {
    > if(username.length() < 8) {
    > ERXValidationFactory factory = ERXValidationFactory.defaultFactory();
    > ERXValidationException ex = factory.createCustomException(this,
    > "username", username, "MinimumLengthException");
    > throw ex;
    > }
    > return username;
    > }
    >
    > Then in your ValidationTemplate.strings file add:
    >
    > "MinimumLengthException" = "The value of <b..displayNameForProperty@@</b>
    > is not long enough.";
    >
    > and perhaps something a bit more specific for your user entity like:
    >
    > "User.username.MinimumLengthException" =
    > "<b..displayNameForProperty@@</b> must be at least <b>8</b> characters long!";
    >
    > Wonder will automatically handle any validation it can based on your
    > model. If an attribute is required and the value is null, it will throw a
    > NullPropertyException through the factory before validateUsername() is ever
    > called.
    >
    > **DO NOT attempt to alter the state of the EO in validation methods. In
    > the above example, you can coerce username and return it as any value you
    > like, but do not attempt to set the value of any other attribute or
    > relationship inside a validation method. That is bad. It will seem to work at
    > first, but you are violating an EOF commandment and you will pay for it later
    > when strange, unexplainable editing context errors start to occur. Set
    > values in willUpdate, willInsert, init, or other methods intended to be used
    > for that purpose. Validation methods are purely for validating the state of
    > the object and coercing the argument passed in.
    >
    >
    > Ramsey
    >
    > >>
    > >> How can I display the messages, if I want to use the wonder-generated
    > Validation-Messages?
    > >>
    > >> Thanks
    > >> Peter M.
    > >>
    > >>
    > >> -------- Original-Nachricht --------
    > >>> Datum: Tue, 3 May 2011 08:51:53 -0400
    > >>> Von: Kieran Kelleher <kelleher..mail.com>
    > >>> An: woproject-de..bjectstyle.org, "Peter Müller"
    > <peter.mueller193..mx.net>
    > >>> Betreff: Re: Validation on my own
    > >>
    > >>> You can implement custom validation by simply adding validation
    > methods to
    > >>> any class that implements NSValidation interface.
    > >>>
    > >>> You can throw custom 'nice' message from your own Validation method.
    > >>>
    > >>> Also, if you use Wonder, the default messages will be 'nice' and
    > Wonder
    > >>> allows for nice localization too.
    > >>>
    > >>> There is a bit for you to learn, but it will be worth it.
    > >>>
    > >>> So for your user EO, you can add custom validation methods.
    > >>>
    > >>> For example for your password logic below, this would normally be
    > added in
    > >>> the EO class as sth like:
    > >>>
    > >>> public String validatePassword(Object aValue) throws
    > >>> NSValidation.ValidationException {
    > >>> if (aValue == null || aValue.toString().length() < 5) {
    > >>> throw new NSValidation.ValidationException("Password must be
    > >>> set and must contain at least 5 characters.");
    > >>> }
    > >>> return aValue.toString();
    > >>> }
    > >>>
    > >>> Your validate method gets called automatically in
    > takeValuesFromRequest
    > >>> phase of request handling.
    > >>>
    > >>> Your current approach will not work because you are validating in the
    > >>> invokeAction phase which comes after the takeValues phase.
    > >>>
    > >>> There is a book written by a bourbon-loving fairly smart Canuck
    > entitled
    > >>> "Practical WebObjects". Chapter 5 explains Validation in very easy to
    > >>> understand terms. If you read that, you will then know enough to be
    > dangerous.
    > >>> ;-)
    > >>>
    > >>> Regards, Kieran
    > >>>
    > >>>
    > >>> On May 3, 2011, at 8:31 AM, Peter Müller wrote:
    > >>>
    > >>>> Hello WO-Community,
    > >>>> i've a coding-problem because WO does a job for me, I want to do on
    > my
    > >>> own.
    > >>>>
    > >>>> I've a modelclass called "User" with a view fields:
    > >>>> id, firstname, lastname, email, ...
    > >>>>
    > >>>> id is primary key, firstname, lastname and a view others are
    > "required"
    > >>> fields.
    > >>>>
    > >>>> On my component I have a Form to set this fields. The "save"-Button
    > is
    > >>> linked to my method:
    > >>>>
    > >>>> public WOComponent save() {
    > >>>> alertMessage=null;
    > >>>> if(selectedUser.lastname()==null) {
    > >>>> alertMessage="Lastname of user must be set!";
    > >>>> return null;
    > >>>> }
    > >>>> if(selectedUser.firstname()==null) {
    > >>>> alertMessage="Firstname of user must be set!";
    > >>>> return null;
    > >>>> }
    > >>>> if(selectedUser.username()==null) {
    > >>>> alertMessage="Username of user must be set!";
    > >>>> return null;
    > >>>> }
    > >>>> if(selectedUser.password()==null ||
    > >>> selectedUser.password().length()<5) {
    > >>>> alertMessage="Password of user must be set and must contain at
    > least
    > >>> 5 signs.";
    > >>>> return null;
    > >>>> }
    > >>>> session.defaultEditingContext().saveChanges();
    > >>>> selectedUser = null;
    > >>>> return null;
    > >>>> }
    > >>>>
    > >>>> As you can see, I want to do the validation for the fields on my own
    > >>> (because I want to make a "nice" message to the user, and later also
    > >>> multilingual).
    > >>>>
    > >>>> But now the problem: If I click "save" on my component, first the
    > form
    > >>> will be set, and WO validates, if all required fields are set. If not,
    > it
    > >>> will print a message in console and "reset" the fields. My validation
    > will be
    > >>> ignored.
    > >>>>
    > >>>> Have I any chance to validate "required" fields on my own, and ignore
    > >>> WO's validation?
    > >>>>
    > >>>> Thank you very much,
    > >>>> All the best from germany
    > >>>> Peter M.
    > >>>> --
    > >>>> Empfehlen Sie GMX DSL Ihren Freunden und Bekannten und wir
    > >>>> belohnen Sie mit bis zu 50,- Euro!
    > https://freundschaftswerbung.gmx.de
    > >>>
    > >>
    > >> --
    > >> NEU: FreePhone - kostenlos mobil telefonieren und surfen!
    > >> Jetzt informieren: http://www.gmx.net/de/go/freephone
    > >
    >

    -- 
    NEU: FreePhone - kostenlos mobil telefonieren und surfen!			
    Jetzt informieren: http://www.gmx.net/de/go/freephone
    



    This archive was generated by hypermail 2.0.0 : Wed May 04 2011 - 05:47:18 UTC