15. ObjectValidator - מה המספר פלאפון שלך?, פורסם ב-31.7.2007
16. ObjectCollectionValidator - מה המספרי פלאפון של החברים שלך?, יפורסם ב-2.7.2007
ObjectValidator - מה המספר פלאפון שלך?
התקבלה ההחלטה שניקח מהמבקרים במועדון החשפנות את הפלאפון שלהם ונתקשר אליהם שבוע לפני היום-הולדת שלהם כדי להזכיר להם על ה-Lap dance החינם.
בנוסף, במהלך אותו ישיבה רבת-מעלה בצידי הבמה בזמן שהאורות האדומים והירוקים מהבהבים, נאמר משהו על כך שבעתיד נרצה לקחת עוד כמה מספרי פלאפון. ואם זה לא היה מספיק גרוע, שאנחנו שומרים למסד נתונים נרצה לשמור את הקידומת (054\052\056\050) בנפרד משאר מספר הפלאפון ובכלל לתוך טבלה נפרדת.
אז מה אנחנו יודעים?
- וולידציה של מספרי פלאפון הוא חוזר על עצמו.
- הניתוח של הוצאת קידומת ממספר פלאפון בטוח גם חוזר על עצמו.
אז כדי לחסוך עבודה בעתיד ניצור מחלקה מיוחדת בשם פלאפון שתהיה אחראית לטיפול בפלאפונים.
מה המחלקה הזו תכיל? מספר פלאפון זה בטוח.
נוסיף גם איזה קונסטרקטור שבתוכו נוכל לאתחל את המספר פלאפון הזה.
עכשיו נרצה להוסיף גם וולידציה שמספר הפלאפון הוא מספר פלאפון תקף בישראל.
כבר ראינו שבשביל ניתוח מחרוזת נשתמש ב-RegexValidator. אז נוסיף RegexValidator בהתאם.
נעבור בקצרה על ה-Regex לדוגמה הזה:
- מחייב שמספר הפלאפון יתחיל עם 05 ואחריו 0, 2, 4 או 6.
- משאיר מקום לסימן מקף "-" באמצע המספר פלאפון ומאפשר בין 0 ל-1 הופעות שלו.
- בין 7 ל-8 ספרות
ניצור את הפונקציה הרלוונטית שדיברנו עליה שמחלצת את הקידומת (שלושת הספרות הראשונות) של מספר הפלאפון.
נרצה לבצע מספר וולידצייה גם על הקידומת הזו.
נבדוק שהקידומת של ארבעת המספרים הראשונה תואמת להיצע הנוכחי של חברות הסלולרי.
נשים לב שאפשר לשים Validatorים של VAB על פונקציות!
יש מספר הגבלות ל-VAB עם פונקציות, בעיקר שהן לא מקבלות שום פרמטרים.
אגב, תחשבו איזה סמטוכה אם היינו צריכים להכניס את הלוגיקה הזאת של קידומת מספרים סלולריים לתוך ה-Regex...
OK, בנינו איזה מחלקת פלאפון מתוחכמת להחריד שיודעת לעשות חצי מהכל ועוברת כמה וולידיות. אז מה?
אנחנו הרי בונים מערכת דירוג ביקור במועדון חשפנות!
נוסיף בתוך המחלקה שעבדנו עליה כל הזמן הזה, טיפוס מסוג פלאפון.
עכשיו יש לנו דילמה. הרי יש לנו שדות ב-Winforms ו-ASP.Net שצריכים וולידציה.
והם צריכים לפנות לוולידציה ל: (1) מחלקה מסויימת (2) מאפיין מסויים.
אי-אפשר להפנות אותם רק ל-CellPhone.PhoneNumber כי אז תתפספס הוולידציה על ()CellPhone.ExctractCellPhoneAreaCode ולהפך.
אז נפנה את הוולידציה שלנו, בשני ה-GUIים ל-VisitRating.CellPhone.
ב-Winforms יש לנו את השדה:
ובהתאם נקבע שהוא יפנה ל-VisitRating.CellPhone
ב-ASP.Net יש לנו את השדה הבא
ונקבע לו מאפיינים שיצביעו גם על BL.VisitRating.CellPhone.
עכשיו אתם שואלים, "אבל רגע, ג'סטין, VisitRating.CellPhone הוא בכלל מטיפוס CellPhone ואנחנו מבצעים וולידציה עד עכשיו רק על טיפוסים פרימיטביים."
נכון, בשביל שה-PropertyProxyValidator של ASP.Net וה-ValidationProvider של Winforms ידעו להציב את המחרוזת שקיבלנו ב-tbxCellPhone לתוך VisitingRating.CellPhone נצטרך להמיר ממחרוזת ל-CellPhone.
נדבר על זה עוד שנגיע לוולידציה.
ההמרה ממחרוזת ל-CellPhone היא יחסית פשוטה, פשוט נאתחל מופע חדש של BL.CellPhone עם המחרוזת הרלוונטית.
ב-ASP.Net נשתמש באירוע ה-ValueConvert:
כאן קיבלנו את הערך של המחרוזת בתוך תיבת הטקסט כ-e.ValueToConvert והחזרנו אותו בתור e.ConvertedValue.
ב-Winforms גם נשתמש באירוע ה-ValueConvert, אבל בצורה קצת שונה:
הקוד שהשתמנו להמרה ממחרוזת לטיפוס פלאפון לא רלוונטיים כרגע (היות ונרחיב עליו הרבה בהמשך), אבל חשוב להבין למה היה צריך היה לבצע את ההמרה הזו.
אנחנו למעשה לוקחים TextBox.Text ורוצים להריץ עליו וולידציות של BL.CellPhone, ברור שנצטרך לבצע כאן המרה מסויימת.
ועכשיו נחזור לבעיה שראינו קודם, למה בכלל שהוולידציות שכתובת בתוך טיפוס BL.CellPhone ירוצו שאנחנו מבצעים וולידציה על BL.VisitRating.CellPhone?
נצטרך וולידטור שאומר שהוולידציה של הטיפוס VisitRating תלויה בוולידציה של הטיפוס CellPhone.
יהפוך ל
שימו לב שה-GUIים שלנו מריצים וולידציה על VisitRating.CellPhone ואין להם מושג בכלל מה הכללי וולידציה בתוך BL.CellPhone.
בואו נראה איך כל זה נראה ב-GUIים שלנו.
ננסה להכניס סתם טקסט:
ננסה להכניס את מספר הפלאפון שלי 054-6566789 שבתקווה גם יעבור וולידציה:
ועכשיו נשנה את הקידומת של הפלאפון למשהו שלא קיים ב-DomainValidator שכתבנו. למשל לקידומת 0540 הלא קיימת.
שמתם לב? מספר פלאפון וולידי, אבל הקידומת לא ברשימת הקידומות שלנו.
נראה איך היינו מוסיפים את כל הוולידטורים האלו דרך עורך הקונפיגיורציה הגרפי.
נתחיל מלהוסיף את הקונפיגיורציה של CellPhone.
שימו לב שבהגדרה של CellPhone יש גם מתודה שעוברת וולידציה באמצעות ה-DomainValidator שלנו שבודק קידומות.
נביט על ה-XML שקיבלנו מהעורך הגרפי בקובץ הקונפגיורציה BL.config:
הדבר היחידי הבאמת מעניין כאן זה שהקונפיגיורציה של CellPhone מכילה וולידציה על מתודה ומולנו אפשר לראות שיש תגית <methods> מיוחדת לזה ובתוכה מקוננות תגיות <method>, ובתוכן יש וולידציה כרגיל.
נוסיף את ההגדרה של ObjectValidator שיושב על VisitRating.
אין שום דבר מעניין לפרט במאפיינים של ObjectValidator.
בקונפיוגרציה של VisitRating יש רק הנחייה כללית לבצע וולידציה על CellPhone לפי הכללים של הטיפוס CellPhone.
בואו נביט על דוגמה פשוטה ואבסטרקטית לשימוש ב-ObjectValidator שלא קשורה כרגע למועדון החשפנות שלנו.
הרעיון הוא שנוכל לראות את העיקר ב-ObjectValidator, בלי להתעסק ב-GUI ובדרישות, אלא להתמקד בצורת העבודה שלו כרגע.
יש לנו שלוש מחלקות:
1. FirstClass שבתוכה יש SecondClass
2. SecondClass שבתוכה יש ThirdClass
3. ThirdClass עם מחרוזת שהיא לכל היותר שלושה אותיות.
נראה את זה בדיאגרמה:
נכתוב קוד שקובע ערך ל-MaxThreeLetterString.
כאן, הלכנו דרך FirstClass.SecondClass.ThirdClass והגענו ל-MaxThreeLetterString.
עכשיו נראה למה צריך וולידציה.
נצטרך איכשהו לאכוף את זה ש-MaxThreeLetterString הוא אכן לכל היותר 3 אותיות.
אנחנו כבר מתורגלים ב-VAB אז נוסיף StringLengthValidator ל-MaxThreeLetterString.
נריץ את הקוד הבא שמאתחל את המחלקה FirstClass הלא וולידית, שולח אותה לוולידציה ומדפיס אם היא וולידית או לא.
והתוצאה - ברור שהיא בסדר גמור.
אז מה עם הוספנו StringLengthValidator על MaxThreeLetterString?
לכל וולידציה שתתבצע על FirstClass אין שום דרך או סיבה להכיר את הוולידציות של ThirdClass.
נצטרך להגיד לוולידציות של FirstClass לכלול את הוולידציות של SecondClass שבתוכה, ולוולידציות של SecondClass לכלול את הוולידציות של ThirdClass שבתוכה.
ורק עכשיו כאשר נריץ את הקוד הבא, נראה שהוא אכן לא וולידי:
למעשה, הוולידציה של המחלקות גולשת ממחלקה למחלקה ומכילה בתוכה את הלוגיקה של אותה מחלקה.
החצים הם לא רק קשרי אסוצאיציה, אלא הם גם הכיוון אליו תגלוש הוולידציה שלנו.