DCSIMG
May 2009 - Posts - שלמה גולדברג (הרב דוטנט)

שלמה גולדברג (הרב דוטנט)

מרצה בסלע ויועץ בעולם ה - net.

May 2009 - Posts

הפרויקט שלי ב - CodePlex מופיע בעמוד הבית של Internet Explorer Downloads ב - MSDN

 

זוכרים את התוכנה לניהול ה -  Context Menu של IE
 
היום שוטטתי להנאתי בגוגל, ומצאתי שזה מופיעה ב - MSDN ב - Internet Explorer Downloads
 
 

The Difference Between Equals and Static Equal

 

כשהראתי לסטודנטים שאני מלמד את הפוסט של ספיריטוס שמדבר על ההבדלים בין Equal ל - ==,
 
שאלו אותי - מה ההבדל בין ה - Equal שיורשים מ - object לבין ה - Equal הסטטי ?
 
במחשבה ראשונה עניתי - שלמעשה הקריאה - Equal(obj1, obj2 מפעילה את obj1.Equal(obj2.
 
וכמובן שהשאלה הבאה הייתה, אז מה ההבדל ביניהם,
 
והתשובה הייתה נפתח את ה - reflector ונראה.
 
אז הנה הקוד של Equal
 

public static bool Equals(object objA, object objB)

{

    return ((objA == objB) ||

        (((objA != null) && (objB != null)) && objA.Equals(objB)));

}

 
למעשה קודם בודקים את האופרטור == ורק במקרה שזה החזיר false בודקים האם שניהם שונים מ - null ומפעילים את ה - equal,
 
שזה אומר למעשה כמה הבדלים מעשיים.
 
במידה ו - obj1 יהיה null, ה - Equal הרגיל ירסק את האפליקצייה בעוד שהסטטי יחיזר false.
 
במידה שעשינו override ל == אנחנו יכולים לקבל תוצאות שונות עבור ה - equal הרגיל (שלא מפעיל את ה - ==) לבין הסטטי.
 
במידה שעשינו override ל - equal אחנו יכולים לקבל תוצאה שונה עבור שני ה - equal

Visual Studio is configuring fo the first time...

אני מניח שכולם מכירים את החלון המעצבן הבא, כשאנחנו מפעילים את ה - VS בפעם הראשונה:
vs
 
 
בדרך כלל אפשר לחיות איתו, אבל במחשבים ציבוריים, (כמו במכללות) כל פעם שמגיעים לכיתה חדשה, צריך לחכות וזה מעצבן.
 
היום נטליה פטרוב (סטונדטית בכיתה) גילתה טריק נהדר.
 
במקום לחכות עד שה - VS יואיל בטובו להיפתח, אפשר לתת לחלון את הזמן שלו לקנפג את ה - VS, ובמקביל להפעיל עוד פעם את - VS, ולהתחיל לעבוד.
 

מה חדש ב- ‎C#‎ 4.0 (המאמר הראשון שלי)

 

כאן תוכלו לקרוא על C# 4.0
 
זהו המאמר הראשון שלי ב - MSDN
 
ותודה לסשה על העזרה בכתיבת המאמר.
 
וכמובן לאיש והאגדה גיא בורשטיין (אין כמוהו) על כל העזרה ועל כל ההשקעה שלו.
Posted: May 24 2009, 09:51 PM by Shlomo | with 3 comment(s)
תגים:, ,

כנס האקרים הישראלי - חלק ראשון

 

קודם כל, תודה לאבי שעדכן אותנו על הכנס.
 
הגעתי בשעה 3:15, היה תור די גדול בעמדת ההרשמה, היינו אמורים להתחיל ב 4:30 בהרצאות, כנראה שעקב העומס, זה נדחה,
 
בשעה 4:45 (איחור סביר) נסגרו הדלתות, (ניסיתי לשמור לך מקום, אבי)
 
התחיל לדבר עו"ד יהונתן קלינגר על דמות ההאקר איך שהוא מוצג על ידי הוליווד, בסופו של ההרצאה יצאנו עם רשימת סרטים חדשים שלא ראינו שמציגות האקרים בפעולה.
 
לאחר מכן, דיבר יניב מירון (מארגן הכנס) על Steganography - שבסופו של דבר הצלחתי להבין שההבדל בין Steganography להצפנה, שבהצפנה ההאקרים יודעים שיש מידע אבל הוא בלתי קריא, וב - Steganography אף אחד לא יודע,
 
יניב גם הביא דוגמא של סיסמא שמוסתרת בתוך קובץ תמונה, על ידי שהסיסמא כתובה בצבע שונה במעט מכל התמונה, והדרך היחידה לגלות את הסיסמא, היא לפתוח את הקובץ ולשנות את כל הערכים שזהים אחד לשני (כאלו שאנו חושדים שהם מסתירים את המידע האמיתי)
 
כרגע יצאנו לפיצות (נבדוק האם זה כשר)
 
נחזור בהמשך לעידכון
 
Posted: May 24 2009, 05:36 PM by Shlomo | with 4 comment(s)
תגים:,

Delegate --> Anonymous Methods --> Lambda Expression

 

אנחנו מתקרבים בצעדי ענק ל - C# 4.0, אבל אני נתקל עדיין באנשים (בעיקר סטונדנטים במהלך הלימודים) שמחפשים דוגמא לשלושת האופציות להפעלת delegate.
 
 
אז ככה:
 
ב - 1.1, האופציה היחידה לשליחת מתודה ל - delegate, היתה לכתוב מתודה ולתת אותה אותה כפרמטר ל - delegate,
 
דוגמא ראשונה:
 

        List<int> list = new List<int>();

        private int tmp;

 

        public int Function1(int item)

        {

            tmp = item;

            return list.Find(new Predicate<int>(FindItem));

        }

 

        private bool FindItem(int item)

        {

            return item == tmp;

        }

 
אמנם ב - 1.1 היה קיים רק ArrayList, אבל הרעיון הוא שהדרך היחידה לשלוח פונקציה ל - delegate, היא על ידי יצירת delegate, ושליחת השם של הפונקציה להפעלה.
 
דוגמא שניה:
 

        public void ThreadFunction1()

        {

            Thread thread = new Thread(new ThreadStart(Target));

            thread.Start();

        }

 

        private void Target()

        {

            int i = 0;

            while (true)

            {

                Thread.Sleep(1000);

                Console.WriteLine(i);

                i++;

            }

        }

 
כמו שאפשר לראות בדוגמא הראשונה, החיסרון הגדול של הדרך הזאת, היא שאין לפונקציה המופעלת באמצעות ה - delegate, גישה למשתנים לוקליים של הפונקציה שמתוכה היא הופעלה.
 
ואז ב - 2.2 הגיע לעולם המושג - Anonymous Methods, וכך נראה הקוד.
 
דוגמא ראשונה.
 

        public int Function2(int item)

        {

            return list.Find(delegate(int i)

            {

                return i == item;

            });

        }

דוגמא שניה:
 

        public void ThreadFunction2()

        {

            Thread thread = new Thread(delegate()

                {

                    int i = 0;

                    while (true)

                    {

                        Thread.Sleep(1000);

                        Console.WriteLine(i);

                        i++;

                    }

                });

 

            thread.Start();

        }

 
 
ואז ב - C# 3.0 הגיע המושג - Lamda Expression, שחוסך את המילה delegate,
וכך נראה הקוד:
 
דוגמא ראשונה:

        public int Function3(int item)

        {

            return list.Find(item1 => item1 == item);

        }

 
דוגמא שניה:

        public void ThreadFunction3()

        {

            Thread thread = new Thread(() =>

            {

                int i = 0;

                while (true)

                {

                    Thread.Sleep(1000);

                    Console.WriteLine(i);

                    i++;

                }

            });

 

            thread.Start();

        }

 
 
 נקודה ששווה לשים לב, זה שהרבה פעמים התחביר של 1.1 הוא הרבה יותר קריא (בעיקר כשלא צריך לכתוב את ה - new, ואפשר לכתוב ישירות)
 
 

        public int Function1(int item)

        {

            tmp = item;

            return list.Find(FindItem);

        }

 
 
מאמר טוב שכתב שחר לגבי חידושים ב - C# 3.0 תוכלו לקרוא כאן.

CustomValidator part 2 (CustomValidator and ValidatorCallout)

 

בהמשך לפוסט על CustomValidator, אז כמו שהבטחתי, נדבר גם על השילוב בינו לבין ValidatorCallout.
 
ה - ValidatorCallout הוא אחד מהתוספות המעניינים של ajax, הוא מאפשר להציג את הודעת השגיאה בצורה יפה ונוחה.
 
מה שצריך לעשות, זה לשייך את ה - targetControlID ל - Validator הספציפי.
 
הבעייה מתחילה כשאנחנו מצמידים ל - ValidatorCallout את ה - CustomValidator.
 
במקרה הזה במדה ונגדיר שהבדיקה תהיה רק בצד השרת, אנחנו נהיה בבעיה, כי במקרה כזה ה - CustomValidator לא מרונדר בכלל לדף, וה - ValidatorCallout מחפש את ה - Validator והוא לא מוצא אותו.
 
הפיתרון הוא פשוט, להגדיר EnableClientScript כ - true, (אין צורך לתת פונקציה - אלא אם כן אתם רוצים גם לבדוק בצד הלקוח) במקרה הזה ה - CustomValidator מרונדר לדף, וה - ValidatorCallout ימצא אותו, והכול יבוא על מקומו בשלום

CustomValidator Part 1

 

יצא לי לא מזמן, לייצר CustomValidator, יחד עם ValidatorCallout של ajax,
 
יש עם זה כמה בעיות, ופתרתי אותם, אז כמובן שצריך לכתוב פוסט על זה,
 
אבל חשבתי שלפני שאכתוב פוסט על הבעייה הספציפית, אולי שווה לכתוב פוסט על ה CustomValidator.
 
 
השימוש בשאר ה - validators הוא די פשוט,
גוררים את ה - validator לדף,
נותנים ערך ל - ControlToValidate,
במידת הצורך גם לעוד מאפיין, (כמו ContrloToCompare ב - CompareValidator, או ValidationExpression עבור RegularExpressionValidator
מגדירים את המאפיין EnableClientScript, שמגדיר האם לבצע את הבדיקה גם בצד הלקוח (ברוב במוחץ של המקרים זה צריך להיות מסומן כ - true)
 
וזהו.
 
השימוש ב CustomValidator, הוא טיפ טיפה יותר מורכב, היות ואנחנו צריכים לכתוב את כל הבדיקות לבד.
 
נחפש דוגמא פשוטה, נניח שאנחנו רוצים CompareValidator על שלוש תיבות טקסט שכולל גם RequiredFieldValidator (על הבעייה ש - CompareValidator לא מכיל RequiredFieldValidator, כתבתי כאן)
(ברור שאת הבעייה הזאת ניתן לפתור בדרכים קלות יותר, בחרתי בדוגמא הזאת כי זה קל למימוש)
 
 
כך נראה קוד ה html
 
 
   

    <asp:TextBox ID="txt1" runat="server"></asp:TextBox>

    <asp:TextBox ID="txt2" runat="server"></asp:TextBox>

    <asp:TextBox ID="txt3" runat="server"></asp:TextBox>

 

    <asp:CustomValidator

        ID="cv1"

        ControlToValidate="txt1"

        runat="server" 

        ErrorMessage="*"

        ClientValidationFunction="CompareAndRequierd"

        ValidateEmptyText="True"

        Comparer1="txt2"

        Comparer2="txt3"

        onservervalidate="cv1_ServerValidate">

    </asp:CustomValidator>

 

חשוב לשים לב למאפיין ValidateEmptyText שמוגדר כ - true, אחרת, במידה ולא יהיה ערך בתיבת הטקסט, הוא לא יריץ את הבדיקות.
 
וכן חשוב לשים לב, שהמצאתי שני מאפיינים חדשים ל CustomValidator,
בשם Compare1 ו - Compare2, (וזאת כדי שהפונקציות הבודקות האם ה valid, יהיו פונקציות גלובליות, ולא בכל פעם שארצה כזה validator, אצטרך לכתוב את הפונקציות מחדש)
 
 
נתחיל עם צד הלקוח,
 
כך נראה הסקריפט שבודק את צד הלקוח:
 

<script type="text/javascript">

    function CompareAndRequierd(sender, args) {

       

        if (args.Value == '') {

            args.IsValid = false;

            return;

        }

 

        var a = document.getElementById(sender.Comparer1);

        var b = document.getElementById(sender.Comparer2);

 

        args.IsValid = args.Value == a.value && args.Value == b.value;

    }

</script>

 
הפונקציה מקבלת שני פרמטרים, הראשון הוא sender, שהוא למעשה ה - Validator, והשני הוא args שמכיל שני מאפיינים,
הראשון Value, שזה הערך של תיבת הטקסט.
השני הוא IsValid, שכברירת מחדל שווה ל - true, ובמקרה שאנחנו רוצים להגיד שהערך אינו חוקי, נשנה את ערכו ל - false.
 
שימו לב ששני המאפיינים מתחילים באות גדולה.
 
נקודה נוספת, הסקריפט הזה ירוץ בשני המקרים הבאים,
הראשון - בזמן שיוצאים מהפקד, כלומר שתיבת הטקסט מאבדת פוקוס.
השני - לפני ריצה לשרת, בדרך כלל בלחיצת כפתור.
 
והנה הסבר הסקריפט.
בודקים האם יש ערך בתיבת הטקסט,
במידה וכן, נמצא את שני הפקדים האחרים, לפי השם שלהם.
נשווה את ערכי שלושת תיבות הטקסט.
 
 
 
וכעת נעבור לצד השרת.
 

protected void cv1_ServerValidate(object source, ServerValidateEventArgs args)

{

    if (args.Value.Trim() == string.Empty)

    {

        args.IsValid = false;

        return;

    }

 

    string a = ((WebControl)(source)).Attributes["Comparer1"];

    string b = ((WebControl)(source)).Attributes["Comparer2"];

 

    args.IsValid = args.Value == Request[a] && args.Value == Request[b];

}

 
אותו קוד בדיקה בצד השרת, בדיוק כמו בצד הלקוח.
 
במידה ואין ערך מחזירים false.
מוציאים מה - source את ה - attribute שמכיל את שמות ה - controls להשוואה, ומשווים את הערך של תיבת הטקסט, למה שהגיע ב - Request (השם של ה - control הוא למעשה גם ה - key בערכים שהגיעו דרך ה - request)
 
וכמובן לא לשכוח בקוד של הלחצן שגרם ל post back, לבדוק האם הדף הוא valid
שזה משהו שאנשים שוכחים לעשות, וצריך לעשות את זה כל פעם כשמוסיפים validators לדף.
 

protected void vrb_Click(object sender, EventArgs e)

{

    if (IsValid)

    {

 

    }

}

 
ושוב אני רוצה להדגיש, שאם הייתי צריך לעשות את הבדיקה הזאת באמת, כנראה שהייתי עושה את זה בצורה שונה, והדוגמא הנ"ל היא רק כדי להדגים כמה נקודות.
איך לעבוד עם CustomValidator בצד הלקוח ובצד השרת
ושיש את האפשרות להוסיף ל controls מאפיינים משלנו, ואיך מוציאים את הערכים שלהם, כשצריך.
 
 
הפוסט הבא ידבר בעזרת השם, על השילוב בין CustomValidator עם ValidatorCallout

CompareValidator Required RequiredFieldValidator

 

נניח שיש לכם את הקוד הבא:
 

<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>

<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>

 

<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server"

ErrorMessage="RequiredFieldValidator"

    ControlToValidate="TextBox1"></asp:RequiredFieldValidator>

<asp:CompareValidator ID="CompareValidator1" runat="server"

ErrorMessage="CompareValidator"

    ControlToValidate="TextBox2" ControlToCompare="TextBox1">

 
שני תיבות טקסט.
 
RequiredFieldValidator על התיבה הראשונה
 
ו CompareValidator על תיבת הטקסט השנייה.
 
נניח שנכניס ערך כלשהו לתיבת הטקסט הראשונה, ולא נכניס שום ערך לתיבת הטקסט השנייה. כשננסה לרוץ לשרת, נצפה לכאורה לקבל הודעת שגיאה שהערכים של שני תיבות הטקסט לא מתאימים, לא ?
 
אז התשובה היא שלא נקבל שום הודעת שגיאה,
 
רק במידה ונכניס ערך שונה לתיבת הטקסט השנייה מהערך של תיבת הטקסט הראשונה, נקבל את ההודעה של ה CompareValidator.
 
 
הפיתרון הוא פשוט, להוסיף גם RequiredFieldValidator עבור תיבת הטקסט השנייה.
 
 
אבל כשאני רואה כאלו דברים, אני חייב להבין למה זה קורה, אז פתחתי את ה reflector, והנה הקוד:
 

protected override bool EvaluateIsValid()

{

    string controlValidationValue =

            base.GetControlValidationValue(base.ControlToValidate);

    if (controlValidationValue.Trim().Length == 0)

    {

        return true;

    }

 
 
 
לא העתקתי את המשך הקוד.
אבל ברור מדוע במידה ולא הכנסנו ערך, אנחנו לא מקבלים את השגיאה של CompareValidator.
 
לי זה נראה כמו באג של מי שפיתח, את ה CompareValidator .
 
 
דרך אגב, שמתם לב שהמפתחים של מייקרוסופט לא משתמשים ב string.Empty, אלא ב Length==0, כדי לבדוק האם קיים ערך ב string, (ככל הנראה ענייני ביצועים)

Change network computers windows credentials

 

כשאנחנו מחברים את המחשב שלנו לדומיין, מערכת ההפעלה מזהה את המחשבים שמחוברים לדומיין, כשאנחנו מנסים להפעיל אותם,
במידה ואין הרשאות, מערכת ההפעלה תקפיץ חלון דומה לזה:
 
 
cert2
 
הבעייה עם החלון הזה, שבמידה ונסמן Remember,
כשניכנס פנימה, יכול מאוד להיות שנמצא תיקיות, שאין לנו הרשאות.
 
כשנירצה לשנות את ה user שאיתו אנחנו נכנסים, נגלה שאין קליק ימין ולבחירה כמו Change user
 
כדי לשנות את ההגדרה עבור כל אלו שמוגדרים ב Remember.
 
יש להיכנס ל Control Panel --> User Accounts --> Manager your credentials
 שם נוכל לשנות/למחוק סיסמאות שהוגדרו כ Remember.

Windows 7 and oracle

 

לצערי בחלק הפרויקטים אני צריך לעבוד עם oracle.
 
כשניסיתי להתקין, קבלתי את ההודעה הבאה :
Checking operating system version: must be 4.0, 5.0, 5.1, 5.2 or 6.0.    Actual 6.1
                                      Failed <<<<
 
חיפשתי ברשת ומצאתי שאפשר לשנות את ה compability כמו עם המסנג'ר 
 
ניסיתי לשנות את ההגדרה, והתברר לי שבמידה והקבצים יושבים ברשת, אין לי אפשרות (הרשאות ?) לשנות את ה compability,
 
אז העתקתי את הקבצים למחשב הלוקלי, ואמרתי לעצמי, לפני שאני אשנה את ה compability, ננסה להתקין שוב.
 
כמובן שזה נכשל, אבל לפני שהספקתי למצמץ, קבלתי את ההודעה הבאה:
comp
 
כמובן שבחרתי ב reinstall, וההתקנה עברה בצורה חלקה.
 
אז תעברו (מהר) ל windows7 והחיים שלכם יהיו יותר נחמדים.

Resource and Culture and UICulture (והשמה אוטומטית של מידע)

 

קבצי resource הם דרך נהדרת לשמור את ההודעות והטקסט של האפליקצייה לפי ה culture,
 
הדבר שמעצבן אותי כמפתח, שאני צריך בכל פעם לכתוב את הקוד של ההשמה מתוך קובץ ה resource על ה label המתאים.
 
אז לפני שאני אראה את הפיתרון שאני משתמש, נעשה מעבר מהיר על הנושא. לטובת אלו שלא יודעים מה זה resource ומה זה culture.
 
 
נניח שיש לי אפליקצייה שאני רוצה שתהיה גם באנגלית וגם בעברית, נתעלם לרגע מהעובדה שכיון הכתיבה הוא הפוך, ונתמקד בזה שהטקסט צריך להיות בשתי השפות.
 
איך נעשה את זה ?
 
קליק ימין עם העכבר על הפרויקט שלנו, נבחר ב add new item, ונבחר ב  Resource
 
 
Resource 1
 
 
אני נוהג לייצר קובץ עבור כל דף, והשם של ה resource הוא בדרך כלל השם של הדף.
 
כעת נוסיף עוד קובץ resource שהשם שלו יהיה זהה לשם של הקובץ הקודם, אבל עם סיומת של ה culture, לדוגמא: Default.he-IL.resx,
 
אחרי שנוסיף את הקבצים, ונתחיל לערוך אותם, נוכל להוסיף ערכים, שהם למעשה key-value, כשה key, יהיה זהה בשני הקבצים, אבל ה value, יהיה שונה, לדוגמא:
 
(העליון הוא הקובץ עם הסיומת של he-IL)
 
Resource2
 
 
וכעת בקוד מה שאנחנו צריכים לעשות, זה לתת לכל label, את הkey המתאים,
 
לדוגמא:
 

    protected void Page_Load(object sender, EventArgs e)

    {

        lblHello.Text = Default.lblHello;

        lblWelcome.Text = Default.lblWelcome;

    }

 
כעת נשאר לנו רק לקבוע, מאיזה קובץ לקחת את הערכים,
 
אז למעשה יש כמה דרכים, אפשר מקונפיג, אפשר על ידי הגדרות הדף, כאן אפשר לקרוא מאמר שמסביר את הנושא.
 
אני בדרך כלל עושה את זה מקוד, צריך לעשות override ל InitializeCulture, ושם להחליט מה ה resource המתאים,
 
יש לדף שני properties שמחליטים על הסביבה, הראשון, הוא ה Culture, זה אינו קשור אלינו, הוא מחליט באיזה פורמט יוצגו המספרים ותאריכים,
 
לדוגמא הקוד הבא,
 

    protected void Page_Load(object sender, EventArgs e)

    {

        lblTime.Text = DateTime.Now.ToLongDateString();

    }

 

    protected override void InitializeCulture()

    {

        Culture = "he-IL";

    }

 
יחזיר את התוצאה: שבת 09 מאי 2009
 
לעומת זאת הקוד הבא:
 

    protected void Page_Load(object sender, EventArgs e)

    {

        lblTime.Text = DateTime.Now.ToLongDateString();

    }

 

    protected override void InitializeCulture()

    {

        Culture = "en-US";

    }

 
יחזיר את התוצאה: Saturday, May 09, 2009
 
אבל כמו שאמרתי, זה לא המאפיין שכרגע אנחנו מדברים עליו, אנחנו מדברים על המאפיין UICulture,
הוא מחליט מאיזה קובץ resource לקחת את הערכים, ולכן הקוד הבא:
 

    protected void Page_Load(object sender, EventArgs e)

    {

        lblHello.Text = Default.lblHello;

        lblWelcome.Text = Default.lblWelcome;

    }

 

    protected override void InitializeCulture()

    {

        UICulture = "he-IL";

    }

 
יחזיר את הערכים מתוך קובץ ה resource עם סיומת ה he-IL,
 
לעומת זאת הקוד הבא:
 

    protected void Page_Load(object sender, EventArgs e)

    {

        lblHello.Text = Default.lblHello;

        lblWelcome.Text = Default.lblWelcome;

    }

 

    protected override void InitializeCulture()

    {

        UICulture = "en-US";

    }

 
יחזיר את הערכים, מתוך הקובץ הרגיל (ללא סיומת של תרבות כלשהו).
 
בעייה אחת, יש לזה, שבמידה ואנחנו צריכים גישה לערכים מתוך ה javascript, אין לנו, הפיתרון לזה, נמצא כאן.
 
והבעייה האחרונה (שלכבודה נכתב כל הפוסט הזה),
 
אני לא רוצה כמפתח לדאוג להשמה של כל הערכים על ה labels השונים, אז כדי לפתור את זה כתבתי את הפיתרון הבא:
 
בקבצי ה resource, השמות שאני נותן ל keys הם שם האובייקט_שם המאפיין לדוגמא:
 
resource3
 
 
שני הראשונים, הם שמות של label ומאפיין הטקסט שלהם, האחרון הינו RequiredFieldValidator ומאפיין ErrorMessage.
 
כעת בקוד אני מפעיל את המתודה הבאה:
 

private void SetDataFromResource()

{

    Type type = typeof(Default);

    PropertyInfo[] properties = type.GetProperties(BindingFlags.NonPublic | BindingFlags.Static);

 

    var stringProperties = from property in properties

                           where property.PropertyType == typeof(string)

                           select new Pair(property.Name, property.GetValue(null, null));

 

    foreach (var item in stringProperties)

    {

        string[] arr = item.First.ToString().Split('_');

        if (arr.Length == 2)

        {

            Control ctr = FindControl(arr[0]);

            if (ctr != null)

            {

                PropertyInfo pi = ctr.GetType().GetProperty(arr[1]);

                if (pi != null)

                {

                    pi.SetValue(ctr, item.Second.ToString(), null);

                }

            }

        }

    }

}

 
אני מוציא את כל הערכים מתוך קובץ ה resource.
 
מחפש control עם השם של האובייקט, במידה ואני מוצא, אני משים את הערך למאפיין.
 
 
הפיתרון הזה הוא לא כל כך טוב מבחינת ביצועים, אבל במידה והנקודה הזאת לא מפריעה, אז זה פותר לי את הבעייה שאני צריך לדאוג להשים את הערכים למקומות המתאימים

Windows 7 - Part 2

 

הפוסטים שלי לגבי WIN7, יתמקדו בדברים הפשוטים,
 
אז ככה, הדבר הראשון שהפריע לי, זה כשמתקינים את המסנג'ר, וממזערים אותו, הוא מתעקש להישאר על ה taskbar, ולא מוכן ללכת לצד ימין, כמו שהיה בעבר,
 
הפיתרון (ותודה לברוך) הוא להגדיר שהמסנג'ר יעבוד כמו בויסטה, הוראות מפורטות כאן.
 
הדבר השני, זה שה Quick Launch נעלם, הוראות מפורטות להחזרה כאן
Posted: May 08 2009, 08:28 AM by Shlomo | with 3 comment(s)
תגים:,

Windows 7 - א'

אז בהמלצתו של סשה ובעזרתו האדיבה של שי, התקנתי windows 7 על המחשב,
 
(אני חייב לציין שאני מגיע ישירות מ XP, ולא היה לי שום ניסיון עם ויסטה, כך שאני צריך להיזהר לא לכתוב על פיצ'רים שהיו כבר קיימים בויסטה.)
 
 
בכל מקרה, ההתקנה הייתה ממש נעימה בלי שום בעיות, 15 דקות בערך והמחשב היה מותקן,
 
לוקח לי הרבה זמן להתרגל לניווט בתוך windows,
 
אחד הדברים שהתלהבתי, היה כשלא הצלחתי להתחבר לרשת, windows הציע לי באדיבות לבדוק מה הבעייה,
 
אמרתי לו, אשמח אם תפתור לי את הבעייה, הוא חשב דקה וחצי, ואז הוא אומר לי שה DCPH (או משהו כזה) לא מוגדר, והאם אני מעוניין שהוא יגדיר אותו לבד, אמרתי לו שכן, וכעבור דקה וחצי, הייתי מסוגל לגלוש.
 
 
עד עכשיו הכול (חוץ מזה שאני צריך לחשוב איך מגיעים לכל דבר) נהדר עם המערכת, ואני בהחלט ממליץ להתנסות במערכת,
 
בנתיים מצאתי רק דבר קטן, שקצת הציק לי, כשאני מפעיל את ה Windows update, הוא מציג לי את גודל ההורדות, וכמה אחוזים ירדו, ואני צריך לחשב לבד כמה ירד, וכמה זמן נשאר,
 
ואני חושב שאם אחרי יום עבודה אינסטסיבי על המערכת, נתקלתי רק בדבר קטן כזה, שה מעיד שהפעם מייקרוסופט באמת עשו עבודה טובה.
 
 
 
Posted: May 06 2009, 11:45 AM by Shlomo | with 2 comment(s)
תגים:,

הפעלת מתודות סטטיות באמצעות ScriptManager חלק שני - (PageMethods - Authentication Failed)

בפוסט הקודם הדגמתי איך להפעיל מתודות סטטיות באמצעות ScriptManager
 
אבל מה יקרה במצב שהדף שלנו הוא דף הלוגין,ובקונפיג מוגדר בצורה הבאה:
 

    <authorization>

      <deny users="?"/>

    </authorization>

    <authentication mode="Forms">

      <forms loginUrl="Default.aspx"></forms>

    </authentication>

 
שזה אומר, שאסור להכנס לשום דף חוץ מה Default (שזה דף הלוגין)
 
במקרה הזה לא נצליח להפעיל את ה PageMethods,
 
הרבה אנשים אומרים להגדיר על המתודה [WebMethod(EnableSession=true)], אבל זה לא בדיוק עובד,
 
 
לכאורה זה נראה לי כמו באג של הצוות שפיתח את ajax, כי במידה ואני נמצא בדף שמוגדר כדף הלוגין ומותר לגלוש אליו, מדוע אסור להפעיל את ה PageMethods ?
 
מה שאפשר לעשות, זה להוסיף את הקוד הבא לקובץ הקונפיג מעל system.web
 

 

  <location path="Default.aspx">

    <system.web>

      <authorization>

        <allow users="*"/>

      </authorization>

    </system.web>

  </location>

 
זה יגרום שלא תהיה בדיקה האם יש הרשאות לדף Default,
אמנם זה טיפה מטופש כי Default מוגדר כדף לוגין, ולכאורה זה היה צריך לקרות בצורה אוטומטית,
 
אבל זה הפתרון היחידי שמצאתי.
More Posts Next page »