שלום שלום לכולם,

הגעתם לבלוג הדוט נט של ג'סטין-יוסף אנג'ל.

בבלוג זה וכמו כן בבלוג שלו במיקרוסופט ישראל תוכלו להתעדכן במאמרים חדשים פרי עיטו.

ג'סטין-יוסף אנג'ל עובד בשמונה שנים האחרונות בפיתוח בתחום ה-web, מתוכם בשלוש שנים האחרונות כמפתח דוט-נט בכיר ובשנה האחרונה כיועץ .Net בכיר עצמאי.

בשלוש האחרונות הוא עבד וייעץ בפרוייקטים רבים במגוון תפקידים שונים וביניהם: יועץ, אחראי פרוייקט, ארכיטקט ותוכניתן בכיר. הוא פעיל ועובד בתחומים רבים: ניהול פרוייקטים במתודולוגיות Agile, פיתוח מערכות מבוזרות, ASP.Net, ניתוח, אפיון ופיתוח מונחה ארכיקטורת עצמים, Web 2.0, ניהול והכשרות.

ג'סטין-יוסף אנג'ל מחזיק את הבלוג הוותיק ביותר בעברית בתחום הדוט נט. בבלוג זה הוא מפרסם מאמרים טכניים ו-Webcastים שונים המיועדים הן למפתחים מתחילים והן לגורואים בתחומם כאחד.

ג'סטין-יוסף אנג'ל בעל מספר תארים מקצועיים. הוענק לו תואר MVP לשנים 2006-2007 שניתן ע"י מיקרוסופט למפתחים שהראו ידע מעמיק, מיומנות טכנית רצינית ובעלי היסטוריה של מעורבות קהילתית. בנוסף, הוא בעל תארי MCSD ו-MCPD המעידים על יכולותיו המקצועיות והטכניות בפיתוח מגוון אפלקיציות בסביבת דוט נט.

ניתן למצוא את ג'סטין-יוסף אנג'ל בפורומים ואתרים ישראליים בנושא דוט נט ובקבוצות המשתמשים של מיקרוסופט.

 

רשימת מאמרים מעודכנת:

רשימת נושאים, List of Topics:


ארכיטקטורה (5)

עברית, Hebrew, 20/10/2006

Programmatically access an ASP.Net MasterPage inside a Page

«
פתח מאמר מלא בחלון חדש

שאלה:

לא ניתן לשתף באופן ישיר משתנים בין MasterPage והדפים שמתמשים בו(כלומר לגשת מדף X למשתנה שנמצא ב - MasterPage שלו),
יש כל מיני חלטורות כאלו (לדוגמה לשתף עם Session או כל מיני דברים מסובכים), האם מישהו מכיר פתרון קל, נוח ויעיל לנושא

תשובה:

הבעיה הראשונה היא דווקא בעיה מאוד מעניינת ומאוד נפוצה - עבודה מול MasterPage מתוך הדף (Page) שלנו.

נחשוף מאפיין  (גם באנגלית: Property) מתוך ה-MasterPage שיאפשר לשנות את הטקסט של ה-Label:

        public string HeadlineText

        {

            get

            {

                EnsureChildControls();

                return lblHeadline.Text;

            }

            set

            {

                EnsureChildControls();

                lblHeadline.Text = value;

            }

        }

הדף שלנו (Content2.aspx) נמיר את ה-MasterPage שלו לטיפוס MasterPage שלנו ואז ניגש למאפיין.

        public partial class Content2 : System.Web.UI.Page

        {

            protected void Page_Load(object sender, EventArgs e)

            {

                MasterPage myMasterPage = (MasterPage)this.Master;

                myMasterPage.HeadlineText = "www.JustinAngel.Net";

            }

        }

 

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 20/10/2006

General Search screens when working with 3Tiers Architecture

«
פתח מאמר מלא בחלון חדש

שאלה:

רציתי לדעת מה הדרך הנכונה יותר מבחינת ארכיטקטורה להריץ שאילתות דינמיות במערכת מבוססת שכבות ( Business logic ו -Data access ) כלומר,
אם יש ממשק משתמש בעל כמה שדות שונים וברצוני להריץ שאילתה אך ורק עם אותם שדות שמולאו מבלי להחזיק את משפט הSQL כתוב בקוד.

 

תשובה:

שאילתות Find הן אכן נושא מסובך. מסכי חיפוש כאלו באמת מאתגרים ובוחנים את הכוח של הארכיטקטורה שלנו.

דבר ראשון בנושא קבלת "החלטות ארכיטקטורה נכונות" צריך לדעת מה הארכיטקטורה הנוכחית הרי נושא כמו שאילתות Find למיניהן לא תקבע לנו את הארכיטקטורה.

    public static Cow[] FindAllWithTheseProperties(string Name, decimal? ID,

                            DateTime? BetweenBirthDate, DateTime? AndThisBirthDate)

        {

            List<ICriterion> Crit = new List<ICriterion>();

 

 

            if (ID != null)

                Crit.Add(Expression.Eq("Id", ID));

 

            if (BetweenBirthDate != null)

                    Crit.Add(Expression.Between("BirthDate", BetweenBirthDate,AndThisBirthDate));

 

 

            List<Order> order = new List<Order>();

            order.Add(Order.Desc("FirstName"));

            order.Add(Order.Desc("Id"));

 

 

            return ((Cow[])(ActiveRecordBase.FindAll(typeof(Cow), order.ToArray(), Crit.ToArray())));

        }

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 20/10/2006

MasterPage causes CrossPagePostBack to stop working

«
פתח מאמר מלא בחלון חדש

הפתרון הנכון במקרה הזה הוא עבודה עם מאפיינים. נגיד ויש לנו טופס Content1.aspx שיש בו כפתור ואנחנו רוצים לגלות מה הטקסט של הכפתור בדף Content2.aspx שאליו נבצע Cross Page PostBack. ברמת Content1 נחשוף מאפיין שיציג את הטקסט של הכפתור שאותה ינצל Content1.

 

        public partial class Content1 : System.Web.UI.Page

        {

            protected void Page_Load(object sender, EventArgs e)

            {

            }

            public string ButtonText

            {

                get

                {

                    return Button1.Text;

                }

            }

        }

בטעינה ב-Content2 נבדוק שבאמת מדובר ב-Cross Page PostBack ואם כן ניקח את הדף הקודם ונמיר אותו לסוג Content1 ובכך נקבל גישה למאפיין החדש שלנו.

        public partial class Content2 : BasePage

        {

            protected void Page_Load(object sender, EventArgs e)

            {

                if (this.PreviousPage != null)

                {

                    Content1 myPreviousPage = (Content1)PreviousPage;

                    Reponse.Write(myPreviousPage.ButtonText);
                }
            }
        }

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 10/06/2006

The difference between MVC and 3Tier Architecture

«
פתח מאמר מלא בחלון חדש

שאלה: מה ההבדל בין ארכיטקטורת MVC לבין ארכיטקטורת 3Tier?

תשובה:

3Tier או כל ארכיטקטורת שכבות אחרת מדברת על "יש לי פרוייקט א' שתלוי בפרוייקט ב' שתלוי בפרוייקט ג'" וממשיך עד תלוי בפרוייקט X.
MVC מסתמכים הרבה יותר על חלוקה לוגית של אחריות ושל הפרדת "מי מדבר עם מי".

        protected void btnCreateCow_Click(object sender, EventArgs e)

        {

            Cow myNewCow = new Cow();

            myNewCow.Name = tbxCowName.Text;

            myNewCow.Meadow = Meadow.Find(BLHelper.SelectIndexToId(ddlMedows.SelectedIndex));

            myNewCow.Create();

        }

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 23/06/2005

תרגיל בארכיקטורה - תיאוריה בחסות האקדח והמציאות שלי

«
פתח מאמר מלא בחלון חדש

איך הייתם ניגשים לממש שאלה כזו מבחינת האפיון וגם תכנותית (.NET)?

1. שתי ישויות - CONTACT , CONTACT-GROUP  (לטובת EMAIL)

2. CONTACT-GROUP יכולה להכיל גם CONTACT וגם CONTACT-GROUP

3. CONTACT יכול להיות במספר CONTACT-GROUPS או באף אחת

4. יש לאפין ולכתוב תכנה המאפשרת
   א. יצירת CONTACT  ו CONTACT-GROUP
   ב. הוספת CONTACT ל CONTACT-GROUP
   ג. מחיקת CONTACT מ CONTACT-GROUP
   ד. הדפסת כל ה CONTACTS בתצורה עצית
   ה. מיון CONTACTS עפ"י שם

פתח מאמר מלא בחלון חדש

כללי (5)

עברית, Hebrew, 20/11/2007

Development machine recommended specification

«
פתח מאמר מלא בחלון חדש

שאלה:

אני לפני רכישת מחשב חדש,
והשאלה אליכם היא בעצם על איזו קונפיגורציה אתם ממליצים מנסיונכם להרצת ויז'ואל סטודיו 2005 בזריזות (מעבד, זכרונות, דיסקים) ובנוחות (מסך, אולי אפילו מקלדת ועכבר ספציפיים עם קיצורים מיוחדים?)

תשובה:

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

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 26/09/2006

How to become a great .Net developer

«
פתח מאמר מלא בחלון חדש

  שאלה:  איך להיות מתכנת חזק?
תשובה:

אין רשימת נושאים אחידה שניתן לתת לתכנת דוט נט כדי שהוא יהפוך ל"תכנת חזק".
כמות הנושאים הקיימת בדוט נט היא באזור ה-20,000 פלוס מינוס. יש בפריימוורק 12,000 מחלקות כיום ועוד אלפי נושאים שלא נכללים כחלק מהפריימוורק (Application blocks, presistence, testing, ארכיטוקטורה וכיו"ב).

בעיניי, "תכנת חזק" הוא לא תכנת שיודע הכל או שיש לו ניסיון בהכל.
אלא זה תכנת שבא עם הגישה הנכונה.
גישה של תמיד ללמוד, של תמיד להיות מוכן לבצע השלמת ידע, של תמיד להישאר מעודכן.

עברית, Hebrew, 20/05/2006

מבחני ותעודות הסמכת מפתחים של מיקרוסופט

«
פתח מאמר מלא בחלון חדש

אני תומך גדול בכך שתעשיית התוכנה תקבע לעצמה תקנים בתחום ההדרכה.

תעשיית התוכנה צריכה לעשות לעצמה רגולציה בהוכחת ידע המינימלי הנדרש.

סטנדרטיים של הוכחת ידע מינימליים צריכים להתקיים ולבוא מתוך התעשייה ולא מהאקדמיה. חובה שתהיה אבן-בוחן שתאפשר למצוא ולהבדיל בין בעלי הידע והניסיון הרלוונטיים מבין חסרי הידע וחסרי הניסיון.

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

מבחני הסמכה מקצועיים הם האבן-בוחן הזו שהתעשייה צריכה באופן נואש.

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 04/02/2006

ד"ר דוט נט - ביקורת על ספר מצויין חדש בעברית

«
פתח מאמר מלא בחלון חדש

"פיתוח אפליקציות שרת-לקוח בשפת C# .Net מאת ד"ר דוט נט, ASP.Net & Xml Web Services" (מהדורה ראשונה, 2006) מאת יוסף בלאן הינו ספר חדש על דוט נט. היחוד האמיתי של הספר הזה הוא שהסופר ישראלי, הספר נכתב בישראל ופורסם במקור בעברית. בתור ספר שמקורו בתרבות הישראלית יש לו באמת גישה שפונה הרבה יותר לקהל הישראלי. המנטליות הישראלית אומרת ככה "אם אני משקיע במשהו את הזמן שלי, אני מצפה לקבל את התמורה המקסימלית. בנוסף, אני לומד הכי טוב מדוגמאות ולא מדיבורים אקדמיים".

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

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 23/09/2005

שאלות מראיונות עבודה בדוט נט - האם יש לך מה שדרוש?

«
פתח מאמר מלא בחלון חדש

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

פתח מאמר מלא בחלון חדש

.Net Development (12)

עברית, Hebrew, 19/11/2007

Obfuscation is a myth

«
פתח מאמר מלא בחלון חדש

שאלה:

האם קיימת תוכנת obfuscator טובה ככה שלא יהיה ניתן לקרוא בכלל את הקוד של התוכנה שלי?

תשובה:

אני לא מאמין שקיים כזה דבר.

לא ניתן ליצור Obfuscation טוב לדוט נט.

אם לסכם את העניין - לא ניתן להצפין MSIL בצורה חד כיוונית.
זה בדיוק הנקודה - בסופו של דבר ה-CLR עדיין חייב להריץ משהו.
אם ה-MSIL מוצפן בצורה חד כיוונית -ה-CLR לא מריץ קוד ואז למרות ש"ניצחת" והצפנת את התוכנה באופן סופי - אין לך שום תוכנה להריץ.

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 14/11/2007

Writing an Excel File

«
פתח מאמר מלא בחלון חדש

שאלה:

איךאפשר  ליצור קובץ בשם DestPath="c:\1.xls" ולשים ב A1 ערך 20 וב A2 ערך 30?

תשובה:

יש הרבה דרכים לעבוד עם קבצי אקסל בדוט נט.

image

אחת מהן היא להעמיד פנים שאנחנו יוצרים גליון אקסל.
לאקסל יש תכונה מאוד מעניינת - הוא יכול לטעון קובץ HTML לכל דבר ולהציג אותו כקובץ אקסל.

אז בואו נכתוב טבלה <table> ב-HTML, נשמור אותה לקובץ עם סיומת XLS ונראה שאקסל מרנדר אותה.
אבל רגע, אנחנו תכנתי דוט נט - אנחנו לא מדפיסים HTML בעצמנו, יש לנו Server-side controls בשביל זה!
אז ניצור פקד Table של ASP.Net ואותה נשמור לקובץ.

            // render to string

            StringBuilder sb = new StringBuilder();

            using (StringWriter tw = new StringWriter(sb))

            using (HtmlTextWriter hw = new HtmlTextWriter(tw))

            {

                myTable.RenderControl(hw);

            }

 

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 17/07/2007

How to secure an application

«
פתח מאמר מלא בחלון חדש

שאלה:

טיפים וטריקים לאבטחת אתר, ממה צריך להיזהר ועל מה לשים דגש.

1. כמובן SQL INJECTION
2. עוגיות (שניתן יהיה לקרוא אותן רק מהשרת)
3. לא לאפשר להעלות קבצים עם סקריפטים למינהם.
4. אני יודעת שאפשר דרך הלוגים של האתר לזהות טרולים למינהם ש"אינם חפצים ביקר" האתר, איך מזהים אותם?

--------מה עוד?

תשובה:

אין גבול לאבטחה.

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

דוגמה שאני מאוד אוהב להראות היא של Rocky שהוא Security MVP והוא מדגים איך דרך פרצה של Sql Injection באפליקציה דוט נטית, אפשר להשתמש בפרצת FTP במסד נתונים סיקוול סרבר, כדי להעלות אסמבלי חדשה לאפליקצה הדוט נטית שלנו שמדווחת לפורץ על כל מה שקורא באפליקציה.
Assembly Hijacking

בארץ יש קבוצת Net Security. שפעם בחודש נפגשים וסוקרים איום אחר.
ניתן לראות העתק של כל המצגות מאז שהקבוצה התחילה להיפגש ובהחלט מומלץ לקרוא את המצגות ולהגיע לפגישות.
צירפתי את סלייד מספר 8 מהמצגת של נימרוד לוריה מהפגישה האחרונה של הקבוצה שממחישה כמה מהפרצות היותר מוכרות בתחום ה-web.

WebAttackVectors


פתח מאמר מלא בחלון חדש
עברית, Hebrew, 13/06/2007

Refactoring code for code review

«
פתח מאמר מלא בחלון חדש

שאלה:

יש לי מערך של קבציםומערך של אובייקטים המכיל ערך ישן וערך חדש.
אני צריכה להחליף בכל הקבצים את הערך הישן לערך החדש.
אני עשיתי את זה כך / אשמח לשמוע ביקורת לכאן ולכאן או אפשרות לשיפור הביצועים.

מה דעתכם? האם יש דרך לשפר?

    public static void Main()

    {

        //רשימה של השמות הישנים והשמות החדשים על מנת להחליף את הטקסט

        List<manageFiles> mf = new List<manageFiles>();

        mf.Add(new manageFiles("replace me", "with me"));

 

        //רשימת הקבצים החדשה

        List<string> filesUrl = new List<string>();

        filesUrl.Add("myFile1.txt");

        filesUrl.Add("myFile2.txt");

        filesUrl.Add("myFile3.txt");

 

        //מילוי הנתונים

        foreach (string strFile in filesUrl)

        {

            string tochen = "";

            foreach (manageFiles manf in mf)

            {

                string path = HttpContext.Current.Server.MapPath("../../files/") + strFile;

                Regex rg = new Regex(manf.OldName);

                using (StreamReader sr = new StreamReader(path))

                {

                    tochen = sr.ReadToEnd();

                }

                //החלפת הערכים

                tochen = rg.Replace(tochen, manf.NewName);

                //מחיקת הקובץ הישן

                if (File.Exists(path))

                {

                    File.Delete(path);

                }

                using (StreamWriter sw = new StreamWriter(path, true, System.Text.Encoding.UTF8))

                {

                    sw.Write(tochen);

                }

            }

        }

    }

 

תשובה:

יש מקום לשיפור ונעבור על זה ביחד דרך כללי Refactoring.

קודם נגדיר מילונית (או אבטיחית) מה זה החיה המוזרה הזאת  Refactoring.

Refactoring זה שינוי הקוד הקיים, כך שהוא מבצע בדיוק מה שהוא ביצע קודם, רק כתוב בצורה שונה.

כלומר, הפונקציונליות לא תשתנה, אבל הקוד עצמו ישתנה.

מה אנחנו מנסים להשיג ב-Refactoring? קריאות קוד כדי שמתכנתים יוכלו להבין את הקוד, משהו שנקרא חלוקת אחריות נכונה שגם מסתבר שזאת חיה פרוותית שעוזרת במערכות, ובכלל ננסה להביא את המערכת למצב שבה היא ברת תחזוקה.

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 19/03/2007

An attempt was made to load a program with an incorrect format.

«
פתח מאמר מלא בחלון חדש

The informative error message:

An unhandled exception of type 'System.BadImageFormatException' occurred in .dll

Additional information: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 06/01/2007

log4net logging in multiple projects at the same solution

«
פתח מאמר מלא בחלון חדש

שאלה:

שלום שלום לכולם,
אני בדיוק מקנפג באפליקציה כלשהי מערכת רישום אירועים (LOGGING), ספציפית
אני משתמש ב-LOG4NET אבל השאלות שעלו במוחי הן כלליות יותר.

1. האם מבחינה טכנית מודולים חיצוניים יוכלו לגשת ישירות להגדרות לWEB.CONFIG?
למשך דרך CONFIGURATIONMANAGER?
2. האם זה נכון לטעמכם מבחינת הנדסת תוכנה שמודולים חיצונים (שיכולים לשמש אתרים אחרים גם)
תלויים בקובץ קונפיג של אתר ספציפי ומניחים הנחות לגביו?
3. אינני רוצה שכל קוד באתר שרוצה לרשום אירוע יצטרך לאתחל מופע של מודול הרישום, הייתי רוצה שיהיה
מקום מרכזי (סטטי) שדרכו עושים את כל רישום האירועים. איפה וכיצד הכי נכון להגדיר מקום מרכזי כזה?

 

תשובה:

ב-log4net צריך ליצור מחלקה סטטית עם מופע סטטי של הלוגר לפי קובץ הקונפיגיורציה.

namespace Common

{

    public static class Log

    {

        public static ILog logger = log4net.LogManager.GetLogger(typeof(Log));

 

        private static ILog log

        {

            get

            {

                return logger;

            }

        }

 

        public static void Error(string message, System.Exception e)

        {

            if (log.IsErrorEnabled)

                log.Error(ReturnCallStrackInformation(message), e);

        }

    }

}

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 08/12/2006

Refactoring Code-behind to Static Methods and Properties

«
פתח מאמר מלא בחלון חדש

שאלה:

יש לי את הקוד הבא ואני בטוח שיש דרך יותר טובה ונקייה לכתוב אותו, למישהו יש רעיונות?<<>

            // טבלא ראשית

            Table MainTbl = new Table();

 

            // הגדרות עבור טבלא

            MainTbl.CellPadding = 0;

            MainTbl.CellSpacing = 0;

            MainTbl.Width = Unit.Parse("456");

 

 

            TableRow MainRow = new TableRow();

            MainTbl.Rows.Add(MainRow);

            // טור קו שמאלי של טבלא ראשית

            TableCell MainLineLeftCell = new TableCell();

            MainRow.Cells.Add(MainLineLeftCell);

            MainLineLeftCell.Width = Unit.Parse("1px");

            MainLineLeftCell.Height = Unit.Parse("100%");

            MainLineLeftCell.Style.Add("background-image", "url(simages/FramePixel.gif)");

 

תשובה:

בלי לשנות את הפתרון של שימוש בטבלה (במעבר ל-GridView או ל-DataList) בהחלט יש כאן מקום לשיפור הפתרון המוצא.

הפתרון הוא שימוש במתודות סטטיות ואף במאפיינים סטטיים כדי להכיל את כל ההגדרות המעניינות האלו ולרכז קוד.

נתחיל ביחד בתהליך שנקרא Refactoring. מילת המפתח כאן היא Refactoring.
הכוונה היא: שינוי הקוד בלי לשנות את הפונקציונליות שלו.
כלומר, אנחנו יודעים שהקוד עובד אבל עכשיו הגיע הזמן להפוך אותו ליותר קריא וסה"כ יותר "נכון".

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 19/11/2006

HttpWebRequest and HttpWebResponse with non-english content

«
פתח מאמר מלא בחלון חדש

שאלה:

אני משתמש בStreamReader כדי לקרוא את התוכן של דף Web. כלומר:

        Dim dataStream As Stream = m_response.GetResponseStream()
        Using reader As New StreamReader(dataStream, Text.Encoding.Default)
            Return reader.ReadToEnd()
        End Using

(הm_response הוא מסוג HttpWebResponse.)
הבעיה היא שכל עוד לא קראתי את תוכן הדף אני לא יכול לדעת באיזה קידוד הוא נשלח.
האם קיימת דרך לגלות באיזה קידוד הדף נמצא ולהמיר בהתאם?

 

תשובה:

תשובתו של דניאל כץ.

מה שאנחנו למעשה רוצים לעשות כאן זה לקרוא את המידע עד הסוף מה-StreamReader ורק לאחר מכן לחפש בתוך התוכן ה-HTMLי ולראות מהו הקידוד של המסמך.

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 22/09/2006

Strong-named Assemblies Advanced questions

«
פתח מאמר מלא בחלון חדש

מה המשמעות של מפתח SNK שיוצרים Strong-Named Assembly, ומה המשמעות של המחרוזת שהוא מייצר?
האם מומלץ להכניס את קובץ ה snk לתוך ה solution?
ראיתי שבמאפיינים של הפרוייקט יש חוצץ signing או משהו בסגנון ושם גם אפשר לציין את קובץ ה snk ע"י GUI ולא ע"י קוד, מה ההבדל?
האם יש דרך אחרת מלבד זו שציינתי להזין את ה public key? לדוגמא לרשום ישירות את ה key במקום להפנות לקובץ?

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 12/11/2005

Assemblies ו-Strong named Assemblies - המדריך למדוע וכיצד

«
פתח מאמר מלא בחלון חדש

כולנו עובדים עם Assemblies (להלן: אסמבליס ברבים, אסמבלי ביחיד). גם אם אתמול התחלתם לעבוד בדוט נט ובניתם רק אפליקציה לדוגמה - אתם עבדתם עם אסמבלי.  בואו כולנו נפתח עכשיו Visual studio, נבחר לפתוח פרוייקט חדש ונקמפל (נעשה build). מה שכרגע קרה זה שהקומפיילר בנה לכם אסמבלי. אם בנינו אפליקציית web אז קיבלנו בספריית ה-bin קובץ myProject.dll, ואם בנינו אפליקציית winform/console נקבל בספריית ה-bin קובץ myProject.exe.

 

Assembly2.gif

 

Assembly6.gif

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 29/07/2005

תוכנות מועילות שחובה לכל מתכנת

«
פתח מאמר מלא בחלון חדש

החלטתי לכתוב רשימה של כלים שאני חושב שחובה שיהיו לכל מפתח בדוט

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 23/06/2005

אורקל ודוט נט - המציאות מוזרה מכל דמיון

«
פתח מאמר מלא בחלון חדש

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

המאמר הזה מיועד בעיקרו לאלו שעובדים עם אורקל ונתקלו בבעיות נפוצות.

פתח מאמר מלא בחלון חדש

.Net Framework (9)

עברית, Hebrew, 15/10/2007

Dividing operators are not what you thought

«
פתח מאמר מלא בחלון חדש

שאלה:

אני רוצה לחלק 5/3 ולקבל את הערך המלא כלומר גם מה שמאחורי הנקודה העשרונית אפשר אולי להראות לי איך?

 

תשובה:

בואו נראה איך נראית חלוקה רגילה של למשל 6 ו-3.

            int result = 6/3;

            Console.WriteLine(result);

image

כצפוי, התשובה היא 2.

עכשיו בואו נשתמש באותה תבנית ונחלק 5 ב-3.

            int intResult = 5/3;

            Console.WriteLine(intResult);

image

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 18/06/2007

Generics and Anonymous delegates on List With LINQ

«
פתח מאמר מלא בחלון חדש

שאלה:

ב-List<T> Collection יש כל מיני Methods שמקבלות כל מיני פרמטרים ג'נאריים.

List<T>.ConvertAll מקבלת משהו בשם <Converter<T.

List<T>.Exists, List<T>.RemoveAll, List<T>.TrueForAll ו-List<T>.FindXXX מקבלים משהו בשם <Predicate<T.

List<T>.Sort מקבל <IComprar<T.

List<T>.ForEach מקבל <Action<T.

מה זה כל ה-Methods האלו? מה המחלקות האלו? צריך לעשות Inheritance מהן? שמעתי שאפשר לעשות משהו בשם Anonymous Methods? מה הקשר ל-Generics?
קראתי את התיעוד ב-MSDN, אבל הוא מעיק והדוגמאות לא ברורות...

 

תשובה:

זאת שאלה מצויינת שמראה את ההבדל בין 1.1 #C לבין 2.0 #C לבין 3.5 #C.

בואו נתחיל בליצור מודל בעיה - יש לנו אוסף של בקבוקי וויסקי.

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 04/06/2007

Exposing a Read-only collection from a class

«
פתח מאמר מלא בחלון חדש

שאלה:

בנינו מחלקה שמכילה כמה סוגים של Collections ואנחנו חושפים אותם החוצה ב-Properties.
ה-Collections האלו הם Private למחלקה עצמה, והחוצה אנחנו רוצים לחשוף רק אפשרויות לעבור עליהם בקריאה בלבד.
ההוספה והמחיקה לאוספים הפנימיים הוא תוצאה של אלגוריתמים פנימיים, למשל אנחנו רוצים שיהיה אפשר להוסיף רק דרך Add שלנו כדי שנוכל לעלות Events.
הבעיה היא שב-Get של ה-Property אנחנו מחזירים Reference Type ואפשר לשנות מחוץ למחלקה את ה-Collections בלי לעבור דרך האלגורתימים.
יש לזה פתרון בדוט נט?

 

תשובה:

בואו נבנה מחלקה לדוגמה שחושפת שלושה סוגי אוספים: (גם באנגלית: Collections)

1. ArrayList - שהשתמנו בדוט נט 1.1

2. List ג'נארי של דוט נט 2.0

3. StringCollection  - שזה Collection יעודי שעבר אופטיזמציה לטפל רק במחרוזות

מה מסתבר? עם הפריימוורק מגיעים סוגי אוספים שהם קריאה בלבד.
האוספים האלו הם עותקים שרק אפשר לעבור להם על התוכן, אבל לא ניתן להוסיף, למחוק או בכלל לשנות אותם.

נשנה את המאפיינים שלנו שיחזירו אוספים לקריאה בלבד.

        private List<SomeClass> _dotNet20Collection = new List<SomeClass>();

        public ReadOnlyCollection<SomeClass> DotNet20Collection

        {

            get { return _dotNet20Collection.AsReadOnly(); }

        }

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 01/06/2007

Run a .Net application on specific runtime version

«
פתח מאמר מלא בחלון חדש

שאלה:

אני מעונין להוסיף קטע קוד שבודק איזו גרסה יש ל Framework‏ במחשב שמריץ אחת מהאפליקציות שלי.

אשמח לקבל דוגמא לקטע קוד ב C‏# שיוכל לזרוק Exception‏  ברגע שקוד שנוצר על VS2005‏ מנסה לרוץ על פלטפורמה שאיננה Framework 2‏ (למשל Framework 1.1)

תשובה:

בקובץ הקונפיגיורציה של האפליקציה שלך יש אלמנט מעניין שלרוב לא מזכירים בשם <startup>.

באלמנט הזה ניתן לפרט אלמנט <supportedRuntime> עם גירסת הפריימוורק שבקונטקסט שלה תרוץ התוכנה שלנו.

הנה דוגמה של האלמנט:  

    <?xml version="1.0" encoding="utf-8" ?>

    <configuration>

        <startup>

            <supportedRuntime version="v1.1.4322"/>

            <supportedRuntime version="v1.0.3705"/>

            <supportedRuntime version="v2.0.50727"/>

        </startup>

    </configuration>

 

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 21/11/2006

Iterate over a collection and remove items from it

«
פתח מאמר מלא בחלון חדש

שאלה:

יש לי פקד CheckBoxList עם מס' פריטים בתוכו.
אני מעוניין שבאירוע מסויים, כמו למשל CLICK, הפריטים ב-CheckBoxList שלא ניבחרו על ידי המשתמש, יימחקו. כתבתי את הקוד הבא:

           for(int i = 1;i<CheckBoxList1.Items.Count;i++)
            {
                if(!CheckBoxList1.Items[i].Selected)
                {
                    CheckBoxList1.Items.Remove(CheckBoxList1.Items[i]);
                    Label1.Text = CheckBoxList1.Items.Count.ToString();
                }

שאני מריץ לולאת for, אני מקבל כל מיני התנהגויות מוזרות וזה בכלל לא עושה מה שרציתי. איך אפשר לעשות כזה דבר? 

 

תשובה:

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

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 21/11/2006

Class Pointers in .Net 101 (with Tree Collection)

«
פתח מאמר מלא בחלון חדש

שאלה:

אני מנסה להבין את איך דוט נט עובדת עם מחלקות שמכילות הצבעות למחלקות אחרות מאותו סוג?

למשל, אני רוצה לבנות עץ היררכי של אזרחי מדינת ישראל כאשר מכל הורה ניתן לנווט לילדים ומכל ילד ניתן לנווט בחזרה להורים.

יש מושג "מצביעים" או תחליף להם בvb.net?האם זו בכלל הגישה הנכונה?

 

תשובה:

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

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 08/04/2006

המדריך המקיף ל-System.IO - כוננים, ספריות, קבצים וצופים, היאח!

«
פתח מאמר מלא בחלון חדש

במאמר הבא נבנה ביחד אפליקציה שתנצל את היכולות של System.IO ובעיקר עבודה עם כוננים, ספריות, קבצים כיווץ ו-Isolated Storage.

הרעיון מאחורי ה-System.IO Namespace הוא לרכז את כל העבודה מול Streams ולהציע ספרייה מכובדת שמאפשרת עבודה מול ההארד-דיסק.

נתחיל את הפרוייקט שלנו ונפתח Windows application חדש בשם WinSystemIO. בטופס נוסיף Multiline Textbox בשם tbxOutput שלתוכה נדפיס את המידע שלנו במהלך הפרוייקט ונוסיף כפתור שינקה את תיבת הטקסט. נציין שאין שום חשיבות לכך שיצרנו פרוייקט חלונאי ולא פרוייקט ASP.Net היות ו-System.IO פועלת בשניהם אותו דבר.

במהלך המאמר נפתח את האפליקציה עד שנידע לעשות כל אחת מהפעולות הבאות:

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 04/02/2006

המדריך המלא ל-System.Net.Mail - רזי שליחת דוא"ל דרך דוט נט

«
פתח מאמר מלא בחלון חדש

System.Net.Mail הוא הגירסה בדוט נט 2.0 של System.Web.Mail. כן כן, שמתם לב להבדל - העבירו את זה Namespace משני.

במאמר זה נעבור על כל מה שיש לדעת על System.Net.Mail.

בואו נתחיל מהתחלה. בכל שרת אינטרנט של מיקרוסופט מותקן IIS שזה ה-Internet information services. שמתם לב שהדגשתי את ה-s ב-services? כן, ה-IIS המיקרוסופטי מכיל מספר שירותים אפשריים ולא רק את היכולת להגיש דפי אינטרנט. שלושת השירותים העיקריים שה-IIS מציע הם: הגשת דפי אינטרנט, גישת FTP ושרת SMTP. כולנו מכירים את יכולת הגשת דפי אינטרנט וכולנו פחות או יותר יודעים מה זה FTP ("נו, אתה יודע, זה כמו העתקת קבצים רגילה רק איטי ומתסכל"). אבל מה זה ה-SMTP הזה שהזכרתי?

בפשטות ובקצרה, שרת ה-SMTP המובנה ב-IIS הוא שירות מוכר, ידוע ואמין שמאפשר שליחת דוא"ל. במאמר זה אנחנו נלמד כיצד ניתן לנצל את השירות הזה דרך דוט נט בכדי לשלוח דוא"ל מתוך הישומיים שלנו.

  MailMessage myMessage = new MailMessage();

 

  myMessage.To.Add(new MailAddress("J@justinAngel.net", "Justin Angel"));

  myMessage.From = new MailAddress("mail@JustinAngel.net");

 

  myMessage.Subject = "simple mail";

  myMessage.Body = "hello justin, how are you today?";

 

  SmtpClient mySmtp = new SmtpClient();

  mySmtp.Host = "127.0.0.1";

  mySmtp.Port = 25;

 

  mySmtp.Send(myMessage);

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 29/07/2005

Struct ו-Class -ההבדלים והכוח הטמון בשוני ביניהם

«
פתח מאמר מלא בחלון חדש

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

public class ClassName

{

// ...

}

אז שאנחנו עובדים עם מבנה זה יראה ככה:

public struct StructName

{

// ...

}

הבדל ענק נכון? אז אתם, שנתקלים במושג הזה פעם ראשונה או שנתקלתם בו בעבר, כנראה חושבים שהוא מיותר לחלוטין. סתם עוד פדנטיות שמתכנתי הסיפיפי האלו הכניסו לנו לשפה כי הייתה להם חרדת נטישה. אז אני בא ואומר שזה לא המצב. במאמר הזה נראה מה באמת ההבדלים בין מבנה למחלקה,  ולא רק מה ההבדלים - אלה נראה איזה כוח עצום טמון במבנים.

פתח מאמר מלא בחלון חדש

ASP.Net (12)

עברית, Hebrew, 21/11/2007

Session State storage hardcore explanation

«
פתח מאמר מלא בחלון חדש

שאלה:

יש לי מערכת די גדולה, ואני משתמשת בה בSessions.

הבעיה היא שה Session מתנהג לי בצורה מאוד לא יציבה, למרות הגדרת הtimeOut ב web.config הוא פג אחרי זמן קצר מאוד של חוסר תזוזה במערכת. וגם- אם אני עושה איזו שהיא פעולה מחוץ למערכת, כמו פעולה על FTP (העברת קבצים, למשל) - כשאני מסיימת את הפעולה הזאת ה sessions פשוט פגים.

 

תשובה:

Sessions מתאפסים מהרבה מאוד סיבות.
כמה לדוגמה:
1. הגעת לגבול העליון מבחינת זכרון שמוקצה ל-Sessions.
2. ה-AppDomain עצמו של השרת אותחל.
3. ה-Session עצמו פג תוקף ביחס לקריטריונים של השרת.

ויש עוד הרבה סיבות.

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 15/07/2007

Authentication and Impersonation flow in ASP.Net and Sql Server

«
פתח מאמר מלא בחלון חדש

שאלה:

באפליקציית ASP.Net החיבור ל-DB לא עובד כשמנסים מרחוק, להבדיל מכאשר מנסים לוקלית (F5). למטה יש את הודעת השגיאה: 

  Cannot open database "pubs" requested by the login. The login failed.
  Login failed for user 'MOSHE-F91B90F39\ASPNET'.

תשובה:

לפי מה שאתה מתאר סביר להניח שמדובר ב-Impersnation עם Windows Authentcation של ASP.Net בשילוב עם Windows Authentication של סיקוול סרבר.

ל-ASP.Net יש שלושה אפשרויות לזיהוי משתמשים:

image

סיקוול סרבר מאפשר שתי אפשרויות לזיהוי משתמשים:

image

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 21/10/2006

ViewState or PostBack data isn't being loaded

«
פתח מאמר מלא בחלון חדש

שאלה:

הוספתי למסך כפתור, שמבצע פוסטבק,
במתודת ה Click של הכפתור (בשרת), אני ניגש ל SelectedValue של ה DropDownList בקונטרול,
אך תמיד אני מקבל את הערך הראשון ברשימה, ולא באמת את הערך שהגולש בחר.  מדוע ?

תשובה:

אי-טעינת מידע ViewState או PostBack נגרמת ב-99% מהמקרים ע"י דבר אחד: ה-ID של הפקד שאמור לקלוט את הערכים אינו קבוע ומשתנה בין PostBackים.

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 21/10/2006

Access controls inside Custom/User Controls

«
פתח מאמר מלא בחלון חדש

שאלה:

יש לי User Control שמכיל DropDownList, ויש לי דף שמכיל אותו.
שמתי לב שה Page_Load של המסך רץ לפני ה Page_Load של הקונטרול,
לכן אני לא יכול לאתחל את הקונטרול ב Page_Load של המסך, אלא רק בשלב מאוחר יותר,
למשל OnPreRender של המסך.
האם הבנתי נכון, וכך עושים זאת ?

תשובה:

כ-כלל אצבע, מה שעושים במצבים כאלו שרוצים לגשת לפקדים של Custom Control או User Control שיתכן שקיימים ויתכן שאינם קיימים הם לדאוג שהפקדים קיימים. בתוך כל Property שאתה חושף לפני שאתה ניגש לפקדים עצמם תצטרך לקרוא למתודה EnsureControlsCreated. זאת מתודה שנמצאת בשימוש נרחב בכל מקום שבו כותבים פקדים באמת כדי לוודא שקיימים פקדים לפני שניגשים אליהם מתוך Properties למיניהן שאינן קשורות בישירין לסדר האירועים הדיפולטי של הדף.

        public string HeadlineText

        {

            get

            {

                EnsureChildControls();

                return lblHeadline.Text;

            }

            set

            {

                EnsureChildControls();

                lblHeadline.Text = value;

            }

        }

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 06/10/2006

Overhead of using MasterPages and UserControls in ASP.Net

«
פתח מאמר מלא בחלון חדש

שאלה: האם שימוש ב-UserControls וב-MasterPages (שהוא למעשה UserControl) גורר פגיעה כלשהי בביצועים?

תשובה:

בדוט נט 2.0 יש אפשרות חדשה שהיא לבצע Precompile לכל האתר עצמו מה שלוקח את קבצי ה-ASPX וה-ASCX שבעבר נותחו רק עם פנייה לדף ומקפמל אותם למחלקות אמיתיות. את ה-Procompile הזה ניתן להגדיר בעת הפריסה של האפליקציה באמצעות Deploy Web Site של Visual Studio 2005 או ניתן להשתמש ב-aspnet_precompile.exe שמגיע עם הפריימוורק ומאפשר לקמפל אתר כאתר או לקמפל אתר לתוך תיקייה שתיפרס במועד מאוחר יותר.

עם ההצגה של מודל הקומפילציה של דוט נט 2.0 אין יותר הבדלים בין כתיבת ASPX/ASCX לכתיבת קוד מבחינת ביצועים.

פתח מאמר מלא בחלון חדש
עברית, Hebrew, 06/10/2006

Rendering HTML based on Client Browser

«
פתח מאמר מלא בחלון חדש

הקביעה של היכולות של הדפדפן שלך נקבעת ע"י הפריימוורק ובהתאם הרנדור.

בדוט נט 1.1 קיים אלמנט <browserCaps> שיושב ברמת ה-machine.config (למרות שגם ניתן לקבוע אותו ברמת ה-web.config) ומכיל את ההתאמה בין המאפיינים השונים של הדפדפן (בעיקר שמו ופילטרים נוספים המבוססים על כך) לבין היכולות של הדפדפן ביחס למה שהפריימוורק צריך לדעת (האם תומך בטבלאות, האם תומך ב-CSS, האם תומך ב-XML, האם תומך בג'אווה סקריפט, האם תומך בעוגיות וכיו"ב).

בדוט נט 2.0 הקונספט הזה השתנה עקב קיומם של כמה אלפי דפדפנים בימינו. מה שנהוג כיום הוא ליצור קבצי browser שמופקים אוטומטית מאתר מיקרוסופט.

    <browserCaps>

        <case match="^Mozilla/5\.0 \([^)]*\) (Gecko/[-\d]+)(?'VendorProductToken'

   (?'type'[^/\d]*)([\d]*)/(?'version'(?'major'\d+)(?'minor'\.\d+)(?'letters'\w*)))?">

            browser=Gecko

            frames=true

            tables=true

            cookies=true

            javascript=true

            javaapplets=true

            ecmascriptversion=1.5

            w3cdomversion=1.0

            css1=true

            css2=true

            xml=t