DCSIMG
שלמה גולדברג (הרב דוטנט)
Sign in | Join | Help

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

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

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

פורסם בתאריך Jan 29 2012, 11:11 PM על ידי Shlomo

 

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

HTML5 - Table of Content

פורסם בתאריך Jan 25 2012, 10:58 AM על ידי Shlomo

 

כתבתי די הרבה על נושאים שונים של HTML5, וחשבתי לרכז את כולם.
 
בשונה ממדריכים אחרים שכתבתי, הפוסט הזה אינו מרוכז לפי סדר מסויים, אלא מגוון רחב של פיצ'רים שהסביבה נותנת.
 
אני מחלק את זה לשינויים ב - HTML, תוספות של CSS ופונקציונליות חדשה ב - JS - כמובן שישנם חידושים שחופפים ואפשר היה להצמיד אותם גם ל - CSS וגם ל - JS, אך מיקמתי אותם היכן שנראה לי יותר מתאים.
 
חשוב לשים לב שבחלק מהפוסטים יש כותרת של What new in IE8 וכדומה, אל דאגה - כאן שמתי אך ורק פוסטים של HTML5, כלומר שינויים של IE שמוגדרים מהתקן.
 
 
HTML
HTML5 - HTML Review - הסיבות למה כדאי לעבור ומה זה בכלל HTML5.
New Elements - הכרת האלמנטים החדשים.
Canvas - הכרת האלמנט שמאפשר לצייר על גבי המסך.
Generic elements - אלמנטים חדשים שהמפתחים ממציאים.
Audio - הכרת האלמנט המאפשר לנגן.
Video - הכרת האלמנט המאפשר להציג וידיאו
 
 
 
JS
The Modernizr - הכרת הספרייה המאפשרת לבדוק אלו תכונות נתמכות בדפדפן שרץ.
Worker - הכרת הדרך לעבודה אסינכרונית ב - JS.
Goelocation - כיצד לכתוב אפליקציות מבוססי מיקום.
Drag & Drop  - כיצד לגרור אלמנטים.
Selected text - כיצד נדע איזה טקסט המשתמש סימן.
Overlapping tags  - הצורה בה ה - JS יתייחס לאלמנטים שמקוננים.
Cross-Document messaging  - הדרך לתקשר בין חלונות פתוחים.
querySelector - כיצד נוכל לקבל את כל האלמנטים העומדים בתנאים מסויימים (כמו jQuery)
XDomain Request - כיצד אפשר להפעיל AJAX מול דומיין אחר.
online - offline - קבלת האירועים והמידע האם יש רשת או לא.
XML Http Request - שיפורים במנגנון AJAX
Dom Storage  - התחליף המעולה ל - Cookie
 
CSS
text-shadow - הגדרת צל לטקסט
background - השינויים בהגדרת רקע.
Media queries - כיצד לדעת מהי הסביבה בה אנחנו רצים (סלולר, מחשב, רזולוציה וכו')
Color - שינויים בצבעים.
Opacity - האפשרות לשקיפות.
border - היכולת לעגל פינות.
Content - כתיבה של טקסט בעזרת CSS
outline - עטיפת border לאלמנטים בלי לתפוס מקום פיזית.
focus selector - הכרת ה - selector שמשפיע על האלמנט שכרגע בפוקוס.
Namespace - הכרת הדרך להגדיר שמות מרחב ב - CSS.
 
 

X-UA-Compatible meta tag

פורסם בתאריך Jan 24 2012, 02:32 AM על ידי Shlomo

 

מהימים בהם התחלנו לקבל גרסאות חדשות של IE - קבלנו את היכולת להריץ את IE כאילו בגרסאות ישנות יותר וזאת בעזרת כלי הפיתוח של IE 
לחיצה על F12 - ושינוי ה - Document Mode.
 
ברור מאיליו שזה כלי נהדר למפתחים שיכולים לראות כיצד האתר ייראה בגרסאות שונות של IE (מעניין שאין יכולת כזאת בדפדפנים המתחרים).
 
 
מה שלא כל המפתחים יודעים הוא - שניתן "להכריח" את הדפדפן להציג את האתר ב - Document Mode שנבחר, נרצה לעשות זאת למשל אם אין לנו תקציב לדאוג שהאתר יראה כמו שצריך ב - IE9 ואנחנו רוצים להשאר בגרסה 8 של הדפדפן.
 
כל מה שצריך לעשות הוא להוסיף את תגית ה - meta הבאה:
 

<meta http-equiv="X-UA-Compatible" content="IE=8">

 
כשניתן לכתוב את הגרסאות השונות של IE או לחילופין לכתוב

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">

 
ובמקרה הזה הוא גם מתחשב במה שהוגדר ב - doctype (להרחבה בנושא)
 
 
נקודה חשובה, התגית הזו (ככל תגיות meta) צריכה לשבת בתוך ה - head. אבל אסור שיופיע תגית script או style לפניה - ה - meta חייב להיות ראשון אחרי תגית ה - title.
 
הסיבה לא ברורה לי - אבל אני יכול לנחש שרינדור הסקריפטים והעיצוב תלוים בתגית הזו, ולכן לאחר שהדפדפן קרא את העיצוב או את הסקריפט אין ביכולתו לשנות את ה - Document Mode
 
 
 במאמר המוסגר.
plug-in מעניין שראיתי הוא Google Crome Frame, לא בדקתי אותו אבל הוא מבטיח שגם אם מותקן IE6 הדפים ירונדרו במנוע של Chrome ויוצגו בכל האלמנטים ש - Chrome תומך.
במקרה זה יש לכתוב

<meta http-equiv="X-UA-Compatible" content="chrome=1">

center elements in html

פורסם בתאריך Jan 17 2012, 08:05 PM על ידי Shlomo

 

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

<center>

    .....

</center>

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

.center

{

    margin-left: auto;

    margin-right: auto;

    text-align: center;

}

 
אלמנט שיקבל את ה - class המתאים (center) ימורכז - כמובן שהוא צריך שיוגדר לו width כלשהו שקטן מגודל ה - container שלו.
 
כל זה יעבוד רק אם לא הגדרתם הגדרה מיוחדת ל - position, אחרת (למשל fixed, absolute) צריך לעשות טריק אחר.
 

#msg

{

    position: fixed;

    left:50%;

    margin-left:-225px;

    width: 450px;

}

 
הערך של margin-left צריך להיות חצי מהערך של width כך שבכל מקרה האלמנט ימורכז לאמצע המסך.

HTML5 - Canvas

פורסם בתאריך Jan 16 2012, 08:11 AM על ידי Shlomo
 
בהמשך לפוסטים על HTML5, הפעם נדבר על Canavs.
 
הקדמה:
בפוסט הראשון תיארתי מהו HTML5, וטענתי שזה לא הגרפיקות והאנימציות - אלא ה - API החדש, אבל כמובן שאי אפשר להתעלם מהיכולות של הגרפיקה, ולכן בפרק זה נכיר את הדרך כיצד לצייר ב - HTML5.
 
כמובן שאי אפשר במסגרת פוסט זה להכיר את היכולות המלאות, (וזה גם דורש המון מטמטיקה), ואני די בטוח שיהיו (או שיש) עטיפות שונות ליכולות ה - Canvas כדי להקל את הכתיבה, ולא לכתוב כל כך קרוב לברזלים, ובכל זאת נרצה לראות את הבסיס ואיך משתמשים בזה.
 
 
Canvas:
ה - Canvas הוא בד ציור המאפשר לנו לצייר עליו מה שנרצה ב - javascript, הוא מכיל את כל היכולות הבסיסיות של ציור כמו ריבוע עיגול קו וכדו', הוא מאפשר לנו להפעיל טרנספורמציות עליו כמו סיבוב, שכפול של אלמנטים, והוא מאפשר להגדיר שקיפות וגרדיאנטים של רקעים וכן הלאה.
 
מנגנון ה - Canvas הוא בזיכרון, כלומר - לאחר שציירנו ריבוע לא ניתן לשנות את צבע הקו - אפשר רק למחוק אותו (על ידי ציור ריבוע לבן מעליו) ולצייר מחדש.
 
נקודה נוספת, ה - Canvas מצייר פיקסלים, שינוי ברזולוציה של המסך יעוות את הציור כמו כל תמונה פיקסלית.
 
 
דוגמאות לשימוש ב - Canvas: (הדוגמאות יעבדו כמובן רק בדפדפנים תומכי Canvas)
 
 
איך מתחילים:
בקוד ה - HTML נוסיף אלמנט Canvas

<canvas id="can1" width="400" height="400"></canvas>

 
בקוד ה - js נקבל את האלמנט, נבקש את ה - Context המאפשר לצייר עליו.

onload = function () {

    var canvas = document.getElementById('can1');

    var ctx = canvas.getContext('2d');

}

 
לאחר קבלת ה - context ניתן להתחיל להשתמש בפונקציות שלו כדי לצייר.
 

var x = 0, y = 0, width = 100, height = 100;

ctx.fillRect(x, y, width, height);

 
נקבל ריבוע שחור בפינה הימנית עליונה של ה - Canvas בגודל 100 על 100.
 
במידה ונוסיף את השורה הבאה (לפני קריאת ל - fillRect)
 

ctx.fillStyle = 'rgb(200,200,200)';

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

// begin custom shape

ctx.beginPath();

ctx.moveTo(170, 80);

ctx.bezierCurveTo(130, 100, 130, 150, 230, 150);

ctx.bezierCurveTo(250, 180, 320, 180, 340, 150);

ctx.bezierCurveTo(420, 150, 420, 120, 390, 100);

ctx.bezierCurveTo(430, 40, 370, 30, 340, 50);

ctx.bezierCurveTo(320, 5, 250, 20, 250, 50);

ctx.bezierCurveTo(200, 5, 150, 20, 170, 80);

ctx.closePath();

// complete custom shape

 

ctx.lineWidth = 5;

ctx.strokeStyle = "#0000ff";

ctx.stroke();

 
 
Canavs - HTML5
 
 
כעת אם נוסיף (לפני השורה של lineWidth) את השורות הבאות:
 

var grd = ctx.createRadialGradient(238, 50, 10, 238, 50, 200);

grd.addColorStop(0, "#7944FF"); // light blue

grd.addColorStop(0.5, "#FF8928"); // light blue

grd.addColorStop(1, "#42FFCC"); // dark blue

ctx.fillStyle = grd;

ctx.fill();

 
נקבל:
Canvas - HTML5
 
 
ואם ממש נתפרע ונכתוב את הקוד הבא:
 

setInterval(function () {

    var grd = ctx.createRadialGradient(Math.floor((Math.random() * 255)),

                                        Math.floor((Math.random() * 255)),

                                        Math.floor((Math.random() * 255)),

                                        Math.floor((Math.random() * 255)),

                                        Math.floor((Math.random() * 255)),

                                        Math.floor((Math.random() * 255)));

 

    grd.addColorStop(0, "#7944FF"); // light blue

    grd.addColorStop(0.5, "#FF8928"); // light blue

    grd.addColorStop(1, "#42FFCC"); // dark blue

    ctx.fillStyle = grd;

    ctx.fill();

}, 200);

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

HTML5 - New Elements

פורסם בתאריך Jan 10 2012, 10:39 AM על ידי Shlomo

 

כפי שהבטחתי בפוסט הקודם אני אדבר הפעם על אלמנטים חדשים ב - HTML5.
 
כמובן שיש יותר מידי אלמנטים חדשים, ולכן אנסה לחלק לוגית בין הסוגים השונים ולספר על חלק מהאלמנטים החדשים מכל סוג.
 
 
כשאנחנו מנסים לחלק לוגית את האלמנטים החדשים, אנחנו רואים את הסוגים הבאים:
  • אלמנטים לוגיים - כלומר אלמנטים שאין להם כמעט משמעות מבחינת הפונקציונליות שלהם - אלא הם משמשים אותנו לחלוקה הגיונית יותר של האלמנטים בעמוד.
  • אלמנטים אמיתיים - אלמנטים המכילים פונקציונליות חדשה לחלוטין.
  • מאפיינים חדשים - אלמנטים קיימים שקבלו מאפיינים חדשים המאפשרים פונקציונליות חדשה.
 
 
אלמנטים לוגיים.
עד היום כשאנחנו מעמדים את עמודי ה - html אנחנו משתמשים או ב - divs או ב - tables, אין משמעות לוגית וסמנטית לאלמנטים בהקשר לתוכן שלהם, מה שמקשה את הקריאה וההבנה של התוכן למפתחים ולרובטים החוקרים את התוכן, בעזרת האלמנטים החדשים נוכל לצקת משמעות לעטיפה של התגים בהתאם לתוכן שנמצא בפנים - חשוב לזכור אין כמעט משמעות פונקציונלית בשימוש באותם אלמנטים.
 
דוגמא לאלמנטים החדשים.
  • Article - המקבילה הכי דומה ל - div, אלמנט המכיל תוכן מסויים.
  • Footer - מידע כמו זכויות יוצרים, מידע משפטי וכן הלאה.
  • Header - מידע בכותרת העמוד.
  • Nav - לינקים וניווט.
  • Section - עוטף כמה Article (דומה ל - div שעוטף div)
  • Aside - מכיל מידע ליד (על) Article
  • Figure - תמונה המסבירה תוכן של מאמר.
  • Dialog - אלמנטים כמו צ'אט וכדומה.
  • dt - מידע של משתתף אחד בדיאלוג.
  • dd - מידע של משתתף שני בדיאלוג.
 
 
שימוש באלמנטים הללו מאפשר להסתכל על האלמנטים מבלי לקרוא את התוכן שלהם ולהבין במה מדובר - לדוגמא כשרואים אלמנט מסוג nav מבינים שמדובר בניווט של העמוד, וכן הלאה.
 
 
 
אלמנטים אמיתיים.
יש הרבה אלמנטים חדשים, נראה דוגמאות לחלק מהם.
 
Mark - מאפשר לסמן מידע חשוב בתוך טקסט, לדוגמא:
 
My Name Is: <mark>Shlomo</mark>
ייתן את התוצאה הבאה
mark - html5
Progress - מאפשר לנו להשתמש ב - Progress bar אמיתי של מערכת ההפעלה כדי להציג התקדמות כלשהי למשתמש.
 
<progress max="100" value="30"></progress>
Progress HTML5
Details, Summary - מאפשר לנו להסתיר תוכן ולהציג בעזרת משהו שדומה ל - Expander
 
 
<details open="open">
    <summary>The title of the details</summary>
    <p style="padding-left:20px">
        Content Content Content Content <br />
        Content Content Content Content <br />
        Content Content Content Content <br />
        Content Content Content Content <br />
    </p>
</details>
 
Details, Summary - HTML5
 
אלו דוגמאות לאלמנטים חדשים המאפשרים לנו לעשות דברים חדשים שחלקם לא יכולנו לעשות ועבור חלקם היינו צריכים לעבוד קשה, (כמובן שיש עוד אלמנטים שלא תיארתי כאן.)
 
 
מאפיינים חדשים.
לכל מיני אלנטים קיימים נוספו מאפיינים חדשים המאפשרים יכולות חדשות, לדומא לאלמנט input עבור המאפיין type נוספו היכולות הבאות:
 
Range  - מאפשר לקבוע תחום.
 
 
Range - HTML5
 
דוגמא נחמדה לשימוש תהיה לקשר בן ה - Range לבין ה - Progress
 
<progress max="100" 
            value="30" 
            id="prog"></progress>
 
<input type="range" 
        min="0" 
        max="100" 
        value="30" 
        onchange="document.getElementById('prog').value=this.value" />
 
Email המאפשר לקבוע שבתיבת טקסט מסויימת יצטרכו להכניס Email, יחד עם מאפיין חדש בשם requierd המגדיר שבזמן submit חייב להיות שם ערך.

<input type="email" required="required" />

email requierd - HTML5

 
חשוב לשים לב שלא צריך לכתוב קוד javascript כדי לקבל את ההודעות על מה שחסר (או על התוכן שהוא מייל לא תקין).
 
יש עוד רבים כמו color, time שמאפשרים יכולות חדשות שבעבר היינו צריכים לעבוד קשה בשביל להשיג אותם (time נותן לוח שנה)
 
יש גם מאפיין בשם placeholder המאפשר להגדיר טקסט בצבע אפור כטקסט התחלתי לפני שהמשתמש התחיל לכתוב
 
<input type="text" placeholder="הקלד שם" />
plceholder - HTML5
 
(נלקח מהקורס של מכללת סלע על HTML5)
inputs - HTML5
 
 
 
אחד מהאלמנטים החדשים מאפשר לנו לעשות autocomplete מבלי תוספות רק לדאוג למידע)
 
<input type="text" list="list1" />
<datalist id="list1">
    <option value="שלמה גולדברג"></option>
    <option value="שלום כץ"></option>
    <option value="נועם כפיר"></option>
    <option value="מנחם הולידר"></option>
    <option value="חיים בריקמן"></option>
    <option value="יוסי גולדברג"></option>
    <option value="שמוליק סגל"></option>
</datalist>
 
datalist - HTML5
 
כמובן שיש עוד הרבה ולא אפרט כאן, חשוב לראות ולהבין שהיכולות של HTML5 מקילות עלינו את החיים.
 
נקודה חשובה נוספת, לא כל הפיצ'רים שתארתי כאן נתמכים בכל הדפדפנים (כל פיצ'ר ודפדפנו) - אבל הדרך לא ארוכה עד שכולם יתמכו בהכול.
 

HTML5 - The Modernizr

פורסם בתאריך Jan 04 2012, 10:34 AM על ידי Shlomo

 

בדיקת תמיכת פיצ'ר בדפדפן:
כפי שהבטחתי בפוסט הקודם אני אדבר היום איך כותבים ב - HTML5 עם מינימום נזק לדפדפנים שאינם תומכים ב - HTML5.
 
 
כשנרצה להשתמש בפיצ'רים שונים של HTML5 נרצה לוודא האם הדפדפן תומך בזה - לדוגמא לפני שימוש ב - localStorage וכדו'.
 
כדי לוודא זאת נוכל להוריד ספריית JS חביבה בשם Modernizr. ולכתוב:
 
 
 
if(Modernizr.localstorage)
{
 
}
 
וכך נוכל לבדוק כל פיצ'ר שנרצה להשתמש איתו ב - JS בבטחה.
 
אוטומציה לתהליך: 
כמובן שנעדיף מנגנון יותר אוטומטי שיטען קבצי סקריפט שונים במידה והדפדפן תומך (או לא) בפיצ'ר מסויים.
 
כדי לעשות זאת נצטרך להוריד עוד ספרייה קטנה בשם yepnope ואז נוכל לכתוב קוד כזה:
 
Modernizr.load({
    test: Modernizr.localstorage,
    yep: 'workWithStorage.js',
    nope: 'workWithcookie.js'
});
 
וכך יירד קובץ ה - JS (או ה - CSS) המתאים לפי הפיצ'רים שהדפדפן תומך.
 
 
תמיכה ב - CSS:
נוסף על כך ספריית ה - Modernizr מוסיפה css classes ל - html לפי התכונות הנתמכות, כך שאם הדפדפן שלנו לא תומך ב - border-raduis קובץ ה - html יקבל את class בשם no-borderradius.
לדוגמאות והרחבה בנושא בבלוג של גיא בורשטיין.
 
 
 
ספריות עזר לתמיכה באלמנטים שונים:
יש הרבה ספריות עזר כדי לקבל יכולות HTML5 בדפדפנים ישנים.(לדוגמא כאן).
 
נניח שתרצו להשתמש בתג progress של HTML5 ואתם נמצאים בדפדפן שאינו תומך, תוכלו להוריד מכאן css ו - js שיהפכו כל אלמנט progress לתמונה שתחקה את ההתנהגות של progress.
 
 
 
לסיכום - ניתן כבר היום להתחיל לכתוב עם HTML5, נוכל להחליט שאנחנו תומכים רק בדפדפנים מתקדמים (שזו החלטה לגיטימית - בעיקר אם אנחנו כותבים אפליקציות לסביבות סגורות) או שנחליט שאנחנו רוצים לתמוך בכולם ובמקרה זה נצטרך להשתמש בספריות חיצונית כדי לקבל תמיכה אחורה לדפדפנים שונים.

מפגש פורום תפוז

פורסם בתאריך Jan 02 2012, 08:17 PM על ידי Shlomo
כמידי תקופה אנחנו (חברי פורום תפוז) מארגנים מפגש טכנולוגי.
 
המפגש הבא יערך ב - 24 לינואר יום שלישי.
 
מכללת סלע מארחת כמידי פעם את המפגש - הכתובת: ברוך הירש 14 בני ברק (מול קניון אילון - חניה חופשית)
 
 
בתוכנית:
17:30 - 18:00 התכנסות.
 
18:00 - 18:50 הרצאה ראשונה של עידו פלטו על Fiddler.
 
18:50 - 19:00 הפסקה.
 
19:00 - 19:50 הרצאה של גדי מאיר על אחד מהנושאים החביבים עליו (כנראה על הכנת "היישום שלך לסביבת הייצור" או על "למידה מהנחיות של מייקרוסופט לגבי כתיבת קוד נכון")
 
20:00 - 20:50 הרצאה של רון קליין על שינוי קוד - מפרוצדורלי ל OOP. או על מבוא ל MSMQ ודוגמה מהחיים.
 
 
ניתן להרשם ב - LinkedIn.
 

HTML5 - HTML Review

פורסם בתאריך Jan 01 2012, 08:44 PM על ידי Shlomo
הקדמה:
מאז שכתבתי על כל מיני פיצ'רים ב - HTML5, דברים התווספו והשתנו בתקן ובדפדפנים, אני מתכוון להמשיך לכתוב על פיצ'רים שונים ומשונים של התקן, אך לפני הכול קצת היסטוריה ולמה בכלל אנחנו רוצים לעבוד עם HTML5.
 
 
היסטוריה:
HTML - Hyper Text Markup Language, נולד בשנת 1991 על ידי Tim Berners-Lee, כדרך להעברת טקסט סטטי תמונות ולינקים לדפים סטטים אחרים על גבי הרשת (באותה שנה גם יצא תקן ה - HTTP לאויר העולם).
 
בשנת 1994-1995 העולם התקדם לתקן HTML2 שהכיל פיצ'רים חשובים כמו טבלאות העלאת קבצים וכד'.
 
בשנת 1996 קבלנו את המושגים CSS1 ו - JavaScript שקידם את יכולות ה - HTML מסתם מידע סטטי לדף עם מידע דינמי (לפתע היה מקצוע בשם "מתכנת Web").
 
בשנת 1997 התקדם התקן ל - HTML4 (לכמה חודשים היה HTML3.2) עם יכולות ה - Frames ואחרים.
 
בשנת 1998 - התקדם ה - CSS לגרסה 2, עם פיצ'רים חדשים לעיצוב.
 
בשנת 2000 - השתנה התקן ל - XHTML וגרם למפתחי ה - HTML לכתוב קוד יותר מוקשח ותקני.
 
בשנת 2002 התחילו מלחמות הדת כיצד נכון וראוי לעמד את דפי ה - HTML (בעזרת div/table).
 
בשנת 2005 נכנס לתקן המושג AJAX (ב - IE זה היה קיים משנת 2002 כ - ActiveX)
 
ובשנת 2009 התחילו לדבר על HTML5 (למעשה W3C התחיל את תקן XHTML2 וקבוצת WHATWG התחילו את תקן Web Forms and Web Application, ולאחר מכן הם התאחדו לכדי תקן HTML5)
 
 
כמובן שרשימה זו חלקית ואינה מלאה וישנם כל מיני גרסאות ביניים, אבל בגדול זה מה שעברנו עם ה - HTML.
 
 
חשוב לשים לב שמשנת 1991 עד 1997 עברנו ארבע גרסאות, ומאז ועד היום אנחנו תקועים באותה גרסה, (XHTML אינו נחשב לשינוי גרסה מכיוון שזה רק מדבר על הקשחת הקוד) כשבפועל העולם מתקדם והתקן שבהחלט התאים אז כבר אינו מתאים היום, בעבר כתבו דפי מידע (ויקיפדיה) היום מצפים מאיתנו לכתוב אפליקציות (פייסבוק), מה שגורם לנו לעשות כל מיני דברים מוזרים ולכתוב הרבה קוד שבכל סביבה אחרת זה טריוויאלי לחלוטין.
 
 
 HTML5:
מה הם הסיבות שבעטיים נרצה לעבור ל - HTML5.
 
כמובן הסיבה הראשונה שהזכרתי למעלה, שהתקן הנוכחי אינו מתאים לאתרים מודרניים ואינו מכיל מספיק פיצ'רים לכתיבה נוחה.
 
עימוד האתר בעזרת Divs או Tables אינו נכון לוגית, מכיוון שאין שום משמעות לאלמנטים (div, tr) בהקשר של התוכן שהוא מכיל, אנו מצפים להשתמש בתגים בעלי משמעות לתוכן שהם מכילים (nav עבור תוכן שמכיל לינקים וכדו')
 
הצורך לכתוב קוד שונה עבור כל דפדפן - בעוד שמבחינתנו הדפדפן הוא האמצעי (אירוח האפליקציה) ולא המטרה.
 
 
התקן:
חשוב לזכור - לפי השמועות התקן ייסגר בשנת 2022 (אלפיים עשרים ושנים) וזה עוד ה ר ב ה זמן - דברים משתנים וישתנו ככל שיעבור הזמן, לא כל הדפדפנים תומכים בכל התכונות, ולא כולם מממשים אותם בצורה זהה בשלב זה. אבל אם אפשר לכתוב כבר עכשיו בדברים שכבר סגורים וכנראה לא ישתנו - כדאי לעשות זאת ולא להשאר מאחור.
 
יש פתרונות מעניינים לבעיות התאימות - ואני אספר אליהם בפרק הבא.
 
 
מה זה בכלל HTML5:
מתי שהוא כשהתחילו לדבר על HTML5, הראו את הגרפיקות המשחקים והאנימציות המדהימות שאפשר לעשות בעזרת HTML5.
 
זהו לא HTML5, זה באזז.
 
הסיבה שבעיני הקהל הרחב מה שמתקשר ל - HTML5 אלו הדברים שתיארתי, מכיוון שכשצריך להציג HTML5 צריך להראות דברים שמושכים את העין וכמובן משחקים ואנימציות זה דבר מדהים.
 
אבל אם נחשוב לרגע בהגיון, כמה אחוז מהקוד בצד הלקוח ברוב החברות באמת צריך אנימציות וגרפיקה מתקדמת, אחוז אפסי, ולכן בעיני אין לזה כמעט משמעות.
 
מה בכל זאת זה HTML5, התשובה היא: HTML + CSS3 + JavaScript API,
 
HTML - קיבל הרבה אלמנטים חדשים - כמו סוגים חדשים של Input, לדוגמא (range, mail, color), הוא קבל את היכולת להגדיר required על כל input בלי צורך לכתוב javascript שיעשה את הבדיקה, ועוד.
 
CSS3 - מאפשר מאפיינים חדשים כמו border-raduis, css selctors.
 
JavaScript API - מאפשר יכולות של הרצה מקבילית של קוד, זניחת הכתיבה המעצבנת של Cookies, כתיבה לבסיס נתונים בצד הלקוח, ועוד.
 
 
זהו בעיני HTML5, הכתיבה הקלה יותר, מרובת הפיצ'רים שחוסכים זמן ועבודה, זהו ה - HTML5 האמיתי שכל כך מרגש אותי ואני מחכה לו בקוצר רוח.
 
 
 
בפוסט הבא אני אציג ואספר כיצד כותבים קוד HTML5 מבלי לפגוע בדפדפנים שאינם תומכים ב - HTML5 (או לפחות ננסה לעשות את המקסימום)

הרצת כמה WorkerRole בפרוייקט azure אחד

פורסם בתאריך Dec 28 2011, 02:47 PM על ידי Shlomo

 

בהמשך לפוסט שהסביר כיצד להריץ כמה Web Roles במחשב אחד, נראה כעת כיצד להריץ כמה Worker Roles במחשב אחד.
 
בשונה מ - Web Roles שכדי להריץ אותם ממחשב אחד צריך רק לעשות שינויים בקובץ הקונפיג, ב - Worker Role זה כבר דורש שינוי קוד.
 
אני משתמש בפיתרון שנכתב כאן (כדאי לקרוא את ההסברים שם) - את דוגמת הקוד וה - framework שלהם אפשר להוריד כאן
 
 
 
כדי להשתמש בקוד שלהם צריך לייצר WorkerRole שיורש ממחלקה בשם ThreadedRoleEntryPoint (מחלקה שהם כתבו)
כל WorkerRole צריך לרשת מ - WorkerEntryPoint. ולא מ - RoleEntryPoint
 
 
וכעת ניתן לכתוב את הקוד הבא ב - WorkerRole (שאמור להכיל את שאר ה - Roles)
 

public class WorkerRole : ThreadedRoleEntryPoint

{

    public override bool OnStart()

    {

        List<WorkerEntryPoint> workers = new List<WorkerEntryPoint>();

 

        workers.Add(new RaderWorkerRole());

        workers.Add(new LogWorker());

 

        return base.OnStart(workers.ToArray());

    }

}

 
 
וזהו. (שוב - מומלץ לקרוא את הפוסט המקורי ולהבין איך זה עובד מאחורי הקלעים - זה לא מסובך)

הרצת כמה WebRole בפרוייקט azure אחד

פורסם בתאריך Dec 25 2011, 08:48 AM על ידי Shlomo

 

הרבה פעמים יש לנו כמה פרוייקטים שאמורים להתארח על IIS, בסביבה רגילה נארח את כולם על אותו IIS בשרת אחד, ב - azure העניינים קצת יותר מסובכים, היות שכברירת מחדל כל web role אמור לרוץ על מחשב משלו - מה שכמובן הרבה פעמים מיותר ועולה כסף.
 
יש כמה פתרונות לזה - אני אדגים כאן פיתרון בעזרת הגדרה של Virtual Application.
 
Virtual Application הוא בעצם Application רגיל שאנחנו מכירים ב - IIS - מה שמיוחד זה כיצד להגדיר אותו שירוץ כמו שצריך ב - azure.
 
 
ראשית נכנס לקובץ ServiceDefinition.csdef, נמחק את הגדרות ה - WebRoles שאנחנו לא מעוניינים שיעלו כמחשב נפרד.
 
לאחר מכן תחת Site (לפני הגדרת ה - Bindings) בהגדרה של הפרוייקט שאנחנו מתעדים להעלות אותו כמחשב נכתוב את הקוד הבא:
 

<VirtualApplication name="a10" physicalDirectory="c:\........">

</VirtualApplication>

 
כמובן שה - physicalDirectory צריך להכיל את המיקום המדוייק בו נמצא הפרוייקט, המאפיין name מכיל את ה - alias דרכו יגלשו לאתר.
 
 
כמה נקודות שצריך לזכור, היות שה - Site עצמו מפנה לאיזשהוא אפליקציה (מה שמוגדר במאפיין Name של ה - WebRole) זה אומר שההגדרות הקונפיג של פרוייקט ה"אבא" מחלחלים לכל ה - Virtual Applications וצריך להזהר משכפולים (כמו למשל עם אותו ConnectionString יהיה מוגדר בשניהם, יגרום להתרסקות ה - Virtual Application).
 
עוד דוגמא לבעייה - כיום azure לא תומך ב - MVC3, אם ברצונכם בכל זאת לעבוד איתו, צריך להגדיר על רשימת ה - dll's הבאים Copy Local עם הערך true.
 
 
Microsoft.Web.Infrastructure
System.Web.Helpers
System.Web.Mvc
System.Web.Razor
System.Web.WebPages
System.Web.WebPages.Deployment
System.Web.WebPages.Razor
 
במידה ופרוייקט ה"אבא" יהיה MVC3 - כל שאר ה - Virtal Applications יצטרכו להכיל את כל אותם dll's אע"פ שהם כלל לא ישתמשו בהם (לדוגמא wcf service).
 
פתרון טוב לבעיות אלו, יהיה להגדיר את פרוייקט ה"אבא" כפרוייקט ריק שאין בו כלום, ולהגדיר את כל שאר הפרוייקטים כ - Virtual Applications.
 
 
פתרון אחר הוא להגדיר כמה Sites, אבל על זה אכתוב בהזדמנות אחרת.

קריאת הערכים מתוך קבצי קונפיג בפרוייקט שיכול לרוץ בענן

פורסם בתאריך Dec 19 2011, 10:20 AM על ידי Shlomo

 

כשאנחנו מפתחים אפליקציות web אנחנו משתמשים בקובץ הקונפיג כדי להגדיר את ה - Connection String והגדרות שונות ב - App Settings, במעבר ל - azure הדברים מסתבכים קצת יותר, ניתן עדיין להגדיר את כל ההגדרות בקובץ ה - web.config, אבל זה אומר שבכל שינוי נצטרך לעשות Upload מחדש למערכת - מה שכמובן לא מומלץ.
 
האופציה האחרת היא להשתמש בקבצי הקונפיג של azure.
 
ניתן כמובן להשתמש עם חלון המאפיינים של הפרוייקט (תחת תיקיית ה - Roles, לחיצה כפולה על ה - Role המתאים) - אבל כדי להבין מה עושים תמיד עדיף בהתחלה לכתוב לבד.
 
בפרוייקט ה - azure שלכם ניתן לפתוח את הקובץ ServiceDefinition.csdef, בתוך ה - Role המתאים ניתן לכתוב את המקטע הבא:
 

<ConfigurationSettings>

  <Setting name="DBConnectionString" />

</ConfigurationSettings>

 
 
כעת נעבור לקבצים ServiceConfiguration.Local.cscfg, ServiceConfiguration.Cloud.cscfg אשר הם מכילים את הערכים עצמם.
קובץ Local מכיל את ההגדרות כשהמערכת רצה עם האימולטור, וקובץ ה - Cloud מכיל את ההגדרות כשהמערכת תהיה בענן.
 
נכתוב את הקוד המתאים לפי הסביבה
 

<ConfigurationSettings>

  <Setting name="DBConnectionString" value="CONNECTION_STRING" />

</ConfigurationSettings>

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

var connStr = RoleEnvironment.GetConfigurationSettingValue("DBConnectionString");

 
 
כדי להגדיר בנוחות בלי צורך לכתוב xml, ניתן לפתוח את ה - Role המתאים, לבחור בטאב Settings ולהוסיף כל הגדרה שתרצו, כדי להגדיר את הערכים צריך לבחור בקומבו (בחלק העליון של המסך) עבור איזה סביבה רוצים להגדיר את הערכים.
 
 
הבעייה עם הקוד הזה - שהוא מכריח אותנו להריץ לוקלית את האפליקציה עם האימולטור, לפעמים נרצה להריץ אותו תחת IIS כמו שהכרנו בעבר, מה שיגרום להתרסקות האפליקצייה בזמן ניסיון לקריאה מה - RoleEnvironment.
 
כדי לפתור זאת - כתב ידידי היקר חיים בריקמן את הקוד הבא:
 

public static class ConfigFetcher

{

    private static bool isRunningOnCloud = false;

 

    static ConfigFetcher()

    {

        isRunningOnCloud = RoleEnvironment.IsAvailable || RoleEnvironment.IsEmulated;

    }

 

    public static string Fetch(string name)

    {

        string val;

        if (isRunningOnCloud)

        {

            val = FromAzure(name);

        }

        else

        {

            val = FromConfig(name);

        }

        return val;

    }

 

    private static string FromAzure(string name)

    {

        try

        {

            var connStr = RoleEnvironment.GetConfigurationSettingValue(name);

            return connStr;

        }

        catch

        {

            return FromConfig(name);

        }

 

    }

 

    private static string FromConfig(string name)

    {

        var connStr = ConfigurationManager.ConnectionStrings[name];

 

        if (connStr != null)

        {

            return connStr.ConnectionString;

        }

 

        var setting = ConfigurationManager.AppSettings[name];

 

        if (setting != null)

        {

            return setting;

        }

 

        throw new ConfigurationErrorsException(name);

    }

}

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

ניהול בסיסי של תהליך כניסה והרשאות לאתר

פורסם בתאריך Dec 15 2011, 09:37 AM על ידי Shlomo

 

ניהול משתמשים והרשאות הוא אף פעם לא מהדברים הקלים, בפוסט זה נראה כיצד נשתמש במנגנון הבסיסי של asp.net כדי לוודא שאי אפשר להגיע לשום דף לפני שעברו תהליך login בהצלחה, בנוסף נראה כיצד אנחנו "אומרים" לשרת שהמשתמש עבר לוגין.
 
 
הדבר הראשון שנרצה לעשות זה להגדיר שהמשתמש לא יכול לגלוש לשום מקום לפני תהליך login, כדי לעשות זאת נכתוב בקובץ הקונפיג תחת system.web את המקטע הבא:
 

<authorization>

  <deny users="?"/>

</authorization>

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

<authentication mode="Forms">

  <forms loginUrl="login.aspx"

          defaultUrl="main.aspx"

          name="myLoginCookieName"

          timeout="10080"

          slidingExpiration="true"></forms>

</authentication>

 
נעבור על המאפיינים.
לא נכנס לעומק על המשמעות של המאפיין mode, רק אספר שבמידה והוא הוגדר כ - forms זה אומר שהאפליקציה שלנו אחראית על המשתמשים והיא מנהלת את תהליך הלוגין.
 
בתוך התגית forms המאפיין loginUrl מכיל את הכתובת לדף שבו מבצעים את תהליך הלוגין, חייבים להגדיר לו זאת מכיוון שהגדרנו במקטע הקודם שאסור לגלוש לאתר במידה והמשתמש אנונימי, ולכן ההגדרה של loginUrl מאפשרת עמוד אחד שאליו ניתן לגלוש. (זה הפרמטר היחיד שחובה להגדיר)
 
המאפיין defaultUrl מגדיר את הדף שאליו המשתמש יועבר לאחר תהליך הלוגין.
 
המאפיין name מגדיר את שם העוגייה שתשמור את המידע שאומר שהמשתמש עבר login בהצלחה (מומלץ לשנות את שם העוגייה - ברירת המחדל היא .ASPXAUTH)
 
המאפיין timeout קובע כמה זמן העוגייה תישמר (ברירת המחדל היא 30 דקות, בדוגמא זה הוגדר כשבוע) - חשוב להבין שההגדרה בקונפיג היא לא ההגדרה של "זכור אותי", בברירת מחדל העוגיה נשמרת בזיכרון של הדפדפן ולא בקבצים, מה שאומר שכל דפדפן חדש שיפתח יצטרך לוגין בפני עצמו, בהמשך נראה כיצד להגדיר "זכור אותי".
 
המאפיין slidingExpiration מגדיר האם הזמן שהוגדר לעוגייה היא אבסולוטית (כלומר 30 דקות מהרגע הראשון) או מהכניסה האחרונה של המשתמש (כלומר בכל PostBack הזמן מתחיל להספר מחדש).
 
 
כעת נכתוב את דף login.aspx, נניח שיש לכם שני תיבות טקסט ולחצן. נכתוב את הקוד הבא:
 

protected void Login_Click(object sender, EventArgs e)

{

    if (LoginValidate(txtName.Text, txtPassword.Text))

    {

        FormsAuthentication.RedirectFromLoginPage("name", true);

    }

}

 
 
כמובן שהפונקציה LoginValidate היא פונקציה שנצטרך לממש כך שתבדוק האם שם המשתמש והסיסמא חוקיים, במידה וכן, נשתמש בפונקציה שמעבירה את המשתמש לדף שהוגדר כ - defaultUrl, הערך true מגדיר את "זכור אותי" כך שבפעם הבאה שהמשתמש יגלוש לאתר הוא לא יצטרך לעבור login, במידה ותרצו שבכל פעם שהוא נכנס לאפליקציה הוא יעבור תהליך login, הגדירו ערך זה כ - false.
 
 
במידה ואתם רוצים להחליט לאיזה דף לגלוש, תוכלו לכתוב את הקוד הבא:
 
 

protected void Login_Click(object sender, EventArgs e)

{

    if (LoginValidate(txtName.Text, txtPassword.Text))

    {

        FormsAuthentication.SetAuthCookie("name", true);

 

        // redirect...

    }

}

 
 
פוסט זה הינו הבסיס לתהליך login, ולא דברתי כאן על מנגנון ה - Membership של asp.net - אולי בפוסט ארחיב ארחיב עליו.

log4net and azure

פורסם בתאריך Dec 11 2011, 10:03 AM על ידי Shlomo

 

בדרך כלל אני משתמש בתשתית log4net כדי לשמור לוגים, אני אוהב לשמור אותם אותם לקבצים ואני משתמש ב - RollingFileAppender.
 
כמובן שכשעובדים עם windows azure אי אפשר לעבוד בצורה כזו, מכיוון שכדי לקרוא את הלוגים נצטרך להכנס למכונה ב - remote וגרוע מכך בדרך כלל יש יותר ממכונה אחת - מה שאומר שהלוגים נשמרים על מכונות שונות, וכמובן אחר restart שלהם לא יהיה זכר ללוגים.
 
 
לכאורה הפיתרון הפשוט הוא לשמור אותם לבסיס נתונים או ל - storage, הבעייה עם בסיס נתונים שהתימחור שלו הוא לפי גודל - ולוגים יכולים לתפוס הרבה מקום, מצד שני עבור storage משלמים לפי מספר טרנזקציות - ואם כותבים הרבה ללוג זה יכול לצאת הרבה כסף.
 
לכן חשבתי על הפיתרון הבא:
1. נכתוב את הלוג לבסיס נתונים.
2. פעם ביום נעביר את המידע משם ל - storage, כך נוודא שבסיס הנתונים לא גודל ולא כותבים ל - storage יותר מפעם ביום,
3. כדי לא להעמיס יותר מידי על בסיס הנתונים, נשמור את הלוגים לזיכרון, ובתהליך נפרד אחת לדקה נעביר את כל הלוגים לבסיס הנתונים.
 
 
את הפיתרון והקוד המלא (הדוגמא בבלוג לא מכילה את הקוד המלא) ניתן להוריד כאן.
(הדוגמא מכילה גם קוד sql ליצירת בסיס נתונים, לא לשכוח לשנות בקונפיגים את ההפנייה לבסיס הנתונים)
 
 
הקוד יראה כך:
 
 
ראשית נבנה בסיס נתונים שנראה כך:
 
log object
 
 
נייצר פרוייקט אשר נקרא לו Logging, הוא יהיה הפרוייקט היחידי אשר יחזיק reference ל - log4net.dll, שאר הפרוייקטים רק יצטרכו לכתוב בקונפיג את הגדרות ה - logging.
 
(בדוגמא השימוש הוא בעזרת entity framework 4.0)
 
אחרי שתייבאו את בסיס הנתונים למודל, נרצה לכתוב קוד שיודע להמיר בין אובייקט של log4net לבין אובייקט Log של המודל, נכתוב את הקוד הבא
 

public partial class Log

{

    public override string ToString()

    {

        return string.Format("{0} about {1} on {2} at {3}\r\n{4}\r\n{5}\r\n\r\n",

            this.Level,

            this.Project,

            this.Instance,

            this.Date,

            this.Message,

            this.Exception);

    }

 

    public static implicit operator Log(LoggingEvent le)

    {

        return new Log()

        {

            Date = le.TimeStamp,

            Exception =  le.GetExceptionString(),

            Message = le.MessageObject != null ? le.MessageObject.ToString() : "",

            Instance = 0,

            Level = le.Level.Name,

            Project = AssemblyName

        };

    }

 

    private static string _name;

 

    private static string AssemblyName

    {

        get

        {

            if (_name == null)

            {

                _name = Assembly.GetExecutingAssembly().GetName().Name;

            }

 

            return _name;

        }

    }

}

 
נשתמש במנגנון partial calss כדי להוסיף יכולות למודל שלנו.
נדרוס את מתודת ToString כדי לקבל מחרוזת "אנושית" עבור כל שגיאה,
לאחר מכן נשתמש במנגון implicit casting כדי להמיר בין אובייקט של LoggingEvent (ששיך ל - log4net) לבין אובייקט Log (ששיך למודל).
 
 
כעת נוסיף מחלקה בשם Logger שיהיו לה שני תפקידים, ראשית - היא תעשה עטיפה לכל הפונקציות של log4net, כדי שניתן יהיה לכתוב ללוג (לא מופיע בדוגמא רק בקוד להורדה),
שנית - היא תחזיק timer אשר בכל פעימה תיקח את כל הנתונים מהזיכרון (כזכור אנחנו משתמשים ב - log4net ושומרים את המידע בזיכרון) ותשפוך אותם לבסיס הנתונים,
הקוד יראה כך:
 

public static class Logger

{

    internal static readonly ILog _log;

    private static Timer _timer;

 

    public static int Period

    {

        get

        {

            int period;

 

            if (int.TryParse(ConfigurationManager.AppSettings["LogPeriod"], out period))

            {

                return period;

            }

 

            return 60000;

        }

    }

 

    static Logger()

    {

        XmlConfigurator.Configure();

        _log = LogManager.GetLogger("");

 

        _timer = new Timer(TimerCallback, null, 0, Period);

    }

 

    private static object lookObject = new object();

    private static void TimerCallback(object state)

    {

        try

        {

            lock (lookObject)

            {

                using (LogEntities context = new LogEntities("Logger"))

                {

                    MemoryAppender ap = (MemoryAppender)LogManager.GetLoggerRepository().GetAppenders()[0];

                    var logs = ap.GetEvents();

                    ap.Clear();

 

                    foreach (var item in logs)

                    {

                        context.Logs.AddObject(item);

                    }

 

                    context.SaveChanges();

                }

            }

        }

        catch (Exception ex)

        {

 

        }

    }

 

}

 

 
 
ב - static ctor נאתחל את הלוג כפי שיוגדר בקבצי הקונפיגורציה (נראה בהמשך).
 
המאפיין Period יאותחל כברירת מחדל על דקה - או בהגדרה בקונפיג. (מגדיר כל כמה זמן לאסוף את הנתונים מהזיכרון ולשמור בבסיס הנתונים).
 
וכמובן הפוקנציה של ה - timer, אוספת את הנתונים מה - Logger ושומרת אותם לבסיס הנתונים, (כל אובייקט מתוך GetEvents יהיה מסוג LoggingEvent, ובקריאה ל - AddObject הוא עובר המרה אוטומטית לאובייקט מסוג Log בעזרת הפונקציה מהמחלקה הקודמת שמשתמשת ב - Implicit casting.
 
 
כל מי שירצה לכתוב ללוג, יוסיף reference לפרוייקט זה, ויוכל לקרוא לפונקציות הכתיבה בלוג, הדבר היחיד שצריך לעשות זה להוסיף בקבצי הקונפיגורציה את הקוד הבא:
 

<configSections>

  <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />

</configSections>

<log4net>

  <appender name="MemoryAppender" type="log4net.Appender.MemoryAppender">

  </appender>

  <root>

    <level value="DEBUG" />

    <appender-ref ref="MemoryAppender" />

  </root>

</log4net>

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

public override void Run()

{

    while (true)

    {

        InitBlob();

        Thread.Sleep(86400000);

 

        using (LogEntities context = new LogEntities("Logger"))

        {

            var list = context.Logs.ToList();

            string str = "";

            foreach (var item in list)

            {

                str += (item.ToString());

                context.Logs.DeleteObject(item);

            }

 

            CloudBlob blob = _blobContainer.GetBlobReference(DateTime.Now.ToString("dd-MM-yyyy HH-mm"));

            blob.UploadText(str);

 

            context.SaveChanges();

        }

 

    }

}

 
הפונקציה InitBlob מאתחלת את המשתנים שמגדירים את הגישה ל - blob, לאחר מכן ניתן לתהליך לנוח כיום עבודה.
 
נאסוף את כל הנתונים מבסיס הנתונים, נשמור אותם ל - storage עם שם שמכיל את התאריך, ובא לציון גואל.
 

Web Service - basic

פורסם בתאריך Dec 06 2011, 03:16 PM על ידי Shlomo

 

בתפוז עלתה השאלה כיצד מתחילים לעבוד עם web services, בפוסט זה אני אדגים את השלבים צעד אחר צעד לאלו המתחילים את דרכם בעולם ה - web.
 
 
בפרוייקט ה - web צריך להוסיף item חדש מסוג web service (סיומת asmx) - נקרא לו MyWebService.
 
יווצרו שני קבצים - הראשון MyWebService.asmx שאם תלחצו עליו עם העכבר ותבחרו ב - View Markup תראו שיש בו את השורה הבאה בלבד
 

<%@ WebService Language="C#" CodeBehind="MyWebService.asmx.cs" Class="WebApplication10.MyWebService" %>

 

שכל מה שכתוב כאן - היכן נמצא הקוד של ה - WebService.
 
הקובץ השני נקרא MyWebService.asmx.cs המכיל את הקוד שלנו.
כברירת מחדל נקבל את הקוד הבא:
 

[WebService(Namespace = "http://tempuri.org/")]

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

[System.ComponentModel.ToolboxItem(false)]

// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.

// [System.Web.Script.Services.ScriptService]

public class MyWebService : System.Web.Services.WebService

{

 

    [WebMethod]

    public string HelloWorld()

    {

        return "Hello World";

    }

}

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

public int Add(int a, int b)

{

    return a + b;

}

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

[WebMethod]

public int Add(int a, int b)

{

    return a + b;

}

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

[WebMethod(EnableSession = true)]

public int Add(int a, int b)

{

    HttpContext.Current.Session["key"] = "value";

    return a + b;

}

 
אני לא ארחיב בפוסט זה על תפקיד ה - Session, אך אציין שבמידה ואתם צריכים לשמור או לקרוא מידע בצד השרת ותרצו להשתמש ב - Session, צריך להוסיף את ההגדרה הזו.
 
(כדי לאפשר שימוש ב - asp.net ajax (כלומר - קריאה למתודות מקבצי javascript באמצעות ScriptManager) צריך להוריד את ההערה מ - ScriptService - למידע נוסף ומפורט בנושא, ניתן לקרוא במדריך השלם ל - ajax)
 
 
כעת נעבור לצד השני (כלומר מי שהולך להפעיל את המתודה מרחוק)
 
בפרוייקט אחר (לא חייב להיות באותו Solution) נלחץ לחיצה ימנית על הפרוייקט ונבחר ב - Add Service Reference.
במסך שיפתח לכם תוכלו להקליד את כתובת ה - web service או ללחוץ על Discover במידה ופרוייקט ה - WebService נמצא באותו Solution.
 
תקבלו את המסך הבא:
 
Service Reference
 
 
במידה ותלחצו על OK - יווצר לכם בצד הלקוח Proxy שעובד בטכנולוגיות WCF (לפירוט על הטכנולגיה)
 
כעת תוכלו לכתוב את הקוד הבא:
 

static void Main(string[] args)

{

    ServiceReference1.MyWebServiceSoapClient client = new ServiceReference1.MyWebServiceSoapClient();

    int res = client.Add(1, 2);

    Console.WriteLine(res);

}

 
 
כשבפועל הקריאה ל - Add תפנה לשרת ולא תבוצע על המחשב שלכם. (כמובן שבזמן הפיתוח אתם בדרך כלל גם הלקוח וגם השרת).
 
אחד הדברים הנחמדים שניתן לבצע הוא לחיצה על Advanced ולסמן את Generate asynchronous operations - ואז ניתן להפעיל כל מתודה בצורה אסינכרונית, לדוגמא:
 

static void Main(string[] args)

{

    ServiceReference1.MyWebServiceSoapClient client = new ServiceReference1.MyWebServiceSoapClient();

    client.AddCompleted += client_AddCompleted;

    client.AddAsync(1, 3);

 

    Console.ReadLine();

}

 

static void client_AddCompleted(object sender, ServiceReference1.AddCompletedEventArgs e)

{

    Console.WriteLine(e.Result);

}

 
 
במידה ונרצה ליצור אצל הלקוח שימוש ב - WebService (כמו פעם) ולא להשתמש ב - WCF, נוכל ללחוץ בתוך Advanced על Add Web Reference, נקבל את המסך הבא:
 
Web Reference
 
 
כעת ניתן להכניס את הכתובת או ללחוץ על Web Service in this solution
 
לאחר אישור ולחיצה על Add Reference - יווצר proxy שיעבוד בפרוטוקול SOAP, וניתן יהיה לכתוב קוד כזה:
 

localhost.MyWebService service = new localhost.MyWebService();

Console.WriteLine(service.Add(1, 3));

 
 
יש עוד מה להרחיב על הנושא, אך תיאור זה הינו מספק כדי להתחיל לעבוד עם Web Services
More Posts Next page »