<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:blogChannel="http://backend.userland.com/blogChannelModule" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>משחקי קוד</title>
    <description />
    <link>http://blog.talgiladi.net/</link>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>BlogEngine.NET 1.4.5.0</generator>
    <language>he-IL</language>
    <blogChannel:blogRoll>http://blog.talgiladi.net/opml.axd</blogChannel:blogRoll>
    <blogChannel:blink>http://www.dotnetblogengine.net/syndication.axd</blogChannel:blink>
    <dc:creator>Tal Giladi</dc:creator>
    <dc:title>משחקי קוד</dc:title>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/codegames" type="application/rss+xml" /><feedburner:browserFriendly></feedburner:browserFriendly><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
      <title>A conversation with a 2.5 years girl</title>
      <description>&lt;p&gt;
It starts with a random question, but continues with a well designed pattern... 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;div style="background: white none repeat scroll 0% 0%; text-align: left; direction: ltr; font-family: Courier New; font-size: 10pt; color: black; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous"&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Main(&lt;span style="color: blue"&gt;string&lt;/span&gt;[] args)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;string&lt;/span&gt; source = &lt;span style="color: blue"&gt;null&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;while&lt;/span&gt; (&lt;span style="color: blue"&gt;true&lt;/span&gt;)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (source == &lt;span style="color: blue"&gt;null&lt;/span&gt;)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; source = GetTheQuestionThatMostInterestsMeNow();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Why &amp;quot;&lt;/span&gt; + source + &lt;span style="color: #a31515"&gt;&amp;quot;?&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;var&lt;/span&gt; answer = &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.ReadLine();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;var&lt;/span&gt; nextQuestion = ThinkDeeplyAboutTheAnswerAndGetTheNextQuestion(answer);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; source = nextQuestion ?? source;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; GetTheQuestionThatMostInterestsMeNow()
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: #a31515"&gt;&amp;quot;are the birds singing&amp;quot;&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; ThinkDeeplyAboutTheAnswerAndGetTheNextQuestion(&lt;span style="color: blue"&gt;string&lt;/span&gt; answer)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;string&lt;/span&gt; result = &lt;span style="color: blue"&gt;null&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (answer != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;int&lt;/span&gt; index;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; ((index = answer.IndexOf(&lt;span style="color: #a31515"&gt;&amp;quot;because&amp;quot;&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;StringComparison&lt;/span&gt;.OrdinalIgnoreCase)) &amp;gt; -1)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; answer = answer.Substring(index + &lt;span style="color: #a31515"&gt;&amp;quot;because&amp;quot;&lt;/span&gt;.Length);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; result = answer;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; result;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
</description>
      <link>http://blog.talgiladi.net/post/A-conversation-with-a-25-years-girl.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/A-conversation-with-a-25-years-girl.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=c27ac602-99a3-4456-9613-19a3821c136b</guid>
      <pubDate>Sun, 01 Nov 2009 12:28:00 +0400</pubDate>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=c27ac602-99a3-4456-9613-19a3821c136b</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=c27ac602-99a3-4456-9613-19a3821c136b</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/A-conversation-with-a-25-years-girl.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=c27ac602-99a3-4456-9613-19a3821c136b</wfw:commentRss>
    </item>
    <item>
      <title>Code Contracts</title>
      <description>&lt;p&gt;המטרה: ליצור שפה אחידה שמתארת את ההנחות והציפיות שלי כשאני משתמש באובייקט של מישהו אחר, או כשמישהו אחר משתמש&lt;/p&gt;  &lt;p&gt;באובייקט שאני כתבתי. נשמע לא מובן, אך כולנו בעצם עושים את זה יומיום, השינוי היחיד הוא שאנו רוצים לעשות את זה בצורה אחידה.&lt;/p&gt;  &lt;p&gt;היום כשאני מקבל ערך לאיזה מאפיין במחלקה שלי, אני בודק האם הערך תקין, האם הוא לא ריק וכו’, ואם הערכים לא מתאימים לי, אני זורק&lt;/p&gt;  &lt;p&gt;הודעת שגיאה בדרך כלל:&lt;/p&gt;  &lt;div class="code_area"&gt;   &lt;p class="code_line"&gt;&amp;#160; &lt;span class="code_keywords"&gt;private&lt;/span&gt; &lt;span class="code_keywords"&gt;int&lt;/span&gt; _age;&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;int&lt;/span&gt; Age&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="code_keywords"&gt;get&lt;/span&gt;&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="code_keywords"&gt;return&lt;/span&gt; _age;&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="code_keywords"&gt;set&lt;/span&gt;&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="code_keywords"&gt;if&lt;/span&gt; (&lt;span class="code_keywords"&gt;value&lt;/span&gt; &amp;lt; 0)&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="code_keywords"&gt;throw&lt;/span&gt; &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;ArgumentException&lt;/span&gt;(&lt;span class="code_text"&gt;&amp;quot;Age must be a positive value&amp;quot;&lt;/span&gt;);&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _age = &lt;span class="code_keywords"&gt;value&lt;/span&gt;;&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;ואיך נכתוב את זה באמצעות חוזה?&lt;/p&gt;  &lt;div class="code_area"&gt;   &lt;p class="code_line"&gt;&amp;#160;&lt;span class="code_keywords"&gt;private&lt;/span&gt; &lt;span class="code_keywords"&gt;int&lt;/span&gt; _age;&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;int&lt;/span&gt; Age&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="code_keywords"&gt;get&lt;/span&gt;&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="code_keywords"&gt;return&lt;/span&gt; _age;&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="code_keywords"&gt;set&lt;/span&gt;&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="code_classes"&gt;Contract&lt;/span&gt;.Requires(&lt;span class="code_keywords"&gt;value&lt;/span&gt; &amp;gt; 0);&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _age = &lt;span class="code_keywords"&gt;value&lt;/span&gt;;&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p class="code_line"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt; זהו…&lt;/p&gt;  &lt;p&gt;הקוד עדיין בתהליכי פיתוח במייקרוסופט, אך הוא מופץ כבר משולב בתוך דוט נט גירסה 4, וניתן להורדה גם עבור ויז’ואל סטודיו 2008.&lt;/p&gt;  &lt;p&gt;אז מה יש לנו שם עוד? &lt;/p&gt;  &lt;p&gt;יש כמה דברים מעניינים, לדוגמה:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;בדיקה של הערכים שפונקציה יכולה להחזיר, לפני שהיא מחזירה אותם. בדיקה &lt;/li&gt;    &lt;li&gt;סטטית(compile time) של קריאות עם ערכים לא תקינים לפונקציה כך שאנו מקבלים אזהרה עוד לפני זמן הריצה (רק שבינתיים הם הוסיפו את האופציה הזאת רק עבור גירסה team suite…)&lt;/li&gt;    &lt;li&gt;הגדרת דרישות עבור ממשק, כך שכל מחלקה שמיישמת אותו תצטרך למלא את הדרישות האלו.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;אבל הדברים העיקריים הם אלו:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt; תנאי מקדים- שאנו מבטאים באמצעות הקוד שעכשיו כתבנו : Contract.Requires, שבעצם בודק שהכל תקין לפני שאני מתחיל את המתודה שלי.&lt;/li&gt;    &lt;li&gt;תנאי מאוחר – שבודק את התקינות לאחר שהקוד שלי רץ והמתודה עומדת להסתיים.&lt;/li&gt;    &lt;li&gt;תנאים לא תלויי אובייקט- אלו תנאים שתמיד אמורים להיות נכונים לגבי האובייקט שלי, לא משנה מה מצבו- גיל לא יכול להיות שלילי, גם אם הלקוח לא מילא את פרטי גילו, ולכן בכל מצב זה אמור להיות נכון, ולא רק לאחר שהכנסתי ערך לפרטי הגיל.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;על מנת שהחוזים שאנו כותבים יכנסו אכן לקוד, ולא יושמטו על ידי הקומפלייר, יש להגדיר סימבול.&lt;/p&gt;  &lt;p&gt;אם אתם משתמשים בויז’ואל סטודיו 2010 לכו למאפייני הפרוייקט ( לחצן ימני על שם הפרוייקט-&amp;gt; מאפיינים)&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.talgiladi.net/image.axd?picture=WindowsLiveWriter/CodeContracts/7CEF04BC/defineSymbol.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="defineSymbol" border="0" alt="defineSymbol" src="http://blog.talgiladi.net/image.axd?picture=WindowsLiveWriter/CodeContracts/5A2DCCFF/defineSymbol_thumb.jpg" width="472" height="226" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;תוסיפו שם את המילה CONTRACTS_FULL&lt;/p&gt;  &lt;p&gt; בויז’ואל סטודיו 2008 נדרשת התקנה של הקוד, ולאחר מכן יש להוסיף הפניה ל microsoft.contracts, אך לאחר ההתקנה יהיה לכם בהגדרות פרוייקט טאב מיוחד להגדרות של החוזים.&lt;/p&gt;  &lt;p&gt;מידע נוסף ניתן למצוא באתר של &lt;a href="http://research.microsoft.com/en-us/projects/contracts/" target="_blank"&gt;מייקרוסופט&lt;/a&gt;, יש שם וידאו ומסמך pdf עם הסברים רחבים ודוגמאות.&lt;/p&gt;</description>
      <link>http://blog.talgiladi.net/post/Code-Contracts.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/Code-Contracts.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=3271a51f-6a48-473a-a500-5b930f296a31</guid>
      <pubDate>Sun, 28 Jun 2009 12:07:07 +0400</pubDate>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=3271a51f-6a48-473a-a500-5b930f296a31</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=3271a51f-6a48-473a-a500-5b930f296a31</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/Code-Contracts.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=3271a51f-6a48-473a-a500-5b930f296a31</wfw:commentRss>
    </item>
    <item>
      <title>Service locator</title>
      <description>&lt;p&gt;
ראיתי את &lt;a href="http://commonservicelocator.codeplex.com/"&gt;הפרוייקט&lt;/a&gt; הזה ב code plex שמיקל על השימוש בService Locator בצורה יותר Loosley Coupled. לאחר מה שקרה לי 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.talgiladi.net/post/d794d7a0d7a1d799d795d79f-d7a9d79cd799-d7a2d79d-StructureMap.aspx"&gt;לפני כמה זמן&lt;/a&gt;, בדיוק בנושא הזה, החלטתי מעצמי לישם פיתרון כזה ואז ראיתי היום שיש כבר קוד מוכן&amp;hellip; לא שזה כזה משנה, בסך הכל 3 
&lt;/p&gt;
&lt;p&gt;
מחלקות יצרתי שם עם כמה שורות קוד&amp;hellip; 
&lt;/p&gt;
&lt;p&gt;
בכל מקרה, עדיין הפרוייקט שלהם טעון שיפור, שכן הוא לא מספק דרך לקנפג את השירות דרך הקוד. הם פשוט סומכים על כל מחלקה שמממשת את הממשק שתקנפג את עצמה, שזה די טוב לרוב האנשים שמשתמשים בקבצי XML חיצוניים לקינפוג, אבל אני טוען את המידע בעצמי ואז בזמן ריצה מקנפג את המיפוי, וזה אומר שאני אצטרך בכל מחלקה שמממשת את הממשק אני אצטרך להכניס מעל 100 שורות עם המיפויים, וכולנו יודעים מה זה אומר לשכפל קוד&amp;hellip; 
&lt;/p&gt;
&lt;p&gt;
אז רק כדי להשלים את הפרוייקט שלהם נראה שצריך להוסיף 2 מתודות בממשק.&amp;nbsp; הראשונה:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&lt;span class="code_keywords"&gt;void&lt;/span&gt; RegisterType&amp;lt;TFrom, TTo&amp;gt;() &lt;span class="code_keywords"&gt;where&lt;/span&gt; TTo : TFrom;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
זאת שאמורה למפות ממשק למחלקה הדיפולטית שמיישמת אותו, והשניה:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p class="code_line"&gt;
&lt;span class="code_keywords"&gt;void&lt;/span&gt; RegisterInstance&amp;lt;TType&amp;gt;(TType instance);
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
שתמפה אינסטס קיים של אובייקט שמממש את הממשק.
&lt;/p&gt;
&lt;p&gt;
עכשיו אני יכול בנקודת הכניסה לאפליקציה (נניח ב global.asax) למפות את כל מה שאני רוצה בלי להיות תלוי במימוש מסוים.
&lt;/p&gt;
&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:7cbea3dd-8c05-467a-ba72-a492f20a7226" class="wlWriterEditableSmartContent" style="display: inline; float: none; margin: 0px; padding: 0px"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/IOC"&gt;IOC&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/ServiceLocator"&gt;ServiceLocator&lt;/a&gt;
&lt;/div&gt;
</description>
      <link>http://blog.talgiladi.net/post/Service-locator.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/Service-locator.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=9361d69d-0e42-41ab-bd65-8cfdc961f1ad</guid>
      <pubDate>Wed, 04 Mar 2009 21:46:00 +0400</pubDate>
      <category>IOC</category>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=9361d69d-0e42-41ab-bd65-8cfdc961f1ad</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=9361d69d-0e42-41ab-bd65-8cfdc961f1ad</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/Service-locator.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=9361d69d-0e42-41ab-bd65-8cfdc961f1ad</wfw:commentRss>
    </item>
    <item>
      <title>רינדור User Control לבקשה מאג’קס</title>
      <description>&lt;p&gt;
הבעיה: אני מאפשר להוסיף תגובות בדף, אני רוצה לשלוח את הבקשה באג&amp;rsquo;קס לשרת, ואם היא מאושרת להוסיף את התגובה ישירות לדף, בלי לרפרש אותו. קוד ה HTML של תגובה נמצא ב user control . אני רוצה שהשרת ישלח לי בחזרה את קוד ה HTML של התגובה החדשה, לא סתם ישלח, אלא בפורמט JSON.
&lt;/p&gt;
  
&lt;p&gt;
עם web forms&amp;nbsp; לא הייתה לי בעיה, יש מתודה שנקראת RenderControl עבור כל פקד, והיא מדפיסה את קוד ה HTML שלו, ואחר כך אני עושה עם הטקסט הזה מה שאני רוצה, במקרה שלי, שולח לדפדפן בפורמט JSON.
&lt;/p&gt;
  
&lt;p&gt;
ב MVC זה לא קיים. אני מתכוון שכל פעולה בנפרד קיימת, אבל הכל ביחד כמו שאני צריך, לא.
&lt;/p&gt;
  
&lt;p&gt;
יש אפשרות לשלוח JSON על ידי שימוש במתודה Json שנמצאת בקונטרולר, או על ידי יצירת JsonResult. 
&lt;/p&gt;
  
&lt;p&gt;
יש אפשרות לרנדר קונטרול פשוט כמו שמרנדרים כל view אחר- פשוט לקרוא למתודה View() עם שם הקונטרול. הבעיה היא שהתוצאה מודפסת ישירות ל response בתור טקסט, ואני רוצה לשלוח אותה בתור json. אז ניסיתי לעבוד עליו, ליצור response מדומה ואז למשוך ממנו את הטקסט ולשלוח על ידי המתודה Json(), לא עבד. ניסיתי עוד כמה דברים שהיו בגוגל, לא עבד.
&lt;/p&gt;
  
&lt;p&gt;
טוב, אז זה מה שיצא לי&amp;hellip; לא שאני הכי שמח עם זה, אבל זה עובד..
&lt;/p&gt;
  
&lt;ol&gt;
	   
	&lt;li&gt;מחלקה שמרנדרת את הקונטרול לטקסט:      
	&lt;div class="code_area"&gt;
	       
	&lt;p class="code_line"&gt;
	&lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;class&lt;/span&gt; &lt;span class="code_classes"&gt;BlockRenderer&lt;/span&gt;
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;private&lt;/span&gt; &lt;span class="code_keywords"&gt;readonly&lt;/span&gt; &lt;span class="code_classes"&gt;HttpContextBase&lt;/span&gt; _httpContext;
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;public&lt;/span&gt; BlockRenderer(&lt;span class="code_classes"&gt;HttpContextBase&lt;/span&gt; httpContext)
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _httpContext = httpContext;
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;partial&lt;/span&gt; &lt;span class="code_keywords"&gt;class&lt;/span&gt; &lt;span class="code_classes"&gt;HttpResponse&lt;/span&gt;
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;bool&lt;/span&gt; UsingHttpWriter { &lt;span class="code_keywords"&gt;get&lt;/span&gt; { &lt;span class="code_keywords"&gt;return&lt;/span&gt; &lt;span class="code_keywords"&gt;true&lt;/span&gt;; } }
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;string&lt;/span&gt; Capture(&lt;span class="code_classes"&gt;Action&lt;/span&gt; viewRenderer)
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;HttpResponseBase&lt;/span&gt; resp = _httpContext.Response;
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;Stream&lt;/span&gt; originalFilter = &lt;span class="code_keywords"&gt;null&lt;/span&gt;;
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;CapturingResponseFilter&lt;/span&gt; innerFilter;
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;string&lt;/span&gt; capturedHtml = &lt;span class="code_text"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;if&lt;/span&gt; (viewRenderer != &lt;span class="code_keywords"&gt;null&lt;/span&gt;)
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;try&lt;/span&gt;
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; resp.Flush();
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; originalFilter = resp.Filter;
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; innerFilter = &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;CapturingResponseFilter&lt;/span&gt;(resp.Filter);
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; resp.Filter = innerFilter;
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; viewRenderer();
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; resp.Flush();
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; capturedHtml = innerFilter.GetContents(resp.ContentEncoding);
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;finally&lt;/span&gt;
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;if&lt;/span&gt; (originalFilter != &lt;span class="code_keywords"&gt;null&lt;/span&gt;)
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; resp.Filter = originalFilter;
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;return&lt;/span&gt; capturedHtml;
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; }
	&lt;/p&gt;
	     
	&lt;/div&gt;
	 עכשיו כדי לקרוא לה, צריך מתוך הקונטרולר להוסיף את המתודה הבאה:       
	&lt;div class="code_area"&gt;
	       
	&lt;p class="code_line"&gt;
	&amp;nbsp;
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;string&lt;/span&gt; RenderPartialToString(&lt;span class="code_keywords"&gt;string&lt;/span&gt; userControl, &lt;span class="code_classes"&gt;ViewDataDictionary&lt;/span&gt; viewData, &lt;span class="code_classes"&gt;ControllerContext&lt;/span&gt; controllerContext)
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;HtmlHelper&lt;/span&gt; h = &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;HtmlHelper&lt;/span&gt;(&lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;ViewContext&lt;/span&gt;(controllerContext, &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;WebFormView&lt;/span&gt;(&lt;span class="code_text"&gt;&amp;quot;Index&amp;quot;&lt;/span&gt;), viewData, TempData), &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;ViewPage&lt;/span&gt;());
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;var&lt;/span&gt; blockRenderer = &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;BlockRenderer&lt;/span&gt;(controllerContext.HttpContext);
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;string&lt;/span&gt; s = blockRenderer.Capture(
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; () =&amp;gt; &lt;span class="code_classes"&gt;RenderPartialExtensions&lt;/span&gt;.RenderPartial(h, userControl, viewData)
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; );
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;return&lt;/span&gt; s;
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
	&lt;/p&gt;
	     
	&lt;/div&gt;
	 ופשוט לקרוא כל פעם שרוצים לרנדר משהו על ידי שליחת הפרמטרים המתאימים:       
	&lt;div class="code_area"&gt;
	       
	&lt;p class="code_line"&gt;
	&amp;nbsp;&lt;span class="code_classes"&gt;ViewDataDictionary&lt;/span&gt; viewData = &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;ViewDataDictionary&lt;/span&gt;(&lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;List&lt;/span&gt;&amp;lt;&lt;span class="code_classes"&gt;Reply&lt;/span&gt;&amp;gt;() { reply });
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp;&lt;span class="code_keywords"&gt;string&lt;/span&gt; s = RenderPartialToString(&lt;span class="code_text"&gt;&amp;quot;~/Views/Shared/ReplyItem.ascx&amp;quot;&lt;/span&gt;, viewData, &lt;span class="code_keywords"&gt;this&lt;/span&gt;.ControllerContext);
	&lt;/p&gt;
	     
	&lt;/div&gt;
	&amp;nbsp;&amp;nbsp; טוב, אז עכשיו קיבלתי את הקונטרול בתור טקסט, ואז אתם חושבים, יפה פשוט נחזיר אותו על ידי קריאה למתודה JSON בקונטרולר, אז ניסיתי וקיבלתי שגיאה- מתברר שבמהלך הקריאה למחלקה שמרנדרת את הקונטרול, מישהו באמצע החליט להוסיף http headers, והקונטרולר לא מסכים לקריאה למתודה JSON כשיש לו headers כבר... טוב אז אחרי כמה משחקים עם הקוד הגעתי לפיתרון פשוט: &lt;/li&gt;    
	&lt;li&gt;לא לקרוא ל JSON, אלא להפוך את המידע לג&amp;#39;ייסון בעצמי, ולשלוח אותו בתור טקסט, אז לא איכפת לקונטרולר אם יש headers או לא. והקוד הפשוט הוא      
	&lt;div class="code_area"&gt;
	       
	&lt;p class="code_line"&gt;
	&amp;nbsp;&lt;span class="code_classes"&gt;JavaScriptSerializer&lt;/span&gt; js = &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;JavaScriptSerializer&lt;/span&gt;();
	&lt;/p&gt;
	        
	&lt;p class="code_line"&gt;
	&amp;nbsp; &lt;span class="code_keywords"&gt;return&lt;/span&gt; &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;TextResult&lt;/span&gt;(js.Serialize(&lt;span class="code_keywords"&gt;new&lt;/span&gt; { approved = reply.IsApproved.ToString(), replyHtml = html }));
	&lt;/p&gt;
	     
	&lt;/div&gt;
	   &lt;/li&gt; 
&lt;/ol&gt;
  
&lt;p&gt;
כמו שאמרתי, אני לא כל כך מרוצה, אם יש למישהו פיתרון יותר אלגנטי, אני אשמח. ובכלל אני לא מבין למה זה כל כך מסובך, זה נשמע לי די תדיר שמישהו יפנה לשרת וירצה לרנדר קונטרול בתור סטרינג&amp;hellip;
&lt;/p&gt;
  
&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:51725bcb-ea4c-4197-8b2b-48e1f85ed471" class="wlWriterEditableSmartContent" style="margin: 0px; padding: 0px; display: inline; float: none"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/mvc"&gt;mvc&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/user+control"&gt;user control&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/ajax"&gt;ajax&lt;/a&gt;
&lt;/div&gt;
</description>
      <link>http://blog.talgiladi.net/post/d7a8d799d7a0d793d795d7a8-User-Control-d79cd791d7a7d7a9d794-d79ed790d792e28099d7a7d7a1.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/d7a8d799d7a0d793d795d7a8-User-Control-d79cd791d7a7d7a9d794-d79ed790d792e28099d7a7d7a1.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=418127b7-459f-451a-9c5d-110f994fa6cd</guid>
      <pubDate>Sun, 01 Mar 2009 01:23:00 +0400</pubDate>
      <category>MVC</category>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=418127b7-459f-451a-9c5d-110f994fa6cd</pingback:target>
      <slash:comments>2</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=418127b7-459f-451a-9c5d-110f994fa6cd</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/d7a8d799d7a0d793d795d7a8-User-Control-d79cd791d7a7d7a9d794-d79ed790d792e28099d7a7d7a1.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=418127b7-459f-451a-9c5d-110f994fa6cd</wfw:commentRss>
    </item>
    <item>
      <title>Captcha for MVC</title>
      <description>&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:cb8950aa-6953-4b7c-96b4-804fda4880b1" class="wlWriterEditableSmartContent" style="margin: 0px; padding: 0px; display: inline; float: none"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/asp.net"&gt;asp.net&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/mvc"&gt;mvc&lt;/a&gt;
&lt;/div&gt;
  
&lt;p&gt;
כתבתי בעבר על איך ליצור captcha control פשוט, וגם כתבתי אחד קצת יותר מתקדם, 
&lt;/p&gt;
  
&lt;p&gt;
אבל עכשיו כשאני בתהליכי מעבר ל mvc הקונטרולים הקודמים לא כל כך מועילים, שהרי הם משתמשים ב webforms. 
&lt;/p&gt;
  
&lt;p&gt;
אז כמובן שאי אפשר פשוט לזרוק כאן קונטרול על הדף וזה יעבוד, זה חלק מהמחיר שאנו משלמים עם mvc,
&lt;/p&gt;
  
&lt;p&gt;
אז נצטרך לכתוב כמה שורות קוד, לא יותר מדי&amp;hellip;
&lt;/p&gt;
 
&lt;ol&gt;
	 	
	&lt;li&gt; 
	&lt;p&gt;
	 אז קודם כל הורדתי קוד ליצירת התמונה, משהו נחמד עם צבעים וציורים :), זה בלוג של מישהו, אתם יכולים לקרוא &lt;a href="http://www.coderjournal.com/uploads/2008/03/captcha.zip" target="_blank"&gt;מאמר&lt;/a&gt; עוד אם אתם רוצים. בקיצור נראה לי שהוא כתב קצת יותר מדי, אז שיפצרתי קצת את הקוד וזה מה שיצא.
	&lt;/p&gt;
	  
	&lt;p&gt;
	קודם כל יש הקוד המקורי שיוצר את התמונה, זו מחלקה אחת לא גדולה בשם &lt;a href="http://www.talgiladi.net/examples/CaptchaImage.cs.txt" target="_blank" title="CaptchaImage class code"&gt;CaptchaImage&lt;/a&gt;
	&lt;/p&gt;
	 &lt;/li&gt; 
	&lt;li&gt; 
	&lt;p&gt;
	 אחר כך יצרתי מחלקה סטטית בשם CaptchaManager שתעטוף את הפונקציונליות בארבע פונקציות:
	&lt;/p&gt;
	  
	&lt;p&gt;
	א. GetCaptchaString &amp;ndash; מייצר טקסט רנדומלי ושומר אותו בסשן להשוואה.
	&lt;/p&gt;
	  
	&lt;p&gt;
	ב. ResetCaptcha &amp;ndash; משמשת לייצור טקטס חדש- אם אתם רוצים לאפשר רינדור של תמונות על ידי אג&amp;#39;קס במקרה שהמשתמש לא רואה טוב את התמונה, אם לא אתם יכולים למחוק אותה.
	&lt;/p&gt;
	  
	&lt;p&gt;
	ג. RenderImage מייצרת את התמונה עבור הקונטרולר שאמור לשלוח אותה לדפדפן.
	&lt;/p&gt;
	  
	&lt;p&gt;
	ד. IsValid &amp;ndash; ערך שמציין האם הפניה האחרונה שהגיע מהדפדפן מכילה ערך תקין בהתאם לתמונה שנשלחה. זוהי בעצם הבדיקה שלי.
	&lt;/p&gt;
	  
	&lt;p&gt;
	&amp;nbsp;
	&lt;/p&gt;
	   
	&lt;div class="code_area"&gt;
	   
	&lt;p class="code_line"&gt;
	&lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;class&lt;/span&gt; &lt;span class="code_classes"&gt;CaptchaManager&lt;/span&gt;
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	{
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;static&lt;/span&gt; &lt;span class="code_keywords"&gt;string&lt;/span&gt; GetCaptchaString()
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;string&lt;/span&gt; result;
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;if&lt;/span&gt; (&lt;span class="code_classes"&gt;HttpContext&lt;/span&gt;.Current.Session[&lt;span class="code_text"&gt;&amp;quot;captchaText&amp;quot;&lt;/span&gt;] != &lt;span class="code_keywords"&gt;null&lt;/span&gt;)
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = &lt;span class="code_classes"&gt;HttpContext&lt;/span&gt;.Current.Session[&lt;span class="code_text"&gt;&amp;quot;captchaText&amp;quot;&lt;/span&gt;] &lt;span class="code_keywords"&gt;as&lt;/span&gt; &lt;span class="code_keywords"&gt;string&lt;/span&gt;;
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;else&lt;/span&gt;
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = &lt;span class="code_classes"&gt;Guid&lt;/span&gt;.NewGuid().ToString(&lt;span class="code_text"&gt;&amp;quot;N&amp;quot;&lt;/span&gt;).Substring(0, &lt;span class="code_classes"&gt;CaptchaImage&lt;/span&gt;.TextLength);
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;HttpContext&lt;/span&gt;.Current.Session[&lt;span class="code_text"&gt;&amp;quot;captchaText&amp;quot;&lt;/span&gt;] = result;
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;return&lt;/span&gt; result;
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; }
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;static&lt;/span&gt; &lt;span class="code_keywords"&gt;void&lt;/span&gt; ResetCaptcha()
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;HttpContext&lt;/span&gt;.Current.Session[&lt;span class="code_text"&gt;&amp;quot;captchaText&amp;quot;&lt;/span&gt;] = &lt;span class="code_keywords"&gt;null&lt;/span&gt;;
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; }
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;static&lt;/span&gt; &lt;span class="code_classes"&gt;Bitmap&lt;/span&gt; RenderImage()
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;CaptchaImage&lt;/span&gt; ci = &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;CaptchaImage&lt;/span&gt;()
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Text = GetCaptchaString()
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;return&lt;/span&gt; ci.RenderImage();
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; }
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;static&lt;/span&gt; &lt;span class="code_keywords"&gt;bool&lt;/span&gt; IsValid
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;get&lt;/span&gt;
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;string&lt;/span&gt; request = &lt;span class="code_classes"&gt;HttpContext&lt;/span&gt;.Current.Request[&lt;span class="code_text"&gt;&amp;quot;captchaText&amp;quot;&lt;/span&gt;];
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;string&lt;/span&gt; user = &lt;span class="code_classes"&gt;HttpContext&lt;/span&gt;.Current.Session[&lt;span class="code_text"&gt;&amp;quot;captchaText&amp;quot;&lt;/span&gt;] &lt;span class="code_keywords"&gt;as&lt;/span&gt; &lt;span class="code_keywords"&gt;string&lt;/span&gt;;
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;return&lt;/span&gt; request == user;
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; }
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	}
	&lt;/p&gt;
	 
	&lt;/div&gt;
	 &lt;/li&gt; 
	&lt;li&gt; 
	&lt;p&gt;
	 יצרתי מחלקה שתשמש כ ActionFilter , למרות שאתם יכולים כמובן לדלג עליה ולדחוף את הקוד שבה ישירות לקונטרולר שבו אתם רוצים את הבדיקה.
	&lt;/p&gt;
	  
	&lt;p&gt;
	הדבר היחיד שאנו עושים כאן זה לתפוס את הבקשה לפני שהיא מגיעה ל action, ואם ה captcha לא תקין, להחזיר הודעת שגיאה לדפדפן. במקרה שלי זה הודעה בפורמט JSON לפניה מאג&amp;#39;קס, אבל כמובן שהתוצאה יכולה להיות כל ActionResult אחר.
	&lt;/p&gt;
	   
	&lt;div class="code_area"&gt;
	   
	&lt;p class="code_line"&gt;
	&amp;nbsp; &lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;class&lt;/span&gt; &lt;span class="code_classes"&gt;ValidateCaptchaAttribute&lt;/span&gt; : &lt;span class="code_classes"&gt;ActionFilterAttribute&lt;/span&gt;
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;override&lt;/span&gt; &lt;span class="code_keywords"&gt;void&lt;/span&gt; OnActionExecuting(&lt;span class="code_classes"&gt;ActionExecutingContext&lt;/span&gt; filterContext)
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;if&lt;/span&gt; (!&lt;span class="code_classes"&gt;CaptchaManager&lt;/span&gt;.IsValid)
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; filterContext.Result = &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;JsonResult&lt;/span&gt;() { Data = &lt;span class="code_keywords"&gt;new&lt;/span&gt; { error = &lt;span class="code_text"&gt;&amp;quot;true&amp;quot;&lt;/span&gt; } };
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;return&lt;/span&gt;;
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;base&lt;/span&gt;.OnActionExecuting(filterContext);
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; }
	&lt;/p&gt;
	 
	&lt;/div&gt;
	 &lt;/li&gt; 
	&lt;li&gt; 
	&lt;p&gt;
	 מה נשאר לנו? נשאר לכתוב את קוד ה Html ולשלוח את התמונה פיזית לדף. לצורך יצירת התמונה ושליחתה לדף, יצרתי קונטרולר נוסף שזה כל הקוד שלו:
	&lt;/p&gt;
	  
	&lt;div class="code_area"&gt;
	   
	&lt;p class="code_line"&gt;
	&amp;nbsp;&lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;class&lt;/span&gt; &lt;span class="code_classes"&gt;CaptchaController&lt;/span&gt; : &lt;span class="code_classes"&gt;Controller&lt;/span&gt;
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_classes"&gt;FileResult&lt;/span&gt; Index()
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;using&lt;/span&gt; (&lt;span class="code_classes"&gt;Bitmap&lt;/span&gt; b = &lt;span class="code_classes"&gt;CaptchaManager&lt;/span&gt;.RenderImage())
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;var&lt;/span&gt; ms = &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;MemoryStream&lt;/span&gt;();
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b.Save(ms, &lt;span class="code_classes"&gt;ImageFormat&lt;/span&gt;.Gif);
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;return&lt;/span&gt; File(ms.ToArray(), &lt;span class="code_text"&gt;&amp;quot;image/png&amp;quot;&lt;/span&gt;);
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_classes"&gt;JsonResult&lt;/span&gt; Render()
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;CaptchaManager&lt;/span&gt;.ResetCaptcha();
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;return&lt;/span&gt; Json(&lt;span class="code_keywords"&gt;new&lt;/span&gt; { success = &lt;span class="code_text"&gt;&amp;quot;true&amp;quot;&lt;/span&gt; });
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
	&lt;/p&gt;
	    
	&lt;p class="code_line"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; }
	&lt;/p&gt;
	 
	&lt;/div&gt;
	  
	&lt;p&gt;
	הוא עושה 2 פעולה &amp;ndash; הפעולה הראשונה, והיא חובה, זה יצירת תמונה ושליחתה לדפדפן. השניה זו תוספת שאיננה חובה, אבל אני רוצה שתהיה אפשרות למשתמשים לרנדר תמונה חדשה אם הם לא מצליחים לקרוא מה כתוב בתמונה הנוכחית, אז הוספתי פעולה ל ajax שתוכל פשוט לרנדר טקסט חדש, ובדף עצמו אני מוסיף לינק ליד התמונה שעושה 2 דברים:
	&lt;/p&gt;
	  
	&lt;p&gt;
	א. פונה לשרת כדי לאפס את הטקס (זו הפעולה שאנו רואים פה Render)
	&lt;/p&gt;
	  
	&lt;p&gt;
	ב. טוען את המקור של התמונה שוב (פשוט לתת לתמונה src אחר), ואז כשהיא תגיע לשרת כדי לקבל את התמונה , ממילא תתקבל התמונה עם הטקסט החדש
	&lt;/p&gt;
	 &lt;/li&gt; 
	&lt;li&gt; 
	&lt;p&gt;
	 בואו נראה את קוד ה HTML
	&lt;/p&gt;
	  
	&lt;div class="code_area"&gt;
	   
	&lt;p&gt;
	&amp;lt;table&amp;gt;
	&lt;/p&gt;
	    
	&lt;p&gt;
	&amp;lt;tr&amp;gt;      &lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;td&amp;gt;       &lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;img src=&amp;quot;&amp;lt;%=Url.Action(&amp;quot;Index&amp;quot;, &amp;quot;Captcha&amp;quot;) %&amp;gt;&amp;quot; alt=&amp;quot;captcha&amp;quot;&amp;nbsp; name=&amp;quot;captchaImages&amp;quot; /&amp;gt;&amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; onclick=&amp;quot;renderCaptcha();return false;&amp;quot;&amp;gt;a&amp;lt;/a&amp;gt;       &lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/td&amp;gt;       &lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;td&amp;gt;       &lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;txtReplyCaptchaText&amp;quot; name=&amp;quot;captchaText&amp;quot;/&amp;gt;       &lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;span&amp;gt;Enter the text in the image&amp;lt;/span&amp;gt;       &lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/td&amp;gt;       &lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/tr&amp;gt;
	&lt;/p&gt;
	    
	&lt;p&gt;
	&amp;lt;/table&amp;gt;
	&lt;/p&gt;
	 
	&lt;/div&gt;
	  
	&lt;p&gt;
	6. ונשאר רק פונקציה ב javascript למי שרוצה אפשרות לרנדר מחדש את התמונה 
	&lt;/p&gt;
	  
	&lt;div class="code_area"&gt;
	   
	&lt;p&gt;
	&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;      &lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;!--       &lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; function renderCaptcha() {       &lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $.ajax({       &lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; type: &amp;#39;post&amp;#39;,       &lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; url: &amp;#39;&amp;lt;%=Url.Action(&amp;quot;Render&amp;quot;, &amp;quot;Captcha&amp;quot;) %&amp;gt;&amp;#39;,       &lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; success: function(j) {       &lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var src = &amp;#39;&amp;lt;%=Url.Action(&amp;quot;Index&amp;quot;, &amp;quot;Captcha&amp;quot;) %&amp;gt;?r=&amp;#39; + Math.random();       &lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; document.getElementById(&amp;#39;captchaImage&amp;#39;).src=src;       &lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }, error: function(err) {       &lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; alert(&amp;#39;Error&amp;#39;);       &lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }       &lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; })       &lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }       &lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; --&amp;gt;       &lt;br /&gt;
	&amp;lt;/script&amp;gt;
	&lt;/p&gt;
	    
	&lt;p&gt;
	&amp;nbsp;
	&lt;/p&gt;
	 
	&lt;/div&gt;
	  
	&lt;p&gt;
	אז כמו שאמרתי הפונקציה פונה לשרת כדי לאפס את הטקסט,&amp;nbsp; ואז רק נשאר לתת לתמונה source חדש, שהוא בעצם אותו source כי הרי המיקום של הקונטרולר שלנו לא השתנה, אלא שאני מוסיף לו מספר רנדומלי כדי להכריח את הדפדפן לרפרש את התמונה
	&lt;/p&gt;
	  
	&lt;p&gt;
	שימו לב ששם תיבת הטקסט הוא קבוע &amp;ldquo;captchaText&amp;rdquo; , כדי שהפילטר שלנו&amp;nbsp; ידע מה לחפש 
	&lt;/p&gt;
	 &lt;/li&gt; 
&lt;/ol&gt;
 
&lt;p&gt;
חיסרון אחד בשיטה שלי לעומת המאמר המקורי הוא שאצלנו שם התמונה הוא כתובת של קונטרולר, ואם תרצו לשים של תמונה עם סיומת תקינה (jpg, gif( אז תצטרכו לשחק בטבלת המיפויים של האפליקציה, לי זה לא&amp;nbsp; מפריע שהשם הוא כזה ולכן לא נגעתי בזה.
&lt;/p&gt;
  
&lt;p&gt;
&lt;a href="http://www.talgiladi.net/examples/mvcCaptcha.zip" title="Sample project"&gt;להורדת פרוייקט דוגמה&lt;/a&gt;
&lt;/p&gt;
</description>
      <link>http://blog.talgiladi.net/post/Captcha.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/Captcha.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=da444c8d-cdb2-4b81-aec9-582ea06e0244</guid>
      <pubDate>Fri, 27 Feb 2009 13:33:00 +0400</pubDate>
      <category>MVC</category>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=da444c8d-cdb2-4b81-aec9-582ea06e0244</pingback:target>
      <slash:comments>2</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=da444c8d-cdb2-4b81-aec9-582ea06e0244</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/Captcha.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=da444c8d-cdb2-4b81-aec9-582ea06e0244</wfw:commentRss>
    </item>
    <item>
      <title>ומה אתם הייתם עושים...?</title>
      <description>&lt;div style="direction: rtl"&gt;
&lt;p align="right"&gt;
אם לקוח גדול היה מסכים לקנות את האפליקציה רק בתנאי שחלק מהמודולים יעבוד עם דוט נט 2.0 כי הוא לא יכול להתקין את גירסה 3.5?
&lt;/p&gt;
&lt;p align="right"&gt;
אז כמובן שתמיד יושבים ומסבירים ללקוחות את הדרישות והאריכטקטורה הנדרשים כדי להריץ את האפליקציה, והם מסכימים פחות או יותר, אבל הפעם... אין אפשרות להתקין על חלק מהשרתים את הגירסה החדשה...
&lt;/p&gt;
&lt;p align="right"&gt;
אז קיבלתי הוראה שהלקוח הזה כל כך חשוב, ושאני פשוט צריך לעשות הכל כדי שזה יעבוד, כולל לייצר לו גירסה מיוחדת, לא משנה איך... נחמד אה?
&lt;/p&gt;
&lt;p align="right"&gt;
שכבת הrepository שלנו עובדת עם דוט נט 2, ה services דוט נט 3, והמודולים שהוא רוצה עובדים עם 2, רק הבעיה כמובן היא שהיא פונים לשכבת ה services ... אז היו לי כמה אופציות, כמובן שכולם לא טובות. אחת הייתה לחלק את שיכבת הservices לשתי שכבות נפרדות, כך שהקוד שמשתמש בגירסה 3 יהיה מלמעלה ואז ניתן יהיה להשתמש בשאר השירותים בשכבה התחתונה יותר, אבל כמובן שזה דפוק... זה כמו לחצות DLL לשניים ולעשות כאילו זה צורך ארכטיקטיוני... אז ויתרתי.
&lt;/p&gt;
&lt;p align="right"&gt;
אחר כך חשבתי פשוט שהמודולים האלה יפנו ישירות ל repository, שוב, אני יודע שזה לא נכון, אבל אין ברירה, וחוץ מזה אין בהם כל הרבה business logic שאני צריך את כל הפניות לשיכבת&amp;nbsp; ה services, ואכן התחלתי לבצע, עד שהבנתי שלא רק שאני אצטרך לשכפל קוד (!!!) אלא שה IOC שלי שנמצא בשכבת ה services יצטרך להשתכפל גם!! ואיפה אני אשים אותו? 
&lt;/p&gt;
&lt;p align="right"&gt;
בסוף אמרתי, גם ככה אני אצטרך לעשות עבודה של חמור, אז כנראה שהכי טוב זה פשוט לגרום ל services לעבוד עם גירסה 2... וככה עשיתי, התחלתי מה Linq היקרים שהפכו לשורות קוד שאני כתבתי, וכלה ב extension methods שפשוט הפכתי למתודות סטטיות ועל שאר הדברים הקטנים פשוט ויתרתי...&amp;nbsp; 
&lt;/p&gt;
&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:a3ae2e20-34d3-4f90-b353-e0128a699dc0" class="wlWriterEditableSmartContent" style="margin: 0px; padding: 0px; float: none; display: inline"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/refactoring"&gt;refactoring&lt;/a&gt;
&lt;/div&gt;
&lt;p align="right"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <link>http://blog.talgiladi.net/post/d795d79ed794-d790d7aad79d-d794d799d799d7aad79d-d7a2d795d7a9d799d79d.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/d795d79ed794-d790d7aad79d-d794d799d799d7aad79d-d7a2d795d7a9d799d79d.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=5fb17b87-65f9-43ea-9c7b-e95b7174a092</guid>
      <pubDate>Sun, 15 Feb 2009 14:38:00 +0400</pubDate>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=5fb17b87-65f9-43ea-9c7b-e95b7174a092</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=5fb17b87-65f9-43ea-9c7b-e95b7174a092</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/d795d79ed794-d790d7aad79d-d794d799d799d7aad79d-d7a2d795d7a9d799d79d.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=5fb17b87-65f9-43ea-9c7b-e95b7174a092</wfw:commentRss>
    </item>
    <item>
      <title>Continuous Integration</title>
      <description>&lt;p&gt;
הרבה פיקסלים נשפכו כבר על הנושא בדפי האינטרנט, מי שירצה לקרוא תיאוריה יכול למצוא &lt;a href="http://martinfowler.com/articles/continuousIntegration.html" target="_blank"&gt;כאן&lt;/a&gt; וכמובן בגוגל. אבל בכל זאת גיליתי שיש דברים שעדיין לא כל כך לבצע, אז החלטתי לכתוב כמה פוסטים מסכמים על העניין.
&lt;/p&gt;
&lt;p&gt;
רק בקיצור נמרץ נזכיר שמדובר על שיטת עבודה שבה התיכנות שלנו משולב באופן שוטף בפרוייקט הכולל, מה שהוא שכל קוד שכתבנו ועשינו צ&amp;rsquo;ק אין לשרת, עובר קימפול ביחד עם שאר הקוד באפליקציה (שלא שינינו משהו בפרוייקט אחד, ופרוייקט אחר שתלוי בו עכשיו לא יתקפמל), עובר את כל הטסטים ( כדי לבדוק שלא דפקנו שום דבר בדרך), ובדיקה שאכן הטקסטים שלנו בודקים את כל הקוד ושלא שכחנו לבדוק את הקוד החדש (אלא אם כן אתם מאלו שלא כותבים קוד לפני שכותבים את הבדיקה :))
&lt;/p&gt;
&lt;p&gt;
מה יוצא לנו מזה? ביטחון, עד כמה שאפשר, שבכל רגע הקוד שנמצא בצ&amp;rsquo;ק אין עובד עם כל האפליקציה, ושבכל רגע יש לנו גירסה עדכנית אם אנו רוצים.
&lt;/p&gt;
&lt;p&gt;
איך עושים את זה? פשוט מאוד, יש תוכנות להורדה, שעוקבות אחרי שינויים שאנו עושים בקוד, או שרצות בזמנים קבועים (כל לילה למשל) ומקמפלות את הקוד, מריצות בדיקות, ועוד כמה דברים נחמדים.
&lt;/p&gt;
&lt;p&gt;
שתי התוכנות העיקריות הן &lt;a href="http://cruisecontrol.sourceforge.net/" target="_blank"&gt;cruise control&lt;/a&gt; שהיא תוכנת קוד פתוח, ו &lt;a href="http://www.jetbrains.com/teamcity/" target="_blank"&gt;team city&lt;/a&gt; שהיא תוכנה עם רשיון, אך גירסה ה professional&amp;nbsp; שלה היא בחינם עד ל 20 משתמשים (תבדקו בדיוק את הפרטים שם).
&lt;/p&gt;
&lt;p&gt;
לצורך הדוגמאות בחרתי להשתמש ב team city.
&lt;/p&gt;
&lt;p&gt;
1. ההתקנה די פשוטה, יש הוראות באתר שלהם. מה שכן, עדיף לבחור פורט אחר ולא הדיפולטי שלהם שהוא 80
&lt;/p&gt;
&lt;p&gt;
2. לאחר ההתקנה נעשה לוגין, וניגש ליצירת פרוייקט חדש
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.talgiladi.net/image.axd?picture=WindowsLiveWriter/ContinuousIntegration/399B49C0/createProject.jpg"&gt;&lt;img style="display: inline; border-width: 0px" src="http://blog.talgiladi.net/image.axd?picture=WindowsLiveWriter/ContinuousIntegration/75135AD3/createProject_thumb.jpg" border="0" alt="createProject" title="createProject" width="152" height="52" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
3. לאחר היצירת הפרוייקט נתחיל בהגדרות
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.talgiladi.net/image.axd?picture=WindowsLiveWriter/ContinuousIntegration/496290D7/buildConfiguration.jpg"&gt;&lt;img style="display: inline; border-width: 0px" src="http://blog.talgiladi.net/image.axd?picture=WindowsLiveWriter/ContinuousIntegration/44EC1010/buildConfiguration_thumb.jpg" border="0" alt="buildConfiguration" title="buildConfiguration" width="199" height="32" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
4. תנו שם לפרוייקט, ותיאור אפשרי. אפשר להשאיר את השאר ריק
&lt;/p&gt;
&lt;p&gt;
5. הקליקו על &amp;ldquo;&lt;strong&gt;VCS Settings&lt;/strong&gt;&amp;rdquo; כדי להגדיר את הסורס קונטרול.
&lt;/p&gt;
&lt;p&gt;
אני משתמש ב Visual Source Safe, אז אם יש לכם סוג אחר, תצטרכו לחפש את ההגדרות המתאימות&amp;hellip;
&lt;/p&gt;
&lt;p&gt;
תבחרו את סוג השרת:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href="http://blog.talgiladi.net/image.axd?picture=WindowsLiveWriter/ContinuousIntegration/2B840CD6/sourceControlType.jpg"&gt;&lt;img style="display: inline; border-width: 0px" src="http://blog.talgiladi.net/image.axd?picture=WindowsLiveWriter/ContinuousIntegration/7FD342D9/sourceControlType_thumb.jpg" border="0" alt="sourceControlType" title="sourceControlType" width="244" height="43" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
בנתיב לקובץ srcsafe.ini שים את הנתיב&amp;nbsp; המלא לקובץ של כל הסורס סייף, לאו דווקא הפרוייקט הנוכחי. אם הוא נמצא על שרת פשוט הקלידו את הנתיב לשרת:
&lt;/p&gt;
&lt;p style="direction: ltr" align="left"&gt;
&lt;a href="file://\\ServerName\directory\srcsafe.ini"&gt;\\ServerName\directory\srcsafe.ini&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
עבור הפרוייקט תכתבו את השם של הפרוייקט (שימו לב- פרוייקט, ולא סולושן) שעבורו אנו בונים את הקונפיגורציה הנוכחית, כמו שהוא מופיע ב GUI של הסורס סייף &amp;ndash; אם אתם משתמשים בשמות דיפולטים בדרך כלל אז זה יהיה משהו כזה:
&lt;/p&gt;
&lt;p style="direction: ltr" align="left"&gt;
$/ProjectName.root/ProjectName
&lt;/p&gt;
&lt;p&gt;
מלאו את שם המשתמש והסיסמה שלכם עבור הסורס סייף ואתם יכולים לבדוק אם הפרטים נכונים על ידי הקלקה על &amp;ldquo;Test Connection&amp;rdquo;. כמובן ללחוץ על שמירה בסוף.
&lt;/p&gt;
&lt;p&gt;
6. כעת נבחר את דרך קימפול ובניית הפרוייקט. תלחצו על הלינק Runner&amp;nbsp; שיש בצד:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.talgiladi.net/image.axd?picture=WindowsLiveWriter/ContinuousIntegration/4B35774F/selectRunner.jpg"&gt;&lt;img style="display: inline; border: 0px" src="http://blog.talgiladi.net/image.axd?picture=WindowsLiveWriter/ContinuousIntegration/589B8A55/selectRunner_thumb.jpg" border="0" alt="selectRunner" title="selectRunner" width="244" height="106" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
לשם התחלה נבחר במה שאנו מכירים &amp;ndash; שזה sln2005 או sln2008 תלוי באיזה גירסה של ויז&amp;#39;ואל סטודיו אתם משתמשים.
&lt;/p&gt;
&lt;p&gt;
בתיבת הטקסט הראשונה (solution file path)תכניסו את שם הסולושן שזה ProjectName.sln בדרך כלל.
&lt;/p&gt;
&lt;p&gt;
בתיבה working directory תכניסו את שם התיקיה בה נמצא הפרוייקט, שזה בדרך כלל פשוט שם הפרוייקט.
&lt;/p&gt;
&lt;p&gt;
בתיבה Targets תכתבו Rebuild
&lt;/p&gt;
&lt;p&gt;
שמירה ואתם מוכנים לצאת לדרך!
&lt;/p&gt;
&lt;p&gt;
בצד ימין למעלה יש כפתור עם המילה Run, תלחצו עליו
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.talgiladi.net/image.axd?picture=WindowsLiveWriter/ContinuousIntegration/3409FCD1/clickRun.jpg"&gt;&lt;img style="display: inline; border: 0px" src="http://blog.talgiladi.net/image.axd?picture=WindowsLiveWriter/ContinuousIntegration/15BF45DB/clickRun_thumb.jpg" border="0" alt="clickRun" title="clickRun" width="405" height="149" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
עכשיו תלחצו על הטאב הגדול בצד שמאל בשם Projects &amp;ndash; שם מופיעים כל הפרוייקטים שלנו, שזה כרגע רק אחד בעצם. אתם יכולים לראות 
&lt;/p&gt;
&lt;p&gt;
את תהליך הריצה והבניה. אם הכל עבד תקין יהיה לנו V ירוק ונחמד
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.talgiladi.net/image.axd?picture=WindowsLiveWriter/ContinuousIntegration/77748EE4/runSuccess.jpg"&gt;&lt;img style="display: inline; border: 0px" src="http://blog.talgiladi.net/image.axd?picture=WindowsLiveWriter/ContinuousIntegration/72FE0E1D/runSuccess_thumb.jpg" border="0" alt="runSuccess" title="runSuccess" width="169" height="57" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
אם לא, אז תלחצו על הודעת השגיאה כדי לראות את הלוג ומה לא עבד.
&lt;/p&gt;
&lt;p&gt;
מה שבעצם קורה הוא שכל קבצי הפרוייקט נמשכים מה source control לתיקיה זמנית, ושם מקומפלים בהתאם להגדרות. המטרה שלנו כרגע היא לדעת שתמיד יש לנו אפליקציה שמתקמפלת.
&lt;/p&gt;
&lt;p&gt;
אם ירצה השם&amp;nbsp; בפעם הבאה נוסיף גם תיזמונים וטריגרים לקימפול, וכן נוסיף הרצה של הבדיקות שלנו כדי לדעת שלא רק שהכל מתקמפל, אלא שגם לא הרסנו שום דבר בשינוי האחרון שעשינו לקוד.
&lt;/p&gt;
&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:5b7d7f92-cfcc-4a97-91ed-8c4a543a3cc9" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/continous+integration"&gt;continous integration&lt;/a&gt;
&lt;/div&gt;
</description>
      <link>http://blog.talgiladi.net/post/Continuous-Integration.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/Continuous-Integration.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=8b7fc8d4-eef2-4040-8df9-063a7439b3dc</guid>
      <pubDate>Thu, 29 Jan 2009 10:41:00 +0400</pubDate>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=8b7fc8d4-eef2-4040-8df9-063a7439b3dc</pingback:target>
      <slash:comments>2</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=8b7fc8d4-eef2-4040-8df9-063a7439b3dc</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/Continuous-Integration.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=8b7fc8d4-eef2-4040-8df9-063a7439b3dc</wfw:commentRss>
    </item>
    <item>
      <title>הנסיון שלי עם StructureMap</title>
      <description>&lt;p&gt;
לא היה כל כך טוב בפעם האחרונה&amp;hellip;
&lt;/p&gt;
  
&lt;p&gt;
האמת היא שאני מאוד אוהב לעבוד עם התוכנה הזאת, ולא באתי להגיד דברים רעים, אבל כדי לחסוך מכם ניסיון מר אני אחלוק אתכם מה שעברתי לפני כמה ימים&amp;hellip;
&lt;/p&gt;
  
&lt;p&gt;
בניתי לאשתי איזה אתר קטן, ולאחר מחשבות הגיע למסקנה שיתכן שהוא יגדל ונצטרך לשנות דברים אז כדאי להשתמש ב dependency injection. מכיוון שאני מכיר את &lt;a href="http://structuremap.sourceforge.net/Default.htm"&gt;StructureMap&lt;/a&gt; ודי אוהב לעבוד איתו אז כמובן שבחרתי בו. 
&lt;/p&gt;
  
&lt;p&gt;
טרחתי אפילו לבדוק באתר שלהם שאין בעיה להריץ על שרת אירוח משותף.
&lt;/p&gt;
  
&lt;p&gt;
טוב, אז עשיתי כמה רפקטורים לקוד, בדרך שיניתי עוד כמה דברים,&amp;nbsp; העליתי לשרת, וקיבלתי את דף השגיאה&amp;hellip; שיניתי בווב קונפיג כדי שיציג את השגיאה והתברר שהאסמבלי של &lt;a href="http://structuremap.sourceforge.net/Default.htm"&gt;StructureMap&lt;/a&gt;&amp;nbsp; לא יכול לעבוד בסביבה שלא מאפשרת הרשאות מלאות&amp;hellip; 
&lt;/p&gt;
  
&lt;p&gt;
&lt;strong&gt;System.Security.SecurityException: That assembly does not allow partially trusted callers.&lt;/strong&gt;
&lt;/p&gt;
  
&lt;p&gt;
ניגשתי לגוגל, התברר שאני לא היחיד עם הבעיה, ניגשתי שוב לאתר שלהם כדי לבדוק שוב שאכן ניתן להריץ גם על שרת משותף ללא כל ההרשאות&amp;hellip;
&lt;/p&gt;
  
&lt;p&gt;
טוב, השארתי לבחור ההוא &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2008/11/30/a-gentle-quickstart-for-structuremap-2-5.aspx#186822"&gt;הודעה&lt;/a&gt; בבלוג אבל בינתיים אני בלי אפליקציה&amp;hellip; 
&lt;/p&gt;
  
&lt;p&gt;
כמובן שלא היה לי גיבוי די מעודכן, וגם לא רציתי למחוק את השינויים הנוספים שעשיתי, אז מהר הלכתי לחפש כלי חלופי. 
&lt;/p&gt;
  
&lt;p&gt;
מצאתי את &lt;a href="http://ninject.org/"&gt;NInject&lt;/a&gt;, בדקתי שניתן להריץ על שרת משותף, הורדתי , מהר התאמתי את הקוד שלי, ו&amp;hellip; 
&lt;/p&gt;
  
&lt;p&gt;
&lt;strong&gt;System.Runtime.CompilerServices.ExtensionAttribute&amp;#39; is defined in      &lt;br /&gt;
multiple assemblies in the global alias; using definition from &amp;#39;c:\xxx       &lt;br /&gt;
\Ninject-1.0-release-net-2.0\Ninject.Core.dll&lt;/strong&gt;
&lt;/p&gt;
  
&lt;p&gt;
מתברר שיש להם איזה &lt;a href="http://groups.google.com/group/ninject/browse_thread/thread/656ab431c67c7be5"&gt;באג&lt;/a&gt; שכדי שהתוכנה שלהם תוכל לרוץ עם דוט נט גירסה 3.5 צריך להוריד את המקור , לעשות כמה שינויים ולקמפל מחדש, שזה אולי לא סיפור גדול אבל זה עדיין לא מובטח שזה יעבוד, וגם הייתי כבר די לחוץ כך שזה ממש לא התאים באותו רגע. 
&lt;/p&gt;
  
&lt;p&gt;
חזרה לגוגל, מצאתי משהו נחמד בשם &lt;a href="http://code.google.com/p/autofac/"&gt;Autofac&lt;/a&gt;, שוב בדקתי שניתן להריץ, הורדתי, התאמתי את הקוד, העליתי לשרת, ו&amp;hellip; אכן עלה הדף הראשי!!!
&lt;/p&gt;
  
&lt;p&gt;
טוב, אני מתחיל לבצע כמה פעולות ומקבל הודעת שגיאה, משהו בקוד שלי לא תקין&amp;hellip; מוזר&amp;hellip; הכל עבד ונבדק&amp;hellip; טוב, אולי עם כל השינויים דפקתי משהו, מסדר את זה אצלי על המחשב ומתחיל שוב בדיקות מקומיות.
&lt;/p&gt;
  
&lt;p&gt;
אני עובד עם MVC, ואם אני מקבל הודעת שגיאה ש Action מצפה לפרמטר ID ולא קיבל אותו, ואני רואה בדיבאג שהפרמטר שם, משהו קצת מוזר&amp;hellip;
&lt;/p&gt;
  
&lt;p&gt;
טוב, חשבתי לעצמי, עכשיו זמן לחץ אין זמן לבדוק את זה, פשוט תוריד את הפרמטר מהמתודה ותקרא אותו בפנים בעצמך מתוך ה Request, וכשיהיה זמן נחקור את זה. עשיתי.
&lt;/p&gt;
  
&lt;p&gt;
ממשיך לרוץ באפליקציה, שוב שגיאה&amp;hellip; שוב פרמטר חסר, שוב מתקן וחושב לעצמי, איזה מתכנת אתה&amp;hellip;
&lt;/p&gt;
  
&lt;p&gt;
ממשיך לרוץ, עכשיו ה UpdateModel מעדכן ערכים ריקים, לא זורק שגיאה, פשוט שם ערכים ריקים&amp;hellip;
&lt;/p&gt;
  
&lt;p&gt;
הראש כבר לא עובד טוב אז נפטרתי גם מ UpdateModel ועדכנתי ידנית&amp;hellip;
&lt;/p&gt;
  
&lt;p&gt;
וכך עוד דבר ועוד דבר&amp;hellip;
&lt;/p&gt;
  
&lt;p&gt;
עד שנפל האסימון!
&lt;/p&gt;
  
&lt;p&gt;
זה לא אני! זה Autofac! איכשהו היא מצליחה לדפוק את הנתונים שמגיעים לקונטרולרים שלי!! 
&lt;/p&gt;
  
&lt;p&gt;
אולי לא הגדרתי לא טוב, אין לי מושג, זה גם לא כל כך משנה לי, פשוט זה לא אמור לקרות!! היא בסדר הכל אמורה לספק פרמטרים לקונסטרוקטור וליצור אובייקט, עובדה שזה עבר תקין עם StructureMap אצלי על המחשב!
&lt;/p&gt;
  
&lt;p&gt;
החלטתי לבדוק את החשד שלי, הורדתי את Autofac&amp;nbsp; עבור קונטרולר אחד, ואכן! גם הפרמטרים מגיעים, גם ה UpdateModel חזר לעדכן ועוד כמה דברים מוזרים חזרו להיות תקינים!
&lt;/p&gt;
  
&lt;p&gt;
מהר הורדתי את Autofac וחזרתי לשיטה הפרימיטיבית שבה הכל עבד!
&lt;/p&gt;
  
&lt;p&gt;
לסיכום אין לי מה להגיד חוץ מהדברים הרגילים שתמיד אני אומר לעצמי- תכין גיבויים קבועים ולפני כל שינוי ולעשות בדיקת היתכנות לפני שימוש במשהו חדש&amp;hellip;
&lt;/p&gt;
  
&lt;p&gt;
בכל מקרה אני חושב StructureMap זה מוצר מעולה, מאוד נוח לעבוד איתו, הוא מהיר ויש בו די הרבה אפשרויות. גם Autofac נראה לי נחמד ממה שהספקתי לקרוא באותו הערב, למרות שלא יצא לעבוד איתו&amp;hellip;
&lt;/p&gt;
  
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
 &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a rel="me" href="http://technorati.com/claim/r8syy9cqk2"&gt;Technorati Profile&lt;/a&gt;   
&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:1e7a67ac-1264-4c63-b679-be441b193583" class="wlWriterEditableSmartContent" style="margin: 0px; padding: 0px; float: none; display: inline"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/ioc"&gt;ioc&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/dependency+injection"&gt;dependency injection&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/structure+map"&gt;structure map&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/autofac"&gt;autofac&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/ninject"&gt;ninject&lt;/a&gt;
&lt;/div&gt;
</description>
      <link>http://blog.talgiladi.net/post/d794d7a0d7a1d799d795d79f-d7a9d79cd799-d7a2d79d-StructureMap.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (tal)</author>
      <comments>http://blog.talgiladi.net/post/d794d7a0d7a1d799d795d79f-d7a9d79cd799-d7a2d79d-StructureMap.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=9c5ed8ed-9a9b-4940-83fd-473efb938b3e</guid>
      <pubDate>Fri, 09 Jan 2009 13:20:00 +0400</pubDate>
      <category>IOC</category>
      <dc:publisher>tal</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=9c5ed8ed-9a9b-4940-83fd-473efb938b3e</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=9c5ed8ed-9a9b-4940-83fd-473efb938b3e</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/d794d7a0d7a1d799d795d79f-d7a9d79cd799-d7a2d79d-StructureMap.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=9c5ed8ed-9a9b-4940-83fd-473efb938b3e</wfw:commentRss>
    </item>
    <item>
      <title>Copy source as HTML</title>
      <description>&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:7788c980-3fad-4c92-8327-b65c4bc56648" class="wlWriterEditableSmartContent" style="margin: 0px; padding: 0px; float: none; display: inline"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/programs"&gt;programs&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/visual+studio+addin"&gt;visual studio addin&lt;/a&gt;
&lt;/div&gt;
  
&lt;p&gt;
למי שלא מכיר, התוכנה הינה תוסף לויזו&amp;#39;אל סטודיו שמאפשרת בלחצן ימני פשוט להעתיק את כל הטקסט שמופיע ולשמור אותו בתור HTML כולל העיצוב והצבעים המקוריים, עם זה בעצם משתמשים הרבה (כולל אותי...) כשרוצים להציג דוגמאות קוד בדף HTML.
&lt;/p&gt;
  
&lt;p&gt;
שיפצרתי קצת את &lt;a href="http://www.jtleigh.com/people/colin/software/CopySourceAsHtml/" title="copy as html source"&gt;המקור&lt;/a&gt; &amp;ndash; קצת הפריע לי שבכל פעם הוא יוצר שמות אחרים ל css class שהוא נותן שם, והאופציה השניה שם היא פשוט לדחוף את כל הסטייל ישירות ל HTML, שזה מפוצץ את גודל הדף וגם מונע שינויים עתידיים, אז הוספתי שם שאם כבר הוא השתמש באיזה css class בעבר אזי הוא ישתמש בה שוב עבור אותו סטייל, וגם שניתן יהיה לערוך את השמות שהוא נותן לסטיילים. 
&lt;/p&gt;
  
&lt;p&gt;
&lt;a href="http://blog.talgiladi.net/image.axd?picture=renameCssClasses3.png"&gt;&lt;img style="border: 0px none ; display: inline" src="http://blog.talgiladi.net/image.axd?picture=renameCssClasses_thumb1.png" border="0" alt="renameCssClasses_thumb1" title="renameCssClasses_thumb1" width="416" height="150" /&gt;&lt;/a&gt; 
&lt;/p&gt;
  
&lt;p&gt;
לא הצלחתי ליצור קשר עם קולין קולר, זה שכתב את המקור, אז אני מקווה שלא איכפת לו...
&lt;/p&gt;
  
&lt;p&gt;
להורדת &lt;a href="http://www.talgiladi.net/examples/CopyAsHTMLSolution.zip" title="download solution"&gt;הפרוייקט&lt;/a&gt;
&lt;/p&gt;
  
&lt;p&gt;
להורדת &lt;a href="http://www.talgiladi.net/examples/CopyAsHTMLInstaller.zip" title="download installer"&gt;ההתקנה&lt;/a&gt;
&lt;/p&gt;
</description>
      <link>http://blog.talgiladi.net/post/Copy-source-as-HTML.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (tal)</author>
      <comments>http://blog.talgiladi.net/post/Copy-source-as-HTML.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=866f61a2-8a3f-4d61-8c55-2105c9494263</guid>
      <pubDate>Sat, 03 Jan 2009 13:29:00 +0400</pubDate>
      <category>tools</category>
      <dc:publisher>tal</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=866f61a2-8a3f-4d61-8c55-2105c9494263</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=866f61a2-8a3f-4d61-8c55-2105c9494263</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/Copy-source-as-HTML.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=866f61a2-8a3f-4d61-8c55-2105c9494263</wfw:commentRss>
    </item>
    <item>
      <title>Reflection for Unit Testing - update</title>
      <description>&lt;p&gt;
רק רציתי לעדכן &lt;a href="http://blog.talgiladi.net/post/Reflection-for-Unit-Testing.aspx" title="reflection for testing"&gt;פוסט מהעבר&lt;/a&gt; מתודה חדשה להשוואת אובייקטים בעת הבדיקות, משהו&amp;nbsp; יותר נחמד עם ג&amp;#39;נריקס
&lt;/p&gt;
&lt;p&gt;
להזכיר, רציתי להשוות שני אובייקטים &amp;ndash; אחד מה שהקוד החזיר ואחד זה מה שמצופה, אז כתבתי מתודה פשוטה שתשווה בין כל 2 אובייקטים.
&lt;/p&gt;
&lt;p&gt;
הוספתי בסוף אופציה להוריד בדיקה של חלק מהמאפיינים &amp;ndash; כמו למשל זמן יצירה&amp;nbsp; שיכול להיות שונה בדטה בייס:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p class="code_line"&gt;
&lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;static&lt;/span&gt; &lt;span class="code_keywords"&gt;void&lt;/span&gt; Compare&amp;lt;T&amp;gt;(T expected, T actual, &lt;span class="code_keywords"&gt;params&lt;/span&gt; &lt;span class="code_keywords"&gt;string&lt;/span&gt;[] exclude)
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;Assert&lt;/span&gt;.IsNotNull(expected);
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;Assert&lt;/span&gt;.IsNotNull(actual);
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;List&lt;/span&gt;&amp;lt;&lt;span class="code_keywords"&gt;string&lt;/span&gt;&amp;gt; p = &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;List&lt;/span&gt;&amp;lt;&lt;span class="code_keywords"&gt;string&lt;/span&gt;&amp;gt;();
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;if&lt;/span&gt; (exclude != &lt;span class="code_keywords"&gt;null&lt;/span&gt;)
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; p.AddRange(exclude);
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;foreach&lt;/span&gt; (&lt;span class="code_keywords"&gt;var&lt;/span&gt; pi &lt;span class="code_keywords"&gt;in&lt;/span&gt; &lt;span class="code_keywords"&gt;typeof&lt;/span&gt;(T).GetProperties())
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;if&lt;/span&gt; (p.SingleOrDefault(a =&amp;gt; a.Equals(pi.Name, &lt;span class="code_classes"&gt;StringComparison&lt;/span&gt;.InvariantCultureIgnoreCase)) != &lt;span class="code_keywords"&gt;null&lt;/span&gt;)
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;continue&lt;/span&gt;;
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;Assert&lt;/span&gt;.AreEqual(pi.GetValue(expected, &lt;span class="code_keywords"&gt;null&lt;/span&gt;), pi.GetValue(actual, &lt;span class="code_keywords"&gt;null&lt;/span&gt;), pi.Name);
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
והשימוש פשוט כמובן:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p class="code_line"&gt;
[&lt;span class="code_classes"&gt;TestMethod&lt;/span&gt;()]
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;static&lt;/span&gt; &lt;span class="code_keywords"&gt;void&lt;/span&gt; Test()
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;var&lt;/span&gt; a = &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;MailMessage&lt;/span&gt;()
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Subject = &lt;span class="code_text"&gt;&amp;quot;MYSubject&amp;quot;&lt;/span&gt;,
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Body = &lt;span class="code_classes"&gt;Guid&lt;/span&gt;.NewGuid().ToString()
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;var&lt;/span&gt; b = &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;MailMessage&lt;/span&gt;()
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Subject = &lt;span class="code_text"&gt;&amp;quot;MYSubject&amp;quot;&lt;/span&gt;,
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Body = &lt;span class="code_classes"&gt;Guid&lt;/span&gt;.NewGuid().ToString()
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Compare&amp;lt;&lt;span class="code_classes"&gt;MailMessage&lt;/span&gt;&amp;gt;(a, b, &lt;span class="code_keywords"&gt;null&lt;/span&gt;);&lt;span class="code_remarks"&gt;//will fail&lt;/span&gt;
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Compare&amp;lt;&lt;span class="code_classes"&gt;MailMessage&lt;/span&gt;&amp;gt;(a, b, &lt;span class="code_text"&gt;&amp;quot;Body&amp;quot;&lt;/span&gt;);&lt;span class="code_remarks"&gt;//will pass&lt;/span&gt;
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:7fab9e42-533e-4fcb-8df8-d8c61e5d2d75" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/Reflection"&gt;Reflection&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/UnitTesting"&gt;UnitTesting&lt;/a&gt;
&lt;/div&gt;
</description>
      <link>http://blog.talgiladi.net/post/Reflection-for-Unit-Testing-update.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/Reflection-for-Unit-Testing-update.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=19c73c33-f48f-4e76-9dca-eafe94c3fed4</guid>
      <pubDate>Thu, 04 Dec 2008 10:23:00 +0400</pubDate>
      <category>Reflection</category>
      <category>UnitTests</category>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=19c73c33-f48f-4e76-9dca-eafe94c3fed4</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=19c73c33-f48f-4e76-9dca-eafe94c3fed4</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/Reflection-for-Unit-Testing-update.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=19c73c33-f48f-4e76-9dca-eafe94c3fed4</wfw:commentRss>
    </item>
    <item>
      <title>Liskov Substitution Principle</title>
      <description>&lt;p&gt;
או בעברית משהו כמו &amp;ldquo;עיקרון החילופין של ליסקוב&amp;rdquo;- אחד מהעקרונות של תכנות מונחה אובייקטים, שאומר בעצם:
&lt;/p&gt;
&lt;p&gt;
אם אני יורש ממחלקת אם, ודורס אחת מהמתודות שלה (overide), הלקוח שמשתמש בקוד שלי, צריך להיות מסוגל להמשיך להשתמש בקוד בצורה שקופה, בלי שהעובדה שהעברתי לו את המחלקה היורשת ולא את מחלקת האם, תפגע בהנחות שלו לגבי המתודה.
&lt;/p&gt;
&lt;p&gt;
אני חייב לקיים את החוקיות שקיימת במחלקת האם, כך שכל unit test, כל קריאה לפרופרטי או פונקציה, תמשיך לפעול בצורה זהה מבחינת מי שמשתמש בקוד שלי. כמובן שמה שקורה מאחורי הקלעים יכול להיות שונה, בשביל זה הרי יצרתי מחלקה יורשת, אבל מבחינתו אין שום הבדל.
&lt;/p&gt;
&lt;p&gt;
דוגמה קטנה תסביר בבירור:
&lt;/p&gt;
&lt;p&gt;
יש לי מחלקה שמייצגת מרובע כלשהוא
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;class&lt;/span&gt; &lt;span class="code_classes"&gt;Rectangle&lt;/span&gt;
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;virtual&lt;/span&gt; &lt;span class="code_keywords"&gt;int&lt;/span&gt; Width { &lt;span class="code_keywords"&gt;get&lt;/span&gt;; &lt;span class="code_keywords"&gt;set&lt;/span&gt;; }
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;virtual&lt;/span&gt; &lt;span class="code_keywords"&gt;int&lt;/span&gt; Height { &lt;span class="code_keywords"&gt;get&lt;/span&gt;; &lt;span class="code_keywords"&gt;set&lt;/span&gt;; }
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;public&lt;/span&gt; Rectangle() { }
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;public&lt;/span&gt; Rectangle(&lt;span class="code_keywords"&gt;int&lt;/span&gt; width, &lt;span class="code_keywords"&gt;int&lt;/span&gt; height)
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;this&lt;/span&gt;.Width = width;
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;this&lt;/span&gt;.Height = height;
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;virtual&lt;/span&gt; &lt;span class="code_keywords"&gt;int&lt;/span&gt; Size
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;get&lt;/span&gt;
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;return&lt;/span&gt; &lt;span class="code_keywords"&gt;this&lt;/span&gt;.Height * &lt;span class="code_keywords"&gt;this&lt;/span&gt;.Width;
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
וגם בניתי עבורה טסט:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p class="code_line"&gt;
&amp;nbsp; [&lt;span class="code_classes"&gt;TestMethod&lt;/span&gt;()]
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;void&lt;/span&gt; TestSize()
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;int&lt;/span&gt; expectedWidth = 3;
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;int&lt;/span&gt; expectedHeight=7;
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;Rectangle&lt;/span&gt; rectangle = &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;Rectangle&lt;/span&gt;(expectedWidth, expectedHeight);
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;Assert&lt;/span&gt;.AreEqual(expectedWidth, rectangle.Width);
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;Assert&lt;/span&gt;.AreEqual(expectedHeight, rectangle.Height);
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
כעת יצרתי מחלקה נוספת &amp;ndash; ריבוע, שהוא בעצם צורה פרטית של מרובע, אלא שהרוחב שווה תמיד לאורך, אז החלטתי לבנות אותו כתת מחלקה
&lt;/p&gt;
&lt;p&gt;
של המרובע שלי:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;class&lt;/span&gt; &lt;span class="code_classes"&gt;Square&lt;/span&gt; : &lt;span class="code_classes"&gt;Rectangle&lt;/span&gt;
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;public&lt;/span&gt; Square() { }
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;public&lt;/span&gt; Square(&lt;span class="code_keywords"&gt;int&lt;/span&gt; width)
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : &lt;span class="code_keywords"&gt;base&lt;/span&gt;(width, width)
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;override&lt;/span&gt; &lt;span class="code_keywords"&gt;int&lt;/span&gt; Size
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;get&lt;/span&gt;
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;return&lt;/span&gt; &lt;span class="code_keywords"&gt;this&lt;/span&gt;.Width * &lt;span class="code_keywords"&gt;this&lt;/span&gt;.Width;
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
אבל בגלל שלריבוע הרוחב והאורך זהים, אני צריך רק ערך תמיד &amp;ndash; של רוחב או גובה, אז שיניתי את הקוד כלעיל.
&lt;/p&gt;
&lt;p&gt;
עכשיו הטסט שלי יכשל:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p class="code_line"&gt;
[&lt;span class="code_classes"&gt;TestMethod&lt;/span&gt;()]
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;void&lt;/span&gt; TestSize()
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;int&lt;/span&gt; expectedWidth = 3;
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;int&lt;/span&gt; expectedHeight=7;
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;Rectangle&lt;/span&gt; square = &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;Square&lt;/span&gt;(expectedWidth);
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;Assert&lt;/span&gt;.AreEqual(expectedWidth, square.Width);
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;Assert&lt;/span&gt;.AreEqual(expectedHeight, square.Height);&lt;span class="code_comment"&gt;//fail&lt;/span&gt;
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
וזה בדיוק מה שהעיקרון אומר &amp;ndash; אם היו לי ציפיות כלשהם ממחלקת האם, הן צריכות להמשיך להתקיים בכל מחלקה שיורשת. מבחינתי לא צריך להיות הבדל אם אני עובד עם מרובע או ריבוע.
&lt;/p&gt;
&lt;p&gt;
מה הפיתרון? במקרה שלנו באמת זה לא אפשרי, אז נצטרך לבטל את הירושה וליצור אולי מחלקה שלישית אבסטרקטית שממנה ירשו גם הריבוע
&lt;/p&gt;
&lt;p&gt;
וגם המרובע, כך שאני דורס מתודה אבסטרקטית ואין לאף אחד ציפיות מוקדמות ממנה, ואני אוכל לעשות מה שארצה.
&lt;/p&gt;
&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:e28ef7f6-c03c-4f9e-80a3-02c1e0471eba" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/object+oriented"&gt;object oriented&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/liskov"&gt;liskov&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/lsp"&gt;lsp&lt;/a&gt;
&lt;/div&gt;
</description>
      <link>http://blog.talgiladi.net/post/Liskov-Substitution-Principle.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/Liskov-Substitution-Principle.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=f3e92b3a-66d8-400c-a4a0-93213f261fe6</guid>
      <pubDate>Fri, 28 Nov 2008 19:28:00 +0400</pubDate>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=f3e92b3a-66d8-400c-a4a0-93213f261fe6</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=f3e92b3a-66d8-400c-a4a0-93213f261fe6</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/Liskov-Substitution-Principle.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=f3e92b3a-66d8-400c-a4a0-93213f261fe6</wfw:commentRss>
    </item>
    <item>
      <title>Web Services Extensions</title>
      <description>&lt;p&gt;
החלטתי לכתוב קצת על שירותי רשת, שירותי ווב או בקיצור web services... &lt;br /&gt;
אז מכיוון שכולנו יודעים ליצור שירות בסיסי אני אדלג על ההתחלה ואעבור ישירות לשירותים מתקדמים. &lt;br /&gt;
כשאני אומר שירותים מתקדמים אני לא מתכוון לקוד מתוחכם שאנחנו יוצרים, אלא לתמיכה מובנית, סטנדרטים חדשים שצומחים לאיטם &lt;br /&gt;
שמטרתם להוסיף פיצ&amp;#39;רים חדשים ותמיכה בעוד סוגי שירותים לשירותי הרשת. &lt;br /&gt;
לדוגמה -&amp;nbsp; תמיכה מובנית בהצפנה, חתימה דיגיטלית, טרנזאקציות ועוד... 
&lt;/p&gt;
&lt;p&gt;
הבשורה הרעה שכולנו לא אוהבים לשמוע, זה שצריך להוריד משהו מהאינטרנט... כן, זה עדיין לא בא בתור סטנדרט בתוך הפריימוורק, אולי בעתיד... &lt;br /&gt;
אז תגשו לגוגל ותחפשו wse, בפעם האחרונה שבדקתי הגירסה הייתה 3.0 ולינק ההורדה ממיקרוסופט הוא &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=018a09fd-3a74-43c5-8ec1-8d789091255d&amp;amp;displaylang=en"&gt;כאן&lt;/a&gt; &lt;br /&gt;
לאחר ההתקנה יהיו לכם כמה דוגמאות קוד והוראות שימוש די נוחות... &lt;br /&gt;
הדבר הראשון שצריך לעשות אם אנחנו רוצים להשתמש בחתימה דיגיטלית זה להתקין מפתח אסימטרי. &lt;br /&gt;
למזלנו הקובץ מגיע עם 4 מפתחות לצורך הדוגמה, והדבר היחיד שצריך לעשות זה להריץ את הקובץ setup.bat שנמצא בתוך ספריית ההתקנה, בתוך ספריית samples, רק שימו לב שצריך לפתוח את שורת הפקודה של ויזואל סטודיו קודם: 
&lt;/p&gt;
&lt;a href="http://blog.talgiladi.net/image.axd?picture=cmd.png"&gt;&lt;img style="display: inline; border-width: 0px" src="http://blog.talgiladi.net/image.axd?picture=cmd_thumb.png" border="0" alt="cmd" title="cmd" width="639" height="89" /&gt;&lt;/a&gt; 
&lt;p&gt;
ללכת לנתיב שציינתי, ואז לכתוב את שם הקובץ להרצה... תתפללו שהכל יעבוד, ואם כן אז יש לכם 4 מפתחות להצפנה מותקנים על ה iis. 
&lt;/p&gt;
&lt;p&gt;
אם ממש בא לראות אותן, ניתן להקיש בשורת הפקודה mmc כדי לפתוח את הקונסול, אחר כך להקיש על file-&amp;gt;Add/Remove snap in-&amp;gt;Add-&amp;gt;certificates-&amp;gt;Add &lt;br /&gt;
ואז תראו שם את כל המפתחות שמותקנות אצלכם על המחשב מהגלישה באינטרנט... אלו שעכשיו התקנו -&amp;nbsp; אחת מופיע תחת personal , עוד אחת תחת other people ועוד 2 איפשהו שם... 
&lt;/p&gt;
&lt;p&gt;
איך עובדת החתימה הדיגיטלית בשירותי רשת? &lt;br /&gt;
כמו בכל מקום אחר. הלקוח מייצר מפתח פרטי-ציבורי מהחתימה שלו. את המפתח הציבורי הוא ישלח ביחד עם ההודעה לשרת שמפעיל את שירותי הרשת. &lt;br /&gt;
הלקוח עושה האש על ההודעה. &lt;br /&gt;
על קוד ההאש שקיבלנו, אנו מבצעים את ההצפנה בעזרת המפתח הפרטי, מה שקיבלנו עכשיו זו בעצם החתימה הדיגיטלית. &lt;br /&gt;
את החתימה אנחנו מצרפים להודעה שאנחנו שולחים. &lt;br /&gt;
&lt;br /&gt;
בצד השרת- השרת מקבל את ההודעה ורואה חתימה דיגיטלית מצורפת ב header של ההודעה. &lt;br /&gt;
בעזרת המפתח הציבורי שהלקוח צירף, השרת מנסה לפענח את החתימה. אם הצליח אז עכשיו יש בידינו את קוד ההאש של ההודעה. &lt;br /&gt;
כעת השרת יעשה בעצמו חישוב האש על ההודעה (כמובן בעזרת אותו אלגוריתם שהלקוח השתמש - הלקוח צריך להעביר גם את הפרט הזה בהודעה...) &lt;br /&gt;
ועכשיו נשאר רק להשוות אם ההאש שפיענחנו מהלקוח זהה להאש שביצענו בעצמנו... אם לא, ההודעה שונתה בדרך... 
&lt;/p&gt;
&lt;p&gt;
תמיכה נוספת למעין חתימה דיגיטלית היא חתימה על ידי שם משתמש וסיסמא, שהם משמשים בעצם במקום המפתח הפרטי. החיסרון הברור הוא שלשרת צריכים להיות &lt;br /&gt;
את שם המשתמש והסיסמא כדי לוודא שאכן החתימה אמיתית... 
&lt;/p&gt;
&lt;p&gt;
רק עוד דקה של תיאוריה, דבר שצריך לדעית לפני שמתחילים עם כל השירותים המורחבים האלה, זה שכל התוספות האלה מצורפות ל headers של ההודעה, ה wse יושב ומאזין בשרת ואצל הלקוח, וברגע שהלקוח שולח הודעה, אז לפי ההגדרות ה wse לוקח את ההודעה, עושה מה שצריך איתה, ומעביר אותה הלאה לשרת. בצד השרת שוב ה wse מאזין להודעות המגיעות, מנתח אותן לפי ההגדרות, ואז אם הכל בסדר מעביר את ההודעה לקוד שלנו. כך שאם אתם בדיבאג על השרת, ומשום מה הודעה לא מגיעה לשם, כנראה היא לא עברה את&amp;nbsp; מחסום ה wse... 
&lt;/p&gt;
&lt;p&gt;
אז בואו נתחיל עם חתימה על ידי שם משתמש וסיסמא. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;span style="font-size: 14pt; text-decoration: underline"&gt;הגדרת צד השרת &lt;br /&gt;
&lt;/span&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;קודם כל ניצור אתר פשוט.&amp;nbsp; &lt;br /&gt;
	&amp;nbsp; &lt;br /&gt;
	עכשיו כמה הגדרות &lt;br /&gt;
	בואו נפתח את כלי הקונפיגורציה שהגיע עם ההתקנה. אם אתם כבר בויזואל סטודיו אז לחצן ימני על הפרוייקט ותראו למטה לחצן בשם wse settings. (אם לא, אז פשוט תתחילו את התוכנה&amp;nbsp; לבד דרך תפריט ההתחלה: &lt;br /&gt;
	&lt;br /&gt;
	&lt;a href="http://blog.talgiladi.net/image.axd?picture=openConfiguration.png"&gt;&lt;img style="display: inline; border-width: 0px" src="http://blog.talgiladi.net/image.axd?picture=openConfiguration_thumb.png" border="0" alt="openConfiguration" title="openConfiguration" width="459" height="55" /&gt;&lt;/a&gt; &lt;br /&gt;
	&lt;br /&gt;
	אבל אז תצטרכו למקם את הקובץ שנוצר לבד בתוך תיקיית האתר שלכם) &lt;br /&gt;
	&lt;br /&gt;
	התוכנה הזאת בעצם חוסכת מאיתנו את המשחק בווב קונפיג ומכניסה לשם את ההגדרות הדרושות. &lt;/li&gt;
	&lt;li&gt;בטאב הראשון נאפשר את השימוש בהרחבות המתקדמות בפרוייקט שלנו: &lt;br /&gt;
	&lt;br /&gt;
	&lt;a href="http://blog.talgiladi.net/image.axd?picture=enableWSE.png"&gt;&lt;img style="display: inline; border-width: 0px" src="http://blog.talgiladi.net/image.axd?picture=enableWSE_thumb.png" border="0" alt="enableWSE" title="enableWSE" width="371" height="195" /&gt;&lt;/a&gt; &lt;br /&gt;
	&lt;/li&gt;
	&lt;li&gt;בטאב ה security בחלק של seucrity tokens manager נוסיף מנהל חדש על ידי לחיצה על add &lt;br /&gt;
	&lt;br /&gt;
	&lt;a href="http://blog.talgiladi.net/image.axd?picture=AddToken.png"&gt;&lt;img style="display: inline; border-width: 0px" src="http://blog.talgiladi.net/image.axd?picture=AddToken_thumb.png" border="0" alt="AddToken" title="AddToken" width="490" height="270" /&gt;&lt;/a&gt; &lt;br /&gt;
	&lt;br /&gt;
	תבחרו בקומבו בוקס Username Token Manager ושאר הפרטים יתמלאו לבד. &lt;br /&gt;
	כאן בעצם הגדרנו שההודעה שלנו צריכה להכיל חתימה בעזרת שם משתמש וסיסמה. &lt;br /&gt;
	&lt;br /&gt;
	&lt;/li&gt;
	&lt;li&gt;אנחנו צריכים לעשות זה ליצור מחלקה שאליה יעביר ה wse את שם המשתמש, והיא תחזיר לו את הסיסמה &lt;br /&gt;
	כדי שהוא יוכל לבדוק את החתימה הדיגיטלית. המחלקה הזאת במצב רגיל מן הסתם תמשוך את המידע מדטה בייס או קובץ. &lt;br /&gt;
	את שם המחלקה, שעוד מעט נראה איך ליצור, אנו כותבים בתיבת הטקסט Type. אני קראתי למחלקה UserNameTokenHandler &lt;br /&gt;
	&lt;br /&gt;
	&lt;a href="http://blog.talgiladi.net/image.axd?picture=UserNameTokenHandler.png"&gt;&lt;img style="display: inline; border-width: 0px" src="http://blog.talgiladi.net/image.axd?picture=UserNameTokenHandler_thumb.png" border="0" alt="UserNameTokenHandler" title="UserNameTokenHandler" width="454" height="93" /&gt;&lt;/a&gt; &lt;br /&gt;
	&lt;br /&gt;
	תקליקו על אישור &lt;br /&gt;
	&lt;br /&gt;
	&lt;/li&gt;
	&lt;li&gt;עוד דבר יש לנו בטאב הזה, כדי שנוכל לשחק עם המפתחות שלנו, שאינן אמיתיים ולא הונפקו על ידי חברה מורשית כגון verisign וכו&amp;#39;, &lt;br /&gt;
	&lt;br /&gt;
	יש לסמן צ&amp;#39;ק בוקס בשם Allow test roots &lt;br /&gt;
	&lt;a href="http://blog.talgiladi.net/image.axd?picture=allowTestRoots.png"&gt;&lt;img style="display: inline; border-width: 0px" src="http://blog.talgiladi.net/image.axd?picture=allowTestRoots_thumb.png" border="0" alt="allowTestRoots" title="allowTestRoots" width="234" height="110" /&gt;&lt;/a&gt; &lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	&lt;/li&gt;
	&lt;li&gt;עלינו ליצור קובץ שיכיל את ה Policy. הקובץ הזה מכיל הגדרות שונות לגבי החתימה הדיגיטלית. אתם יכולים להעתיק את הקובץ מספריית הדוגמאות שהגיעה עם התקנה ה wse, שם הקובץ הוא wse3policyCache.config והתוכן שלו הוא &lt;br /&gt;
	&lt;div class="code_area"&gt;
	&lt;p&gt;
	&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;&lt;span class="code_text"&gt;policies&lt;/span&gt;&lt;span class="code_keywords"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;xmlns&lt;/span&gt;&lt;span class="code_keywords"&gt;=&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt;http://schemas.microsoft.com/wse/2005/06/policy&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&lt;span class="code_keywords"&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span class="code_text"&gt;extensions&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span class="code_text"&gt;extension&lt;/span&gt;&lt;span class="code_keywords"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span class="code_keywords"&gt;=&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt;usernameForCertificateSecurity&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span class="code_keywords"&gt;=&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt;Microsoft.Web.Services3.Design.UsernameForCertificateAssertion, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt; /&amp;gt;&lt;/span&gt;
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span class="code_text"&gt;extension&lt;/span&gt;&lt;span class="code_keywords"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span class="code_keywords"&gt;=&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt;x509&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span class="code_keywords"&gt;=&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt;Microsoft.Web.Services3.Design.X509TokenProvider, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt; /&amp;gt;&lt;/span&gt;
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span class="code_text"&gt;extension&lt;/span&gt;&lt;span class="code_keywords"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span class="code_keywords"&gt;=&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt;requireActionHeader&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span class="code_keywords"&gt;=&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt;Microsoft.Web.Services3.Design.RequireActionHeaderAssertion, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt; /&amp;gt;&lt;/span&gt;
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&lt;span class="code_keywords"&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span class="code_text"&gt;extensions&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&lt;span class="code_keywords"&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span class="code_text"&gt;policy&lt;/span&gt;&lt;span class="code_keywords"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span class="code_keywords"&gt;=&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt;ServerPolicy&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span class="code_text"&gt;usernameForCertificateSecurity&lt;/span&gt;&lt;span class="code_keywords"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;establishSecurityContext&lt;/span&gt;&lt;span class="code_keywords"&gt;=&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt;false&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;requireSignatureConfirmation&lt;/span&gt;&lt;span class="code_keywords"&gt;=&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt;false&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;messageProtectionOrder&lt;/span&gt;&lt;span class="code_keywords"&gt;=&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt;SignBeforeEncrypt&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;requireDerivedKeys&lt;/span&gt;&lt;span class="code_keywords"&gt;=&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt;true&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;ttlInSeconds&lt;/span&gt;&lt;span class="code_keywords"&gt;=&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt;300&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span class="code_text"&gt;serviceToken&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span class="code_text"&gt;x509&lt;/span&gt;&lt;span class="code_keywords"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;storeLocation&lt;/span&gt;&lt;span class="code_keywords"&gt;=&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt;LocalMachine&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;storeName&lt;/span&gt;&lt;span class="code_keywords"&gt;=&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt;My&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;findValue&lt;/span&gt;&lt;span class="code_keywords"&gt;=&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt;CN=WSE2QuickStartServer&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;findType&lt;/span&gt;&lt;span class="code_keywords"&gt;=&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt;FindBySubjectDistinguishedName&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt; /&amp;gt;&lt;/span&gt;
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span class="code_text"&gt;serviceToken&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span class="code_text"&gt;protection&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span class="code_text"&gt;request&lt;/span&gt;&lt;span class="code_keywords"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;signatureOptions&lt;/span&gt;&lt;span class="code_keywords"&gt;=&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt;IncludeAddressing, IncludeTimestamp, IncludeSoapBody&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;encryptBody&lt;/span&gt;&lt;span class="code_keywords"&gt;=&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt;true&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt; /&amp;gt;&lt;/span&gt;
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span class="code_text"&gt;response&lt;/span&gt;&lt;span class="code_keywords"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;signatureOptions&lt;/span&gt;&lt;span class="code_keywords"&gt;=&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt;IncludeAddressing, IncludeTimestamp, IncludeSoapBody&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;encryptBody&lt;/span&gt;&lt;span class="code_keywords"&gt;=&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt;true&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt; /&amp;gt;&lt;/span&gt;
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span class="code_text"&gt;fault&lt;/span&gt;&lt;span class="code_keywords"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;signatureOptions&lt;/span&gt;&lt;span class="code_keywords"&gt;=&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt;IncludeAddressing, IncludeTimestamp, IncludeSoapBody&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;encryptBody&lt;/span&gt;&lt;span class="code_keywords"&gt;=&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt;false&lt;/span&gt;&amp;quot;&lt;span class="code_keywords"&gt; /&amp;gt;&lt;/span&gt;
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span class="code_text"&gt;protection&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span class="code_text"&gt;usernameForCertificateSecurity&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span class="code_text"&gt;requireActionHeader&lt;/span&gt;&lt;span class="code_keywords"&gt; /&amp;gt;&lt;/span&gt;
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&lt;span class="code_keywords"&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span class="code_text"&gt;policy&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&lt;span class="code_keywords"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="code_text"&gt;policies&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;
	&lt;/p&gt;
	&lt;p&gt;
	&lt;span style="color: blue"&gt;&lt;/span&gt;
	&lt;/p&gt;
	&lt;p&gt;
	&lt;span style="color: blue"&gt;&lt;/span&gt;
	&lt;/p&gt;
	&lt;/div&gt;
	פה בעצם אמרנו למנהל המפתחות הכן נימצא המפתח שלי, מה השם שלו ואיך למצוא אותו. הגדרנו גם איך צריכה להיראות בקשה לשרת, התגובה מהשרת והודעות שגיאה. &lt;br /&gt;
	&lt;br /&gt;
	7. כעת נראה למנהל ה Policy&amp;nbsp; היכן ניתן למצוא את הקובץ. לכו לטאב של ה Policy, תסמנו את הצ&amp;#39;ק בוקס כדי לאפשר Policy, תקליקו על Browse ותמצאו את הקובץ הנ&amp;quot;ל. &lt;br /&gt;
	כעת תנו שם ל Policy. אצלנו השם הוא ServerPolicy &lt;br /&gt;
	&lt;a href="http://blog.talgiladi.net/image.axd?picture=AllowPolicy.png"&gt;&lt;img style="display: inline; border-width: 0px" src="http://blog.talgiladi.net/image.axd?picture=AllowPolicy_thumb.png" border="0" alt="AllowPolicy" title="AllowPolicy" width="484" height="168" /&gt;&lt;/a&gt; &lt;br /&gt;
	&lt;br /&gt;
	תלחצו על אישור &lt;/li&gt;
	&lt;li&gt;בואו ניצור את המחלקה שתטפל בשם המשתמש: &lt;br /&gt;
	ניצור מחלקה בשם UserNameTokenHandler שתירש מהמחלקה UsernameTokenManager. נדרוס את הפונקציה AuthenticateToken שהחתימה שלה היא &lt;br /&gt;
	&lt;div class="code_area"&gt;
	&lt;p style="margin: 0px"&gt;
	&lt;span class="code_keywords"&gt;protected&lt;/span&gt; &lt;span class="code_keywords"&gt;override&lt;/span&gt; &lt;span class="code_keywords"&gt;string&lt;/span&gt; AuthenticateToken(&lt;span class="code_classes"&gt;UsernameToken&lt;/span&gt; token)
	&lt;/p&gt;
	&lt;/div&gt;
	&lt;br /&gt;
	הפונקציה הזאת מקבלת מה wse את ה UsernameToken ואמורה להחזיר את הסיסמה עבור המשתמש הזה. עם הסיסמה שאנחנו מחזירים, ה wse מנסה לפענח את החתימה הדיגיטלית, ואם הוא מצליח הוא אז הוא יעשה האש להודעה וישווה לערך שנמצא בחתימה הדיגיטלית. לצורך הדוגמה הקוד יהיה פשוט &lt;br /&gt;
	&lt;div class="code_area"&gt;
	&lt;p style="margin: 0px"&gt;
	&amp;nbsp;&lt;span class="code_keywords"&gt;protected&lt;/span&gt; &lt;span class="code_keywords"&gt;override&lt;/span&gt; &lt;span class="code_keywords"&gt;string&lt;/span&gt; AuthenticateToken(&lt;span class="code_classes"&gt;UsernameToken&lt;/span&gt; token)
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;if&lt;/span&gt; (token.Username == &lt;span class="code_text"&gt;&amp;quot;talg&amp;quot;&lt;/span&gt;)
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;return&lt;/span&gt; &lt;span class="code_text"&gt;&amp;quot;mypassword&amp;quot;&lt;/span&gt;;
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;else&lt;/span&gt;
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;return&lt;/span&gt; &lt;span class="code_keywords"&gt;null&lt;/span&gt;;
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; }
	&lt;/p&gt;
	&lt;p&gt;
	&amp;nbsp;
	&lt;/p&gt;
	&lt;/div&gt;
	&lt;a href="http://blog.talgiladi.net/admin/Pages/examples/UserNameTokenHandler.zip"&gt;להורדת הקוד של המחלקה &lt;br /&gt;
	&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;ניצור ווב סרביס פשוט, ניתן אפילו להשתמש בשלום עולם שנוצר אוטומטי. השינוי היחד שאנחנו צריכים לעשות זה לציין באיזה פוליסי הסרביס הזה ישתמש. אנו יצרנו כבר פוליסי בשם ServerPolicy ובא נשתמש על ידי הוספת המאפיין לפני שם המחלקה של הווב סרביס: 
	&lt;div class="code_area"&gt;
	&lt;p style="margin: 0px"&gt;
	[&lt;span class="code_classes"&gt;Policy&lt;/span&gt;(&lt;span class="code_text"&gt;&amp;quot;ServerPolicy&amp;quot;&lt;/span&gt;)]
	&lt;/p&gt;
	&lt;/div&gt;
	וסיימנו את צד השרת... היה ארוך, אבל רוב ההגדרות הן חד פעמיות, וכעת כל סרביס נוסף שתגדירו לא ידרוש שום הגדרה נוספת. אם ה wse יחליט שהבקשה עונה על הדרישות, שבמקרה שלנו הם חתימה דיגיטלית בעזרת שם משתמש וסיסמה, הוא יעביר את הבקשה לסרביס שלנו, אם לא, אנחנו אפילו לא נדע מזה, הודעת שגיאה תיזרק לצד הלקוח... &lt;br /&gt;
	&lt;br /&gt;
	&lt;a href="http://blog.talgiladi.net/admin/Pages/examples/WSE3Server.zip"&gt;להורדת קוד והגדרות השרת &lt;br /&gt;
	&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;p&gt;
&lt;strong&gt;&lt;span style="font-size: 14pt; text-decoration: underline"&gt;הגדרת צד הלקוח &lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;
בצד הלקוח נעשה קצת אחרת, נוריד את ההגדרות מהקופיגורציה ונכניס אותם לקוד, כדי שיקביל לדוגמאות שהגיעו עם ההתקנה. 
&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;ניצור פרוייקט, אני יצרתי אפליקציית קונסול. &lt;/li&gt;
	&lt;li&gt;לחצן ימני על הגדרות פרוייקט-&amp;gt; wse settings &lt;br /&gt;
	&lt;/li&gt;
	&lt;li&gt;לסמן את הצ&amp;#39;ק בוקס הראשון שמופיע, שבעצם מאפשר שימוש ב wse בפרוייקט הזה: &lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&lt;a href="http://blog.talgiladi.net/image.axd?picture=enableWSEClient.png"&gt;&lt;img style="display: inline; border-width: 0px" src="http://blog.talgiladi.net/image.axd?picture=enableWSEClient_thumb.png" border="0" alt="enableWSEClient" title="enableWSEClient" width="481" height="103" /&gt;&lt;/a&gt; &lt;/li&gt;
	&lt;li&gt;כעת ניצור הפנייה לווב סרביס בשרת שלנו על ידי הוספת web reference כרגיל. כעת לנקודה הכי חשובה! הפנייה רגילה לווב סרביס יורשת מהמחלקה SoapHttpClientProtocol , אנו צריכים לשנות כך שההפניה שלנו תירש מ WebServicesClientProtocol, שום שינוי אחר לא נדרש בקוד של ההפניה. רק שימו לב שכדאי לכם להוציא את ההפניה מהתיקיה של web references, אחרת כל פעם כשיבוצע עידכון הקוד הישן ימחק ותיצטרכו שוב לשנות את שם המחלקה. &lt;br /&gt;
	&lt;/li&gt;
	&lt;li&gt;הפנייה בקוד לווב סרביס 
	&lt;div class="code_area"&gt;
	&lt;p style="margin: 0px"&gt;
	SecureWebService.&lt;span class="code_classes"&gt;WebService&lt;/span&gt; ws = &lt;span class="code_keywords"&gt;new&lt;/span&gt; WebServiceClient.SecureWebService.&lt;span class="code_classes"&gt;WebService&lt;/span&gt;();
	&lt;/p&gt;
	&lt;/div&gt;
	&lt;/li&gt;
	&lt;li&gt;יצירת מקבילה בקוד לקובץ הפוליסי שיצרנו בשרת: 
	&lt;div class="code_area"&gt;
	&lt;p style="margin: 0px"&gt;
	&amp;nbsp;&lt;span class="code_classes"&gt;UsernameForCertificateAssertion&lt;/span&gt; assertion = &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;UsernameForCertificateAssertion&lt;/span&gt;();
	&lt;/p&gt;
	&lt;/div&gt;
	&lt;/li&gt;
	&lt;li&gt;נגדיר עם איזו חתימה להשתמש, ואיך למצוא אותה 
	&lt;div class="code_area"&gt;
	&lt;p style="margin: 0px"&gt;
	assertion.X509TokenProvider = &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;X509TokenProvider&lt;/span&gt;(&lt;span class="code_classes"&gt;StoreLocation&lt;/span&gt;.CurrentUser,
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;StoreName&lt;/span&gt;.AddressBook,
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_text"&gt;&amp;quot;CN=WSE2QuickStartServer&amp;quot;&lt;/span&gt;,
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;X509FindType&lt;/span&gt;.FindBySubjectDistinguishedName);
	&lt;/p&gt;
	&lt;/div&gt;
	&lt;/li&gt;
	&lt;li&gt;עוד הגדרה שמופיעה אצלנו בקובץ הפוליסי בשרת: 
	&lt;div class="code_area"&gt;
	&lt;p style="margin: 0px"&gt;
	&amp;nbsp; assertion.RequireDerivedKeys = &lt;span class="code_keywords"&gt;true&lt;/span&gt;;
	&lt;/p&gt;
	&lt;/div&gt;
	&lt;/li&gt;
	&lt;li&gt;כעת נכניס את השם המשתמש והסיסמה: 
	&lt;div class="code_area"&gt;
	&lt;p class="code_line"&gt;
	assertion.UsernameTokenProvider = &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;UsernameTokenProvider&lt;/span&gt;(&lt;span class="code_text"&gt;&amp;quot;talg&amp;quot;&lt;/span&gt;, &lt;span class="code_text"&gt;&amp;quot;mypassword&amp;quot;&lt;/span&gt;);
	&lt;/p&gt;
	&lt;/div&gt;
	&lt;/li&gt;
	&lt;li&gt;ונוסיף את הפוליסי לווב סרביס: 
	&lt;div class="code_area"&gt;
	&lt;p style="margin: 0px"&gt;
	&amp;nbsp; &lt;span class="code_classes"&gt;Policy&lt;/span&gt; policy = &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;Policy&lt;/span&gt;();
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; policy.Assertions.Add(assertion);
	&lt;/p&gt;
	&lt;p style="margin: 0px"&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ws.SetPolicy(policy);
	&lt;/p&gt;
	&lt;/div&gt;
	&lt;/li&gt;
	&lt;li&gt;ונקרא לשירות: 
	&lt;div class="code_area"&gt;
	&lt;p style="margin: 0px"&gt;
	&amp;nbsp;&lt;span class="code_keywords"&gt;string&lt;/span&gt; result = ws.HelloWorld();
	&lt;/p&gt;
	&lt;/div&gt;
	אם עשינו הכל כמו שצריך, נקבל תשובה, אם לא... אז תיזרק אקספשן... &lt;br /&gt;
	&lt;br /&gt;
	&lt;a href="http://www.talgiladi.net/examples/WebServiceClient.zip" title="download"&gt;להורדת קוד פרוייקט הלקוח&lt;/a&gt; &lt;/li&gt;
&lt;/ol&gt;
&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:13b914f6-22a2-4709-a779-a441fa85ce34" class="wlWriterEditableSmartContent" style="display: inline; float: none; margin: 0px; padding: 0px"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/WebServices"&gt;WebServices&lt;/a&gt;
&lt;/div&gt;
</description>
      <link>http://blog.talgiladi.net/post/Web-Services-Extensions.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/Web-Services-Extensions.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=3b609e38-321e-4f60-9649-1f8f67734ed7</guid>
      <pubDate>Fri, 03 Oct 2008 20:47:00 +0400</pubDate>
      <category>C#</category>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=3b609e38-321e-4f60-9649-1f8f67734ed7</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=3b609e38-321e-4f60-9649-1f8f67734ed7</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/Web-Services-Extensions.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=3b609e38-321e-4f60-9649-1f8f67734ed7</wfw:commentRss>
    </item>
    <item>
      <title>XSLT</title>
      <description>&lt;p&gt;
ראינו לא מזמן כיצד ליצור &lt;a href="http://blog.talgiladi.net/post/RSS.aspx" title="rss"&gt;RSS Feed&lt;/a&gt; לאתר (הסימן הכתום הזה שהדפדפן מראה כשאפשר להירשם לחדשות ועידכונים מהאתר...) &lt;br /&gt;
שם בעצם יצרנו קובץ xml פשוט והדפדפן הציג לנו אותו בצורה יפה ומסודרת. רציתי להראות משהו נחמד שנקרא xslt שזהו בעצם קובץ, שאומר לתוכנה שקוראת xml, איך &lt;strong&gt;להציג&lt;/strong&gt; את הקובץ &lt;br /&gt;
שימו לב, את הקובץ xml עם התוכן אני יוצר כרגיל איך שיצרתי עד היום בלי שינוי, הקובץ הזה רק נותן הוראה איך &lt;strong&gt;להציג&lt;/strong&gt; את התוכן, וכך הדפדפן, או כל קורא xml יודע להציג אותו בצורה יפה ולא בתור טקסט פשוט &lt;br /&gt;
נראה דוגמה ואז נבין איזה פשוט זה. &lt;br /&gt;
נניח שיש לי קובץ xml כזה: 
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_keywords"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="script_text"&gt;xml &lt;/span&gt;version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;&lt;span class="code_keywords"&gt; ?&amp;gt;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;&lt;span class="script_text"&gt;channel&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;&lt;span class="script_text"&gt;title&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;coding games&lt;span class="code_keywords"&gt;&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;/&lt;/span&gt;&lt;span class="script_text"&gt;title&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;&lt;span class="script_text"&gt;link&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;http://www.talgiladi.net&lt;span class="code_keywords"&gt;&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;/&lt;/span&gt;&lt;span class="script_text"&gt;link&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;&lt;span class="script_text"&gt;description&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;code samples &lt;span class="code_keywords"&gt;&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;/&lt;/span&gt;&lt;span class="script_text"&gt;description&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;&lt;span class="script_text"&gt;ttl&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;180&lt;span class="code_keywords"&gt;&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;/&lt;/span&gt;&lt;span class="script_text"&gt;ttl&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;&lt;span class="script_text"&gt;item&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;&lt;span class="script_text"&gt;title&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;![CDATA[Creating xml documents with xml text writer]]&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;&lt;span class="code_keywords"&gt;&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;/&lt;/span&gt;&lt;span class="script_text"&gt;title&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;&lt;span class="script_text"&gt;link&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;http://www.talgiladi.net/XmlTextWriter.aspx&lt;span class="code_keywords"&gt;&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;/&lt;/span&gt;&lt;span class="script_text"&gt;link&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;&lt;span class="script_text"&gt;guid &lt;/span&gt;isPermaLink=&amp;quot;true&amp;quot;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;http://www.talgiladi.net/XmlTextWriter.aspx&lt;span class="code_keywords"&gt;&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;/&lt;/span&gt;&lt;span class="script_text"&gt;guid&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;&lt;span class="script_text"&gt;description&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;![CDATA[xml text writer for fast and easy creation of xml documents]]&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;&lt;span class="code_keywords"&gt;&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;/&lt;/span&gt;&lt;span class="script_text"&gt;description&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;&lt;span class="script_text"&gt;pubDate&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;2/5/2008 9:24:18 PM&lt;span class="code_keywords"&gt;&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;/&lt;/span&gt;&lt;span class="script_text"&gt;pubDate&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;/&lt;/span&gt;&lt;span class="script_text"&gt;item&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt; &lt;br /&gt;
&lt;span class="code_keywords"&gt;&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;/&lt;/span&gt;&lt;span class="script_text"&gt;channel&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt; 
&lt;/p&gt;
&lt;p&gt;
זה בעצם אותו קובץ שהשתמשתי בו בשביל ה RSS רק הורדתי 2 שורות כדי שהדפדפן לא יזהה אותו בתור RSS ויציג אותו בצורה שונה. &lt;br /&gt;
כעת נלך ליצירת קובץ חדש ונבחר xslt 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.talgiladi.net/image.axd?picture=createXslt.png"&gt;&lt;img style="display: inline; border: 0px" src="http://blog.talgiladi.net/image.axd?picture=createXslt_thumb.png" border="0" alt="createXslt" title="createXslt" width="579" height="423" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
קיבלנו קובץ xml חדש. 3 שורות הראשונות אנחנו לא נוגעים, כעת נתחיל לתת הוראות. זיכרו שהקובץ הזה אמור להורות לקורא xml כיצד להציג כל חלק בקובץ &lt;br /&gt;
נתחיל להסביר לו איך לקרוא:
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;?&lt;span class="script_text"&gt;xml &lt;/span&gt;&lt;span class="script_type"&gt;version&lt;/span&gt;&lt;span class="code_keywords"&gt;=&amp;quot;1.0&amp;quot;&lt;/span&gt; &lt;span class="script_type"&gt;encoding&lt;/span&gt;=&lt;span class="code_keywords"&gt;&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;/span&gt; &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;xsl:stylesheet &lt;span class="script_type"&gt;version&lt;/span&gt;=&amp;quot;&lt;span class="code_keywords"&gt;1.0&lt;/span&gt;&amp;quot; &lt;span class="script_type"&gt;xmlns:xsl&lt;/span&gt;=&amp;quot;&lt;span class="code_keywords"&gt;http://www.w3.org/1999/XSL/Transform&lt;/span&gt;&amp;quot; &lt;span class="script_type"&gt;xmlns:msxsl&lt;/span&gt;=&amp;quot;&lt;span class="code_keywords"&gt;urn:schemas-microsoft-com:xslt&lt;/span&gt;&amp;quot; &lt;span class="script_type"&gt;exclude-result-prefixes&lt;/span&gt; &lt;span class="code_keywords"&gt;msxsl&lt;/span&gt;&amp;quot; &lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt; &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;xsl:output method=&amp;quot;xml&amp;quot; indent=&amp;quot;yes&amp;quot;/&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
עד כאן השורות המקוריות שאומרות שהקובץ הוא xslt, שהוא בעצם גיליון עיצוב ל xml, ושהתוצאה שלו תהיה xml
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;xsl:template match=&amp;quot;/&amp;quot;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
פה אנו אומרים לו שיתחיל להתאים את העיצוב מתחילת קובץ ה xml שלי, ולא לחפש איזה אלמנט מסוים, ומתחילים להקליד לו את התבנית שאותה הוא כבר ידפיס למסך
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;&lt;span class="script_text"&gt;html&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="script_text"&gt;head&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="script_text"&gt;title&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
מכיוון שאני רוצה שהתוצאה תהיה html חוקי אני אומר לו להדפיס את תגי ה html &lt;br /&gt;
כעת אני רוצה לתת לדף שלי כותרת לפי ערך שאני בוחר מקובץ ה xml ולכן נכתוב את ההוראה:
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;xsl:value-of select=&amp;quot;/channel/title&amp;quot; /&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt; 
&lt;/p&gt;
&lt;p&gt;
ההוראה הזאת אומרת להציג ערך שהוא התוצאה של האלמנט בשם &amp;quot;channel/title&amp;quot;, כך שכל ערך שאשים במסמך ה xml שלי בתוך האלמנט הזה הוא יהיה הכותרת של הדף. &lt;br /&gt;
כעת נמשיך ב html פשוט
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;/&lt;span class="script_text"&gt;title&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&amp;lt;&lt;/span&gt;/&lt;span class="script_text"&gt;head&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="script_text"&gt;body&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
וכאן מתחיל גוף הדף, כך שכל אחד יכול לשים את העיצובים היפים שלו כאן... אני אשים div קטן כדי לישר את הכל לימין...
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;&lt;span class="script_text"&gt;div &lt;/span&gt;&lt;span class="script_type"&gt;style&lt;/span&gt;=&lt;span class="code_keywords"&gt;&amp;quot;direction:rtl&amp;quot; &lt;/span&gt;/&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
ועכשיו אני לתת הוראה לרוץ בלולאה, עבור כל אלמנט item שיש לי ב xml
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;xsl:for-each select=&amp;quot;/rss/channel/item&amp;quot;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
ועבור כל אלמנט נכתוב את התבנית הבאה:
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;&lt;span class="script_text"&gt;ddiv &lt;/span&gt;&lt;span class="script_type"&gt;style&lt;/span&gt;=&lt;span class="code_keywords"&gt;&amp;quot;direction:rtl&amp;quot;&amp;gt;/span&amp;gt; &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;&lt;span class="script_text"&gt;a&lt;/span&gt; &lt;span class="script_type"&gt;href&lt;/span&gt;=&amp;quot;{link}&amp;quot;&lt;span class="code_keywords"&gt;&amp;gt;/span&amp;gt; &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;xsl:value-of select=&amp;quot;title&amp;quot; /&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt; &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;/&lt;span class="script_text"&gt;a&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
בתוך הלינק שמתי {link} כך שהערך שנמצא באלמנט link בקובץ xml שלי יוכנס כאן. &lt;br /&gt;
ואז שוב השתמשתי במה שראינו מקודם- להציג את הערך שנמצא בתוך אלמנט title בתוך כל item. ונוסיף גם לדף שלנו את התיאור של כל item:
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_keywords"&gt;&amp;amp;&amp;lt;&lt;/span&gt;&lt;span class="script_text"&gt;span&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt; &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;lt;/span&amp;gt;xsl:value-of select=&amp;quot;description&amp;quot; disable-output-escaping=&amp;quot;yes&amp;quot; /&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt; &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;amp;&amp;lt;&lt;/span&gt;/&lt;span class="script_text"&gt;span&lt;/span&gt;&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; 
&lt;/p&gt;
&lt;p&gt;
שוב אותה שיטה, רק הוספתי גם הוראה לא לפרמט את התוצאה - הכוונה היא שאם הקורא יראה את הסימן span class=&amp;quot;code_keywords&amp;quot;&amp;gt;&amp;lt;
&lt;/p&gt;
אז לא לפרמט אותו ל &amp;amp;lt; וזאת מכיוון שיתכן שהתיאור שלי במאמר יכיל בעצמו Html כמו טקסט בולט, קו תחתון וכו&amp;#39; ואני רוצה שזה אכן יראה כמו Html ולא כמו אוסף של דברים מוזרים... &lt;br /&gt;
זהו... כעת במסמך ה xml שלי שעבורו בניתי את ה xslt יש להוסיף שורה למעלה שאומרת לקורא ה xml שיש קובץ מיוחד שמסביר איך להציג את התוכן , ולתת קישור לקובץ הזה: 
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_keywords"&gt;&amp;lt;&lt;/span&gt;?xml-stylesheet type=&amp;quot;text/xsl&amp;quot; href=&amp;quot;MyXSLT.xslt&amp;quot; version=&amp;quot;1.0&amp;quot;?&lt;span class="code_keywords"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
ישנה מחלקה מיוחדת בדוט נט בשם XPath שעוזרת לנו להשתמש ב xslt בצורה תכנותית להמרה של קבצי xml, שזה בעצם מה שהדפדפן עושה או כל קורא xml אחר, בעזרת השם נדבר על המחלקה הזאת בקרוב
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.talgiladi.net/examples/XsltExample.zip" title="download"&gt;להורדת דוגמה&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://he.wikipedia.org/wiki/XSL"&gt;למידע נוסף&lt;/a&gt;
&lt;/p&gt;
&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:99542622-deb6-4175-ac65-1d9a5de4017f" class="wlWriterEditableSmartContent" style="display: inline; float: none; margin: 0px; padding: 0px"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/xslt"&gt;xslt&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/xml"&gt;xml&lt;/a&gt;
&lt;/div&gt;
</description>
      <link>http://blog.talgiladi.net/post/XSLT.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/XSLT.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=e869cc81-ac40-435c-a640-cc9b8757ef53</guid>
      <pubDate>Tue, 03 Jun 2008 21:02:00 +0400</pubDate>
      <category>Xml</category>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=e869cc81-ac40-435c-a640-cc9b8757ef53</pingback:target>
      <slash:comments>2</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=e869cc81-ac40-435c-a640-cc9b8757ef53</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/XSLT.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=e869cc81-ac40-435c-a640-cc9b8757ef53</wfw:commentRss>
    </item>
    <item>
      <title>Creating virtual directory with code</title>
      <description>&lt;p&gt;
, לשם כך יש צורך ביצירת אתר חדש או ספריה וירטואלית חדשה (אלא אם כן השתמשתם בקאסיני...) &lt;br /&gt;
יוצא לפעמים שאנחנו צריכים להכין תוכנת התקנה של אתר ללקוחות הקוד לא ארוך ומסובך אבל מעצבן קצת. &lt;br /&gt;
קודם נוסיף הפניה לשם המתחם using System.DirectoryServices; שמשמש בעצם גם לגישה ל active directory. שימו לב שההפניה צריכה להיות דרך Add Reference : 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.talgiladi.net/image.axd?picture=addreferenceactivedirectory.png"&gt;&lt;img style="display: inline; border: 0px" src="http://blog.talgiladi.net/image.axd?picture=addreferenceactivedirectory_thumb.png" border="0" alt="addreferenceactivedirectory" title="addreferenceactivedirectory" width="522" height="404" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
כעת נפנה ל IIS:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&lt;span class="code_classes"&gt;DirectoryEntry&lt;/span&gt; iisRoot = &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;DirectoryEntry&lt;/span&gt;(&lt;span class="code_text"&gt;&amp;quot;IIS://&amp;quot;&lt;/span&gt; +
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; serverUrl + &lt;span class="code_text"&gt;&amp;quot;/W3SVC/1/Root&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
כש serverUrl זו הכתובת של המחשב שעליו מתקינים, במקרה של התקנה אצל הלקוח זה בדרך localhost &lt;br /&gt;
כעת, מכיוון שאנחנו רוצים ליצור ספריה וירטואלית ולא ליצור אתר חדש, אנחנו צריכים הפניה לאיזה אתר קיים כבר, אני אפנה לאתר הדיפולטי ושם אצור את הספריה:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&lt;span class="code_classes"&gt;DirectoryEntries&lt;/span&gt; defaultSite = iisRoot.Children; ;&lt;span class="code_remark"&gt;//default site&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
כעת ניצור את הספריה החדשה:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&lt;span class="code_classes"&gt;DirectoryEntry&lt;/span&gt; newVirtualDirectory =&amp;nbsp; defaultSite.Add(virtualDirectoryName,iisRoot.SchemaClassName.ToString());&lt;span class="code_remark"&gt;//add new site&lt;/span&gt;
&lt;/p&gt;
&lt;span&gt;newVirtualDirectory.CommitChanges();&lt;/span&gt; 
&lt;/div&gt;
&lt;p&gt;
ו virtualDirectoryName הוא כמובן שם הספריה החדשה
&lt;/p&gt;
&lt;p&gt;
כעת נגיד לו איפה נמצאים הקבצים שהספריה הזאת צריכה להציג
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
newVirtualDirectory.Properties[&lt;span class="code_text"&gt;&amp;quot;Path&amp;quot;&lt;/span&gt;].Value = physicalPath;&lt;span class="code_remark"&gt;//the path to the files&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
ו physicalPath זה כמובן הנתיב המלא לתיקיה עם הדפים של האתר החדש שלנו...
&lt;/p&gt;
&lt;p&gt;
כעת קצת מאפיינים לאתר החדש שלנו:
&lt;/p&gt;
&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red163\green21\blue21;\red0\green0\blue255;}??\fs20  newVirtualDirectory.Properties[\cf3 "AccessRead"\cf0 ][0] = \cf4 false\cf0 ;\par ??            newVirtualDirectory.Properties[\cf3 "AccessWrite"\cf0 ][0] = \cf4 true\cf0 ;\par ??\par ??            newVirtualDirectory.Invoke(\cf3 "AppCreate"\cf0 , \cf4 true\cf0 );\par ??            newVirtualDirectory.Properties[\cf3 "AppFriendlyName"\cf0 ][0] = virtualDirectoryName;}
--&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
newVirtualDirectory.Properties[&lt;span class="code_text"&gt;&amp;quot;AccessRead&amp;quot;&lt;/span&gt;][0] = &lt;span class="code_keywords"&gt;false&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; newVirtualDirectory.Properties[&lt;span class="code_text"&gt;&amp;quot;AccessWrite&amp;quot;&lt;/span&gt;][0] = &lt;span class="code_keywords"&gt;true&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; newVirtualDirectory.Invoke(&lt;span class="code_text"&gt;&amp;quot;AppCreate&amp;quot;&lt;/span&gt;, &lt;span class="code_keywords"&gt;true&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; newVirtualDirectory.Properties[&lt;span class="code_text"&gt;&amp;quot;AppFriendlyName&amp;quot;&lt;/span&gt;][0] = virtualDirectoryName;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
ובסוף לשמור
&lt;/p&gt;
&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green128\blue0;}??\fs20 newVirtualDirectory.CommitChanges();\cf3 //save the changes}
--&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
newVirtualDirectory.CommitChanges();&lt;span class="code_remark"&gt;//save the changes&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
זהו... קליל ביותר, רק קצת קשה לזכירה, אבל גם ככה בקושי משתמשים בקוד הזה אז זה בסדר... פעם אחרת בעזרת השם ניצור אתר חדש ולא ספריה וירטואלית...
&lt;/p&gt;
&lt;p&gt;
עוד משהו קטן, אם אנחנו רוצים לבדוק אם כבר קיימת כזאת ספריה וירטואלית לפני שמנסים ליצור אותה, אז ניתן להשתמש בקוד:
&lt;/p&gt;
&lt;p class="code_area"&gt;
newVirtualDirectory = defaultSite.Find(virtualDirectoryName, oDE.SchemaClassName.ToString()); 
&lt;/p&gt;
&lt;p&gt;
רק שימו לב שהפונקציה הזאת לא כל כך נחמדה, היא לא מחזירה null אלא זורקת exception אם לא נמצאה הספרייה, אז להקיף ב try catch בבקשה... תיהנו!
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.talgiladi.net/examples/ActiveDirectory.zip"&gt;להורדת פרוייקט דוגמה&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:1a018278-0fc7-41f8-9b46-8f38d4036228" class="wlWriterEditableSmartContent" style="display: inline; float: none; margin: 0px; padding: 0px"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/VirtualDirectory"&gt;VirtualDirectory&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/DirectoryEntry"&gt;DirectoryEntry&lt;/a&gt;
&lt;/div&gt;
</description>
      <link>http://blog.talgiladi.net/post/Creating-virtual-directory-with-code.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/Creating-virtual-directory-with-code.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=828635b9-50df-4b84-b674-fcd2c0795c10</guid>
      <pubDate>Tue, 03 Jun 2008 19:56:00 +0400</pubDate>
      <category>C#</category>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=828635b9-50df-4b84-b674-fcd2c0795c10</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=828635b9-50df-4b84-b674-fcd2c0795c10</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/Creating-virtual-directory-with-code.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=828635b9-50df-4b84-b674-fcd2c0795c10</wfw:commentRss>
    </item>
    <item>
      <title>Service Controller</title>
      <description>&lt;p&gt;
לעיתים אנו רוצים לשלוט ב WinService על המחשב דרך הקוד. בתוכנה שלנו למשל, מופעלים מספר שירותים על המחשב, ועוד אחד שמפקח עליהם, ועוד יש התקנה של המוצר שצריכה גם להתקין את הסרביסים האלה, ולכן שליטה מוחלטת דרך הקוד הכרחית עבורנו. לשם כך ניעזר במחלקה ServiceController.    &lt;br /&gt;
קודם כל צריכים להוסיף הפניה לאסמבלי System.ServiceProcess שכן הפניה לשם לא קיימת בברירת המחדל     &lt;br /&gt;
כעת אפשר להתחיל להשתמש בו     
&lt;/p&gt;
  
&lt;p class="code_area"&gt;
System.ServiceProcess.&lt;span class="code_classes"&gt;ServiceController&lt;/span&gt; myController = new System.ServiceProcess.&lt;span class="code_classes"&gt;ServiceController&lt;/span&gt;(svcName); 
&lt;/p&gt;
  
&lt;p&gt;
כפי שניתן לראות הבנאי שלו מקבל את שם הסרביס שאיתו אני רוצה לעבוד - השם הוא כמו שמופיע כשלוחצים alt+ctrl+del ובוחרים את טאב הסרביסים    &lt;br /&gt;
בינתיים גם אם הסרביס לא קיים הכל עובד כרגיל. ישנה בעיה קטנה - אם פונקציה שעונה לי פשוט האם סרביס קיים או לא, ולכן נתחכם קצת : 
&lt;/p&gt;
  
&lt;div class="code_area"&gt;
&lt;span class="code_keywords"&gt;if&lt;/span&gt; (myController != &lt;span class="code_keywords"&gt;null&lt;/span&gt;)    &lt;br /&gt;
{    &lt;br /&gt;
&lt;span class="code_keywords"&gt;try&lt;/span&gt;    &lt;br /&gt;
{    &lt;br /&gt;
&lt;span class="code_keywords"&gt;string&lt;/span&gt; s=myController.DisplayName;    &lt;br /&gt;
myController.Dispose();    &lt;br /&gt;
&lt;span class="code_keywords"&gt;return&lt;/span&gt; &lt;span class="code_keywords"&gt;true&lt;/span&gt;;    &lt;br /&gt;
}    &lt;br /&gt;
&lt;span class="code_keywords"&gt;catch&lt;/span&gt; { &lt;span class="code_keywords"&gt;return&lt;/span&gt; &lt;span class="code_keywords"&gt;false&lt;/span&gt;; }    &lt;br /&gt;
}    &lt;br /&gt;
&lt;span class="code_keywords"&gt;return&lt;/span&gt; &lt;span class="code_keywords"&gt;false&lt;/span&gt;;
&lt;/div&gt;
  
&lt;p&gt;
ניסינו בעצם למשוך מידע ממנו - ואם הסרביס לא קיים אז נקבל טעות ונדע שהוא לא קיים    &lt;br /&gt;
טוב אז יש לנו סרביס שקיים, כעת אנו רוצים לדעת מה המצב שלו - הוא מותקן בוודאות, אבל אולי הוא התרסק ועצר? 
&lt;/p&gt;
  
&lt;p class="code_area"&gt;
&lt;span class="code_classes"&gt;ServiceControllerStatus&lt;/span&gt; scs= myController.Status; 
&lt;/p&gt;
  
&lt;p&gt;
אם נרצה לעצור אותו, נשתמש בפונקציה מובנית 
&lt;/p&gt;
  
&lt;div class="code_area"&gt;
&lt;span class="code_keywords"&gt;switch&lt;/span&gt; (myController.Status)    &lt;br /&gt;
{    &lt;br /&gt;
&lt;span class="code_keywords"&gt;case&lt;/span&gt; ServiceControllerStatus.Stopped:    &lt;br /&gt;
&lt;span class="code_remarks"&gt;//already stopped...nothing to do&lt;/span&gt;    &lt;br /&gt;
&lt;span class="code_keywords"&gt;break&lt;/span&gt;;    &lt;br /&gt;
&lt;span class="code_keywords"&gt;case&lt;/span&gt; ServiceControllerStatus.StopPending:    &lt;br /&gt;
myController.WaitForStatus(ServiceControllerStatus.Stopped);    &lt;br /&gt;
&lt;span class="code_keywords"&gt;break&lt;/span&gt;;    &lt;br /&gt;
&lt;span class="code_keywords"&gt;default&lt;/span&gt;:     &lt;br /&gt;
myController.Stop();    &lt;br /&gt;
myController.WaitForStatus(ServiceControllerStatus.Stopped);    &lt;br /&gt;
&lt;span class="code_keywords"&gt;break&lt;/span&gt;;    &lt;br /&gt;
}    &lt;br /&gt;
myController.Close();
&lt;/div&gt;
  
&lt;p&gt;
רק נוודא שאנו ממתינים שהוא אכן יעצור...    &lt;br /&gt;
ולהריץ אותו נשתמש בשיטה זהה:
&lt;/p&gt;
  
&lt;div class="code_area"&gt;
&lt;span class="code_keywords"&gt;switch&lt;/span&gt; (myController.Status)    &lt;br /&gt;
{    &lt;br /&gt;
&lt;span class="code_keywords"&gt;case&lt;/span&gt; ServiceControllerStatus.Stopped:    &lt;br /&gt;
myController.Start();    &lt;br /&gt;
myController.WaitForStatus(ServiceControllerStatus.Running);    &lt;br /&gt;
&lt;span class="code_keywords"&gt;break&lt;/span&gt;;    &lt;br /&gt;
&lt;span class="code_keywords"&gt;case&lt;/span&gt; ServiceControllerStatus.StopPending:    &lt;br /&gt;
&lt;span class="code_remarks"&gt;//wait for it to stop&lt;/span&gt;    &lt;br /&gt;
myController.WaitForStatus(ServiceControllerStatus.Stopped);    &lt;br /&gt;
&lt;span class="code_remarks"&gt;//... and then start&lt;/span&gt;    &lt;br /&gt;
myController.Start();    &lt;br /&gt;
myController.WaitForStatus(ServiceControllerStatus.Running);    &lt;br /&gt;
&lt;span class="code_keywords"&gt;break&lt;/span&gt;;    &lt;br /&gt;
&lt;span class="code_keywords"&gt;case&lt;/span&gt; ServiceControllerStatus.StartPending:    &lt;br /&gt;
&lt;span class="code_remarks"&gt;//nothing to do...just wait&lt;/span&gt;    &lt;br /&gt;
myController.WaitForStatus(ServiceControllerStatus.Running);    &lt;br /&gt;
&lt;span class="code_keywords"&gt;break&lt;/span&gt;;    &lt;br /&gt;
&lt;span class="code_keywords"&gt;case&lt;/span&gt; ServiceControllerStatus.Running:    &lt;br /&gt;
&lt;span class="code_remarks"&gt;//nothing to do.already running...&lt;/span&gt;    &lt;br /&gt;
&lt;span class="code_keywords"&gt;break&lt;/span&gt;;    &lt;br /&gt;
&lt;span class="code_keywords"&gt;default&lt;/span&gt;:    &lt;br /&gt;
myController.Start();    &lt;br /&gt;
myController.WaitForStatus(ServiceControllerStatus.Running);    &lt;br /&gt;
&lt;span class="code_keywords"&gt;break&lt;/span&gt;;    &lt;br /&gt;
}
&lt;/div&gt;
  
&lt;p&gt;
כפי שניתן לראות השימוש די אינטואיטיבי, אנו בודקים את מצבו כרגע, לפי זה מחליטים מה לעשות, ובסוף ממתינים שאכן השינוי יתבצע
&lt;/p&gt;
  
&lt;p&gt;
עכשיו, כדי להתקין ולהסיר סרביסים דרך הקוד, כבר נצטרך שימוש בקוד c++, אבל לא הרבה... להתקנת שירות נגדיר קצת קבועים:
&lt;/p&gt;
  
&lt;div class="code_area"&gt;
&lt;span class="code_keywords"&gt;int&lt;/span&gt; SC_MANAGER_CREATE_SERVICE = 0x0002;    &lt;br /&gt;
&lt;span class="code_keywords"&gt;int&lt;/span&gt; SERVICE_WIN32_OWN_PROCESS = 0x00000010;    &lt;br /&gt;
&lt;span class="code_remarks"&gt;//int SERVICE_DEMAND_START = 0x00000003;&lt;/span&gt;    &lt;br /&gt;
&lt;span class="code_keywords"&gt;int&lt;/span&gt; SERVICE_ERROR_NORMAL = 0x00000001;    &lt;br /&gt;
&lt;span class="code_keywords"&gt;int&lt;/span&gt; STANDARD_RIGHTS_REQUIRED = 0xF0000;    &lt;br /&gt;
&lt;span class="code_keywords"&gt;int&lt;/span&gt; SERVICE_QUERY_CONFIG = 0x0001;    &lt;br /&gt;
&lt;span class="code_keywords"&gt;int&lt;/span&gt; SERVICE_CHANGE_CONFIG = 0x0002;    &lt;br /&gt;
&lt;span class="code_keywords"&gt;int&lt;/span&gt; SERVICE_QUERY_STATUS = 0x0004;    &lt;br /&gt;
&lt;span class="code_keywords"&gt;int&lt;/span&gt; SERVICE_ENUMERATE_DEPENDENTS = 0x0008;    &lt;br /&gt;
&lt;span class="code_keywords"&gt;int&lt;/span&gt; SERVICE_START = 0x0010;    &lt;br /&gt;
&lt;span class="code_keywords"&gt;int&lt;/span&gt; SERVICE_STOP = 0x0020;    &lt;br /&gt;
&lt;span class="code_keywords"&gt;int&lt;/span&gt; SERVICE_PAUSE_CONTINUE = 0x0040;    &lt;br /&gt;
&lt;span class="code_keywords"&gt;int&lt;/span&gt; SERVICE_INTERROGATE = 0x0080;    &lt;br /&gt;
&lt;span class="code_keywords"&gt;int&lt;/span&gt; SERVICE_USER_DEFINED_CONTROL = 0x0100;    &lt;br /&gt;
&lt;span class="code_keywords"&gt;int&lt;/span&gt; SERVICE_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED |    &lt;br /&gt;
SERVICE_QUERY_CONFIG |    &lt;br /&gt;
SERVICE_CHANGE_CONFIG |    &lt;br /&gt;
SERVICE_QUERY_STATUS |    &lt;br /&gt;
SERVICE_ENUMERATE_DEPENDENTS |    &lt;br /&gt;
SERVICE_START |    &lt;br /&gt;
SERVICE_STOP |    &lt;br /&gt;
SERVICE_PAUSE_CONTINUE |    &lt;br /&gt;
SERVICE_INTERROGATE |    &lt;br /&gt;
SERVICE_USER_DEFINED_CONTROL);    &lt;br /&gt;
&lt;span class="code_keywords"&gt;int&lt;/span&gt; SERVICE_AUTO_START = 0x00000002;
&lt;/div&gt;
  
&lt;p&gt;
הפונקציה שלנו תקבל 3 משתנים
&lt;/p&gt;
  
&lt;pre class="code_area"&gt;
&lt;span class="code_keywords"&gt;string&lt;/span&gt; svcPath, &lt;span class="code_keywords"&gt;string&lt;/span&gt; svcName, &lt;span class="code_keywords"&gt;string&lt;/span&gt; svcDispName
&lt;/pre&gt;
&lt;p&gt;
את הנתיב הפיסי לסרביס שאנו רוצים להתקין, את שם הסרביס ואת השם שבו הוא יוצג 
&lt;br /&gt;
וכעת להתקנה עצמה:
&lt;/p&gt;
&lt;div class="code_area"&gt;
IntPtr sc_handle =NativeMethods.OpenSCManager(&lt;span class="code_keywords"&gt;null&lt;/span&gt;,
&lt;br /&gt;
&lt;span class="code_keywords"&gt;null&lt;/span&gt;, SC_MANAGER_CREATE_SERVICE);
&lt;br /&gt;
&lt;span class="code_keywords"&gt;if&lt;/span&gt; (sc_handle.ToInt32() != 0)
&lt;br /&gt;
{
&lt;br /&gt;
IntPtr sv_handle = CreateService(sc_handle,&lt;span class="code_remarks"&gt;--&amp;gt;c++ native method&lt;/span&gt; svcName, svcDispName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, 
&lt;br /&gt;
SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, svcPath, &lt;span class="code_keywords"&gt;null&lt;/span&gt;, 0,
&lt;br /&gt;
&lt;span class="code_keywords"&gt;null&lt;/span&gt;, &lt;span class="code_keywords"&gt;null&lt;/span&gt;, &lt;span class="code_keywords"&gt;null&lt;/span&gt;);
&lt;br /&gt;
&lt;span class="code_keywords"&gt;if&lt;/span&gt; (sv_handle.ToInt32() == 0)
&lt;br /&gt;
{
&lt;br /&gt;
CloseServiceHandle(sc_handle);&lt;span class="code_remarks"&gt;--&amp;gt;c++ native method&lt;/span&gt;
&lt;br /&gt;
&lt;span class="code_keywords"&gt;throw&lt;/span&gt; &lt;span class="code_keywords"&gt;new&lt;/span&gt; 
&lt;br /&gt;
ExternalException(&lt;span class="code_text"&gt;&amp;quot;Could not create service&amp;quot;&lt;/span&gt;);
&lt;br /&gt;
}
&lt;br /&gt;
}
&lt;br /&gt;
&lt;span class="code_keywords"&gt;else&lt;/span&gt;
&lt;br /&gt;
{
&lt;br /&gt;
&lt;span class="code_keywords"&gt;throw&lt;/span&gt; &lt;span class="code_keywords"&gt;new&lt;/span&gt; 
&lt;br /&gt;
ExternalException(&lt;span class="code_text"&gt;&amp;quot;Could not open handle to service manager&amp;quot;&lt;/span&gt;);
&lt;br /&gt;
}
&lt;/div&gt;
&lt;p&gt;
כשאנו משתמשים בעצם ב 2 פונקציות מספריית windows 
&lt;br /&gt;
כמובן שצריך &lt;a name="external" title="external"&gt;&lt;/a&gt;להגדיר פונקציות חיצוניות לפני השימוש...: 
&lt;/p&gt;
&lt;div class="code_area"&gt;
[&lt;span class="code_classes"&gt;DllImport(&lt;/span&gt;
&lt;br /&gt;
&lt;span class="code_text"&gt;&amp;quot;advapi32.dll&amp;quot;&lt;/span&gt;)]
&lt;br /&gt;
&lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;static&lt;/span&gt;
&lt;br /&gt;
&lt;span class="code_keywords"&gt;extern&lt;/span&gt; &lt;span class="code_classes"&gt;IntPtr &lt;/span&gt;OpenSCManager(&lt;span class="code_keywords"&gt;string&lt;/span&gt; lpMachineName,
&lt;br /&gt;
&lt;span class="code_keywords"&gt;string&lt;/span&gt; lpSCDB, &lt;span class="code_keywords"&gt;int&lt;/span&gt; scParameter);
&lt;br /&gt;
[&lt;span class="code_classes"&gt;DllImport&lt;/span&gt;(&lt;span class="code_text"&gt;&amp;quot;Advapi32.dll&amp;quot;&lt;/span&gt;)]
&lt;br /&gt;
&lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;static&lt;/span&gt;
&lt;br /&gt;
&lt;span class="code_keywords"&gt;extern&lt;/span&gt; &lt;span class="code_classes"&gt;IntPtr &lt;/span&gt;CreateService(&lt;span class="code_classes"&gt;IntPtr &lt;/span&gt;SC_HANDLE, 
&lt;br /&gt;
&lt;span class="code_keywords"&gt;string&lt;/span&gt; lpSvcName, &lt;span class="code_keywords"&gt;string&lt;/span&gt; lpDisplayName,
&lt;br /&gt;
&lt;span class="code_keywords"&gt;int&lt;/span&gt; dwDesiredAccess, &lt;span class="code_keywords"&gt;int&lt;/span&gt; 
&lt;br /&gt;
dwServiceType, &lt;span class="code_keywords"&gt;int&lt;/span&gt; dwStartType, &lt;span class="code_keywords"&gt;int&lt;/span&gt; 
&lt;br /&gt;
dwErrorControl, &lt;span class="code_keywords"&gt;string&lt;/span&gt; lpPathName,
&lt;br /&gt;
&lt;span class="code_keywords"&gt;string&lt;/span&gt; lpLoadOrderGroup, &lt;span class="code_keywords"&gt;int&lt;/span&gt; 
&lt;br /&gt;
lpdwTagId, &lt;span class="code_keywords"&gt;string&lt;/span&gt; lpDependencies, &lt;span class="code_keywords"&gt;string&lt;/span&gt; lpServiceStartName, &lt;span class="code_keywords"&gt;string&lt;/span&gt; 
&lt;br /&gt;
lpPassword);
&lt;/div&gt;
&lt;p&gt;
ההגדרה DllImport היא ממש לפי המשמעות - אנו מגדירים הפניה ל DLL מקומי, מגדירים איך נראית הפונקציה ואז ניתן לפנות אליה 
&lt;br /&gt;
זה אמור להספיק כדי להתקין את הסרביס... 
&lt;br /&gt;
אם נרצה להסיר אותו השיטה דומה- קודם נעצור אותו בעזרת השיטה שראינו לעיל, אחר כך נקרא לפונקציות חיצוניות כדי להסיר ולמחוק אותו 
&lt;/p&gt;
&lt;div class="code_area"&gt;
StopService(svcName);&lt;span class="code_remarks"&gt;--&amp;gt;out function&lt;/span&gt;
&lt;br /&gt;
&lt;span class="code_keywords"&gt;int&lt;/span&gt; GENERIC_WRITE = 0x40000000;
&lt;br /&gt;
&lt;span class="code_classes"&gt;IntPtr &lt;/span&gt;sc_hndl = OpenSCManager(
&lt;br /&gt;
&lt;span class="code_keywords"&gt;null&lt;/span&gt;, pan class=&amp;quot;code_keywords&amp;quot;&amp;gt;nunull, GENERIC_WRITE);
&lt;br /&gt;
&lt;span class="code_remarks"&gt;--&amp;gt;c++ method&lt;/span&gt;
&lt;br /&gt;
&lt;span class="code_keywords"&gt;if&lt;/span&gt; (sc_hndl.ToInt32() != 0)
&lt;br /&gt;
{
&lt;br /&gt;
&lt;span class="code_keywords"&gt;int&lt;/span&gt; DELETE = 0x10000;
&lt;br /&gt;
&lt;span class="code_classes"&gt;IntPtr &lt;/span&gt;svc_hndl = OpenService(sc_hndl, svcName, 
&lt;br /&gt;
DELETE);&lt;span class="code_remarks"&gt;--&amp;gt;c++ method&lt;/span&gt;
&lt;br /&gt;
&lt;span class="code_keywords"&gt;if&lt;/span&gt; (svc_hndl.ToInt32() != 0)
&lt;br /&gt;
style=&amp;quot;color: #a31515&amp;quot; {
&lt;br /&gt;
&lt;span class="code_keywords"&gt;int&lt;/span&gt; i = DeleteService(svc_hndl);
&lt;br /&gt;
&lt;span class="code_remarks"&gt;--&amp;gt;c++ method&lt;/span&gt;
&lt;br /&gt;
&lt;span class="code_keywords"&gt;if&lt;/span&gt; (i != 0)
&lt;br /&gt;
{
&lt;br /&gt;
CloseServiceHandle(sc_hndl);&lt;span class="code_remarks"&gt;--&amp;gt;c++ method&lt;/span&gt;
&lt;br /&gt;
}
&lt;br /&gt;
&lt;span class="code_keywords"&gt;else&lt;/span&gt;
&lt;br /&gt;
{
&lt;br /&gt;
CloseServiceHandle(sc_hndl);&lt;span class="code_remarks"&gt;--&amp;gt;c++ method&lt;/span&gt;
&lt;br /&gt;
&lt;span class="code_keywords"&gt;throw&lt;/span&gt; &lt;span class="code_keywords"&gt;new&lt;/span&gt; ExternalException(&lt;span class="code_text"&gt;&amp;quot;Could not delete service&amp;quot;&lt;/span&gt;); 
&lt;br /&gt;
}
&lt;br /&gt;
}
&lt;br /&gt;
&lt;span class="code_keywords"&gt;else&lt;/span&gt;
&lt;br /&gt;
&lt;span class="code_keywords"&gt;throw&lt;/span&gt; &lt;span class="code_keywords"&gt;new&lt;/span&gt; 
&lt;br /&gt;
ExternalException(&lt;span class="code_text"&gt;&amp;quot;Could not open service&amp;quot;&lt;/span&gt;);
&lt;br /&gt;
}
&lt;br /&gt;
&lt;span class="code_keywords"&gt;else&lt;/span&gt; &lt;span class="code_keywords"&gt;throw&lt;/span&gt; &lt;span class="code_keywords"&gt;new&lt;/span&gt; ExternalException(&lt;span class="code_text"&gt;&amp;quot;Could not open handle to service manager&amp;quot;&lt;/span&gt;);
&lt;/div&gt;
&lt;p&gt;
לא מסובך כל כך... אומנם משעמם להשתמש בפונקציות והגדרות מובנות במערכת ההפעלה, אבל סביר...
&lt;/p&gt;
&lt;p&gt;
ל&lt;a href="http://www.talgilad.net/examples/WinServiceControl.zip"&gt;הורדת הפרוייקט&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
חלק מהקוד נלקח מ &lt;a href="http://www.thescripts.com/forum/post932461-9.html"&gt;http://www.thescripts.com/forum/post932461-9.html&lt;/a&gt;
&lt;/p&gt;
&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:152890dc-ac18-45c1-9b7d-30a153a3da05" class="wlWriterEditableSmartContent" style="margin: 0px; padding: 0px; display: inline; float: none"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/ServiceController"&gt;ServiceController&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/WinService"&gt;WinService&lt;/a&gt;
&lt;/div&gt;
</description>
      <link>http://blog.talgiladi.net/post/Service-Controller.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/Service-Controller.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=07ec374d-8869-4941-82ef-72af28cae3fb</guid>
      <pubDate>Mon, 02 Jun 2008 21:50:00 +0400</pubDate>
      <category>C#</category>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=07ec374d-8869-4941-82ef-72af28cae3fb</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=07ec374d-8869-4941-82ef-72af28cae3fb</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/Service-Controller.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=07ec374d-8869-4941-82ef-72af28cae3fb</wfw:commentRss>
    </item>
    <item>
      <title>Secure Web Services</title>
      <description>&lt;p&gt;
אני אכתוב כמה מילים על שירותי ווב מאובטחים. כשאני בונה WebService ואני רוצה שהמשתמשים יזדהו לפני השימוש, אז נכון שאני יכול לדרוש שחלק מהפרמטרים יהיו השם משתמש וסיסמה, אבל זו לא הדרך הטובה יותר, דרך יותר נכונה תהיה להשתמש ב Header שהסרביס מקבל, והוא יכיל את שם המשתמש והסיסמה. &lt;br /&gt;
בואו ניצור משהו פשוט: 
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;a href="http://blog.talgiladi.net/image.axd?picture=webservice.png"&gt;&lt;img style="display: inline; border: 0px" src="http://blog.talgiladi.net/image.axd?picture=webservice_thumb.png" border="0" alt="webservice" title="webservice" width="575" height="419" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
עכשיו ניצור מחלקה חדשה שתייצג את ה Header שלנו 
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_keywords"&gt;public class&lt;/span&gt; &lt;span class="code_classes"&gt;SecurityHeader&lt;/span&gt; : System.Web.Services.Protocols.&lt;span class="code_classes"&gt;SoapHeader&lt;/span&gt; &lt;br /&gt;
{ &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string&lt;/span&gt; username; &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string&lt;/span&gt; pass; &lt;br /&gt;
} 
&lt;/p&gt;
&lt;p&gt;
כעת נגיד לשירות שלנו שהוא אמור לחכות ל Header הזה 
&lt;/p&gt;
&lt;p class="code_area"&gt;
[&lt;span class="code_classes"&gt;WebMethod&lt;/span&gt;] &lt;br /&gt;
[&lt;span class="code_classes"&gt;SoapHeader&lt;/span&gt;(&lt;span class="code_text"&gt;&amp;quot;SecurityHeader&amp;quot;&lt;/span&gt;)] &lt;br /&gt;
&lt;span class="code_keywords"&gt;public string&lt;/span&gt; HelloWorldSecure() { 
&lt;/p&gt;
&lt;p&gt;
כפי שניתן לראות מדובר בסך הכל בתוספת של שורה אחת &lt;br /&gt;
עכשיו עוד דבר קטן, נגדיר משתנה גלובלי מסוג המחלקה של ה Header שלנו 
&lt;/p&gt;
&lt;p class="code_area"&gt;
public class &lt;span class="code_classes"&gt;SayHello&lt;/span&gt; : System.Web.Services.&lt;span class="code_classes"&gt;WebService&lt;/span&gt; &lt;br /&gt;
{ &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public &lt;span class="code_classes"&gt;SecurityHeader&lt;/span&gt; secHeader; 
&lt;/p&gt;
&lt;p&gt;
כעת כל פעם שמישהו יקרה לסרביס שלנו, השרת יבדוק אם יש לו Header מהסוג שציינו, ואם כן הוא יכניס את הערכים שהוא קיבל למשתנה הגלובלי שלנו במחלקה. כעת בתוך השירות אנחנו רק צריכים לבדוק שאכן המשתנה הגלובלי קיבל ערך(אכן יש כזה Header) ואז ניתן לבדוק את הנתונים שלו (שם משתמש וסיסמה במקרה שלנו) 
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_keywords"&gt;if&lt;/span&gt; (secHeader == &lt;span class="code_keywords"&gt;null&lt;/span&gt;) &lt;br /&gt;
{ &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/span&gt; &lt;span class="code_text"&gt;&amp;quot;Please authenticate!&amp;quot;&lt;/span&gt;; &lt;br /&gt;
} &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/span&gt; (secHeader.username == &lt;span class="code_text"&gt;&amp;quot;tal&amp;quot;&lt;/span&gt; &amp;amp;&amp;amp; secHeader.pass == &lt;span class="code_text"&gt;&amp;quot;giladi&amp;quot;&lt;/span&gt;) &lt;br /&gt;
{ &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/span&gt; &lt;span class="code_text"&gt;&amp;quot;Shalom &amp;quot;&lt;/span&gt; + secHeader.username; &lt;br /&gt;
} &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;/span&gt; &lt;br /&gt;
{ &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/span&gt; &lt;span class="code_text"&gt;&amp;quot;Bad username or password&amp;quot;&lt;/span&gt;; &lt;br /&gt;
} 
&lt;/p&gt;
&lt;p&gt;
עכשיו להשתמש בזה בצד הלקוח זה עוד יותר קל אפילו... &lt;br /&gt;
ניצור הפניה לשירות שלנו 
&lt;/p&gt;
&lt;p class="code_area"&gt;
&amp;nbsp;&lt;a href="http://blog.talgiladi.net/image.axd?picture=WebServiceRefference.png"&gt;&lt;img style="display: inline; border: 0px" src="http://blog.talgiladi.net/image.axd?picture=WebServiceRefference_thumb.png" border="0" alt="WebServiceRefference" title="WebServiceRefference" width="608" height="424" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
קראתי להפניה הזאת server_sayHello &lt;br /&gt;
ניצור אובייקט של ההפניה הזאת 
&lt;/p&gt;
&lt;p class="code_area"&gt;
server_sayHello.&lt;span class="code_classes"&gt;SayHello&lt;/span&gt; sayHello = new server_sayHello.&lt;span class="code_classes"&gt;SayHello&lt;/span&gt;(); 
&lt;/p&gt;
&lt;p&gt;
ניצור הפניה של ה Header שלנו באותה צורה 
&lt;/p&gt;
&lt;p class="code_area"&gt;
server_sayHello.&lt;span class="code_classes"&gt;SecurityHeader&lt;/span&gt; secHeader = new server_sayHello.&lt;span class="code_classes"&gt;SecurityHeader&lt;/span&gt;(); 
&lt;/p&gt;
&lt;p&gt;
ניתן ערכים לשם והסיסמה 
&lt;/p&gt;
&lt;p class="code_area"&gt;
secHeader.UserName = &lt;span class="code_text"&gt;&amp;quot;tal&amp;quot;&lt;/span&gt;; &lt;br /&gt;
secHeader.Password = &lt;span class="code_text"&gt;&amp;quot;giladi&amp;quot;&lt;/span&gt;; &lt;br /&gt;
sayHello.SecurityHeaderValue = secHeader; 
&lt;/p&gt;
&lt;p&gt;
וזהו... פשוט נקרא לשירות: 
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_keywords"&gt;string&lt;/span&gt; result = sayHello.HelloWorldSecure(); 
&lt;/p&gt;
&lt;p&gt;
* אם אנחנו רוצים שהשירות יהיה מאובטח גם בעזרת SSL,(בהנחה שיש לכם תעודה והגדרתם אותה לשרת) פשוט נעשה מה שאנחנו עושים בדף ווב רגיל, &lt;br /&gt;
נוסיף שורה בסרביס עצמו, בתוך הפונקציה שלנו: 
&lt;/p&gt;
&lt;p class="code_area"&gt;
if (!&lt;span class="code_classes"&gt;HttpContext&lt;/span&gt;.Current.Request.IsSecureConnection) &lt;br /&gt;
{ &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/span&gt; &lt;span class="code_text"&gt;&amp;quot;Please use secure connection!&amp;quot;&lt;/span&gt;; &lt;br /&gt;
} 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.talgiladi.net/examples/SecureWebService.zip"&gt;להורדת הפרוייקט&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:a8f106c5-45b0-4fc7-a4c7-c4d0cd7e86a2" class="wlWriterEditableSmartContent" style="display: inline; float: none; margin: 0px; padding: 0px"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/WebServices"&gt;WebServices&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/Security"&gt;Security&lt;/a&gt; 
&lt;/div&gt;
</description>
      <link>http://blog.talgiladi.net/post/Secure-Web-Services.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/Secure-Web-Services.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=e80c3cfb-dd4c-4f90-8e61-079075935241</guid>
      <pubDate>Fri, 23 May 2008 20:52:00 +0400</pubDate>
      <category>Security</category>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=e80c3cfb-dd4c-4f90-8e61-079075935241</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=e80c3cfb-dd4c-4f90-8e61-079075935241</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/Secure-Web-Services.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=e80c3cfb-dd4c-4f90-8e61-079075935241</wfw:commentRss>
    </item>
    <item>
      <title>Save &amp; Retrieve Image from DataBase</title>
      <description>&lt;p&gt;
משום מה השאלה הזאת נשאלת שוב ושוב בפורומים...
&lt;br /&gt;
לשמור זה די ברור איך, אני יוצר פקודת sql עם פרמטרים, או stored procedure ,ומעביר אליה את הבתים של התמונה, כמובן שהעמודה בדטה בייס צריכה להיות מסוג image/binary.
&lt;br /&gt;
לדוגמה:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&lt;span class="code_keywords"&gt;byte&lt;/span&gt;[] imagedata = &lt;span class="code_keywords"&gt;null&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;//now we can get the image bytes with filestream on local system, or from FileUpload on our web page&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Data.SqlClient.&lt;span class="code_classes"&gt;SqlConnection&lt;/span&gt; con=&lt;span class="code_keywords"&gt;new&lt;/span&gt; System.Data.SqlClient.&lt;span class="code_classes"&gt;SqlConnection&lt;/span&gt;(&lt;span class="code_text"&gt;&amp;quot;myconstring&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Data.SqlClient.&lt;span class="code_classes"&gt;SqlCommand&lt;/span&gt; com = &lt;span class="code_keywords"&gt;new&lt;/span&gt; System.Data.SqlClient.&lt;span class="code_classes"&gt;SqlCommand&lt;/span&gt;(&lt;span class="code_text"&gt;&amp;quot;insert into images (imagename,imagedata) values (@imagename,@imagedata)&amp;quot;&lt;/span&gt;, con);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; com.Parameters.Add(&lt;span class="code_keywords"&gt;new&lt;/span&gt; System.Data.SqlClient.&lt;span class="code_classes"&gt;SqlParameter&lt;/span&gt;(&lt;span class="code_text"&gt;&amp;quot;@imagename&amp;quot;&lt;/span&gt;, &lt;span class="code_text"&gt;&amp;quot;myimage.gif&amp;quot;&lt;/span&gt;));
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; com.Parameters.Add(&lt;span class="code_keywords"&gt;new&lt;/span&gt; System.Data.SqlClient.&lt;span class="code_classes"&gt;SqlParameter&lt;/span&gt;(&lt;span class="code_text"&gt;&amp;quot;@imagedata&amp;quot;&lt;/span&gt;, imagedata));
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; con.Open();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; com.ExecuteNonQuery();
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
יופי, איך מושכים, כרגיל, פקודת select רגילה כשמה שאנו מקבלים מהעמודה הזאת היא מערך של בתים עם נתוני התמונה.
&lt;br /&gt;
עכשיו כדי להציג אותה ללקוח יש כמה שיטות. קודם כל ניתן להפוך את מערך הבתים לאובייקט של BitMap 
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp; &lt;span class="code_keywords"&gt;byte&lt;/span&gt;[] b=&lt;span class="code_keywords"&gt;null&lt;/span&gt;;//&lt;span class="code_remarks"&gt;get bytes from data base... b=(byte[])com.ExecuteScalar(&amp;quot;select imagedata from myimages where...)&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;MemoryStream&lt;/span&gt; ms=&lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;MemoryStream&lt;/span&gt;(b);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Drawing.&lt;span class="code_classes"&gt;Bitmap&lt;/span&gt; bm = &lt;span class="code_keywords"&gt;new&lt;/span&gt; System.Drawing.&lt;span class="code_classes"&gt;Bitmap&lt;/span&gt;(ms);
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
או אם יש לי באתר דף שאמור להציג תמונות מדטה בייס לפי איזה פרמטר שהוא מקבל נשתמש ב Response.BinaryWrite כדי לכתוב את מערך הבתים. בדף הרגיל שבו מוצג הטקסט והתמונות נשים כתובת של תמונה עם כתובת של דף אחר, ובדף האחר נשתמש בפונקציה הזאת כדי לשלוח את הבתים בתור תמונה
&lt;/p&gt;
&lt;p&gt;
נניח שיש לי דף PictureGallery.aspx
&lt;br /&gt;
בתוך הדף אני רוצה להציג תמונות שימשכו מהדטה בייס. אני יוצר דף מיוחד שכל תפקידו הוא למשוך תמונה מהדטה בייס ולשלוח אותה ללקוח, נקרא לו PictureView.aspx
&lt;br /&gt;
בדף PictureGallery.aspx אני שם לינקים לדף PictureView.aspx בתור כתובת של תמונה:
&lt;/p&gt;
&lt;p class="code_area"&gt;
&amp;lt;img src=&amp;quot;PictureView.aspx?imgid=34&amp;quot;/&amp;gt;
&lt;/p&gt;
&lt;p&gt;
וככה מוסיף תמונות כמה שארצה. כעת בדף PictureView.aspx הקוד יראה משהו כמו:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&lt;span class="code_keywords"&gt;byte&lt;/span&gt;[] b = (&lt;span class="code_keywords"&gt;byte&lt;/span&gt;[])com.ExecuteScalar(&lt;span class="code_text"&gt;&amp;quot;select imagedata from myimages where imageid=&amp;quot;&lt;/span&gt; + Request.Params[&lt;span class="code_text"&gt;&amp;quot;imgid&amp;quot;&lt;/span&gt;]);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Response.ContentType = &lt;span class="code_text"&gt;&amp;quot;image/jpeg&amp;quot;&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Response.BinaryWrite(b);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Response.End();
&lt;/p&gt;
&lt;/div&gt;
&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:ff54dcbd-ee9a-49a5-bca7-c335a6b96df2" class="wlWriterEditableSmartContent" style="margin: 0px; padding: 0px; display: inline; float: none"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/Sql"&gt;Sql&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/SqlParameter"&gt;SqlParameter&lt;/a&gt;
&lt;/div&gt;
</description>
      <link>http://blog.talgiladi.net/post/Save-Retrieve-Image-from-DataBase.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/Save-Retrieve-Image-from-DataBase.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=e7c90d6f-70d3-43c4-95f1-1fa94049c9b1</guid>
      <pubDate>Mon, 05 May 2008 21:28:00 +0400</pubDate>
      <category>C#</category>
      <category>sql</category>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=e7c90d6f-70d3-43c4-95f1-1fa94049c9b1</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=e7c90d6f-70d3-43c4-95f1-1fa94049c9b1</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/Save-Retrieve-Image-from-DataBase.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=e7c90d6f-70d3-43c4-95f1-1fa94049c9b1</wfw:commentRss>
    </item>
    <item>
      <title>Zip</title>
      <description>&lt;p&gt;
כיווץ בפורמט zip ניתן לביצוע בפשטות בדוט נט עם המחלקות היעודיות לכך. &lt;br /&gt;
קודם יש להוסיף את השורה using System.IO.Compression &lt;br /&gt;
וכעת ניתן להשתמש במחלקה שנקראת GZipStream
&lt;/p&gt;
&lt;p&gt;
הבנאי מקבל 2 פרמטרים - את הזרם שממנו/אליו צריך לקרוא/לכתוב, ואת צורת הפעולה - לכווץ או לפתוח את המידע &lt;br /&gt;
&lt;br /&gt;
קודם נבחר איזה קובץ אנחנו רוצים לקבץ:
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_classes"&gt;FileStream&lt;/span&gt; source = &lt;span class="code_keywords"&gt;new &lt;/span&gt;&lt;span class="code_classes"&gt;FileStream&lt;/span&gt;(Server.MapPath(&lt;span class="code_text"&gt;&amp;quot;myfile.txt&amp;quot;&lt;/span&gt;), &lt;span class="code_classes"&gt;FileMode&lt;/span&gt;.Create);
&lt;/p&gt;
&lt;p&gt;
את הקובץ שאליו נשמור את המידע המכווץ:
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_classes"&gt;FileStream &lt;/span&gt;target = &lt;span class="code_keywords"&gt;new &lt;/span&gt;&lt;span class="code_classes"&gt;FileStream&lt;/span&gt;(Server.MapPath(&lt;span class="code_text"&gt;&amp;quot;myzip.zip&amp;quot;&lt;/span&gt;), &lt;span class="code_classes"&gt;FileMode&lt;/span&gt;.Create);
&lt;/p&gt;
&lt;p&gt;
נבנה את האובייקט ונבחר באופצית הכיווץ: 
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_classes"&gt;GZipStream &lt;/span&gt;zip = &lt;span class="code_keywords"&gt;new &lt;/span&gt;&lt;span class="code_classes"&gt;GZipStream&lt;/span&gt;(target , &lt;span class="code_classes"&gt;CompressionMode&lt;/span&gt;.Compress); 
&lt;/p&gt;
&lt;p&gt;
וכעת נעביר את הבתים מקובץ המקור לקובץ המטרה:
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_keywords"&gt;int&lt;/span&gt; bytesCount; &lt;br /&gt;
&lt;span class="code_keywords"&gt;byte&lt;/span&gt;[] buffer=&lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_keywords"&gt;byte&lt;/span&gt; [1024]; &lt;br /&gt;
&lt;span class="code_keywords"&gt;while&lt;/span&gt;((bytesCount = source .Read(buffer, 0, buffer.Length)) != 0) &lt;br /&gt;
{ &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; zip.Write(buffer, 0, bytesCount); &lt;br /&gt;
} &lt;br /&gt;
target.Close(); &lt;br /&gt;
zip.Close(); &lt;br /&gt;
&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
לא לשכוח לסגור את הקובץ בסוף! &lt;br /&gt;
ובשביל לקרוא קובץ מכווץ התהליך דומה, נפתח את הקובץ שמכיל את המידע המכווץ:
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_classes"&gt;FileStream &lt;/span&gt;source = &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;FileStream&lt;/span&gt;(Server.MapPath(&lt;span class="code_text"&gt;&amp;quot;myzip.zip&amp;quot;&lt;/span&gt;), &lt;span class="code_classes"&gt;FileMode&lt;/span&gt;.Open);
&lt;/p&gt;
&lt;p&gt;
את הקובץ שאליו נשמור את המידע שנפתח:
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_classes"&gt;FileStream &lt;/span&gt;target = &lt;span class="code_keywords"&gt;new &lt;/span&gt;&lt;span class="code_classes"&gt;FileStream&lt;/span&gt;(Server.MapPath(&lt;span class="script_text"&gt;&amp;quot;myfile.txt&amp;quot;&lt;/span&gt;), &lt;span class="code_classes"&gt;FileMode &lt;/span&gt;.Create); 
&lt;/p&gt;
&lt;p&gt;
נבנה את האובייקט וכעת נחבר באופצית הפתיחה, לא כיווץ: 
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_classes"&gt;GZipStream &lt;/span&gt;zip = &lt;span class="code_keywords"&gt;new &lt;/span&gt;&lt;span class="code_classes"&gt;GZipStream&lt;/span&gt;(source, &lt;span class="code_classes"&gt;CompressionMode &lt;/span&gt;.Decompress); 
&lt;/p&gt;
&lt;p&gt;
וכעת נעביר את הבתים מהזיפ שלנו לקובץ המטרה:
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_keywords"&gt;int&lt;/span&gt; bytesCount; &lt;br /&gt;
&lt;span class="code_keywords"&gt;byte[]&lt;/span&gt; buffer=&lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_keywords"&gt;byte &lt;/span&gt;[1024]; &lt;br /&gt;
&lt;span class="code_keywords"&gt;while &lt;/span&gt;((bytesCount = zip.Read(buffer, 0, buffer.Length)) != 0) &lt;br /&gt;
{ &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; target .Write(buffer, 0, bytesCount); &lt;br /&gt;
} &lt;br /&gt;
target.Close(); &lt;br /&gt;
zip.Close(); 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.talgiladi.net/examples/compression.zip"&gt;להורדת הפרוייקט&lt;/a&gt;
&lt;/p&gt;
&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:90d757f4-6c37-4f0a-9c9c-f94320b14c84" class="wlWriterEditableSmartContent" style="display: inline; float: none; margin: 0px; padding: 0px"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/GZipStream"&gt;GZipStream&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/Zip"&gt;Zip&lt;/a&gt;
&lt;/div&gt;
</description>
      <link>http://blog.talgiladi.net/post/Zip.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/Zip.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=ac33d00a-6501-4cea-948a-ba2e784edf40</guid>
      <pubDate>Tue, 15 Apr 2008 21:16:00 +0400</pubDate>
      <category>C#</category>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=ac33d00a-6501-4cea-948a-ba2e784edf40</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=ac33d00a-6501-4cea-948a-ba2e784edf40</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/Zip.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=ac33d00a-6501-4cea-948a-ba2e784edf40</wfw:commentRss>
    </item>
    <item>
      <title>Weak Reference</title>
      <description>&lt;p&gt;
מוזר שהרבה לא שמעו על המחלקה הזאת... &lt;br /&gt;
מה היא עושה? ובכן אנו יודעים שסביבת הריצה של הדוט נט סופרת הפניות לכל אובייקט. כשאני יוצר אובייקט חדש, המשתנה שאני מגדיר הוא בעצם הפניה, כתובת , לאובייקט שיצרתי בזיכרון. לדוגמה: 
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_classes"&gt;Bitmap &lt;/span&gt;picture=&lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;Bitmap&lt;/span&gt;(&lt;span class="code_text"&gt;&amp;quot;pic.gif&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;p&gt;
בחלק שמאל אני מגדיר הפניה בשם picture לאובייקט שיצרתי בצד ימין והוא מסוג Bitmap &lt;br /&gt;
וסביבת הריצה כותבת לה בצד שיש הפניה אחת לאובייקט הזה ולכן היא לא מנקה אותו מהזיכרון. בשורה הבאה: 
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_classes"&gt;Bitmap &lt;/span&gt;pic2=picture; 
&lt;/p&gt;
&lt;p&gt;
הגדרתי עוד הפניה בשם pic2 לאותו אובייקט בזיכרון, וסביבת הריצה כותבת לעצמה שיש 2 הפניות לאותו אובייקט. כל עוד יש הפניות לאובייקט סביבת הריצה לא יכולה לנקות את אותו מקום בזיכרון. מתי מורידים הפניות? או שהגדרתי משתנה בתוך פונקציה והפונקציה סיימה את תפקידה ואז אותו משתנה מסומן כהפניה אחת פחות. או שהגדרתי משתנה במחלקה עצמה ואותה מחלקה סיימה את תפקידה, או שבפירוש הודעתי שאני לא צריך את ההפניה על ידי : 
&lt;/p&gt;
&lt;p class="code_area"&gt;
picture=&lt;span class="code_keywords"&gt;null&lt;/span&gt;; 
&lt;/p&gt;
&lt;p&gt;
עד כאן הייתה ההקדמה שרובנו יודעים. עכשיו לנושא שלנו. נניח שאני רוצה לשמור בזיכרון הפניה לאובייקטים כדי לא לפנות אליהם כל פעם מחדש, לדוגמה DataSet מתוך דטה בייס. אם אני אתחיל למלא את הזיכרון במידע הוא עשוי להיגמר, מצד שני אני רוצה שהאפליקציה תרוץ מהר ולא תמשוך כל פעם מהדטה בייס... בשביל זה ניתן להשתמש ב WeakReference. המחלקה הזאת מוסיפה הפניה לאובייקט, כך שהוא לא נמחק מהזיכרון, אך זאת הפניה &amp;quot;חלשה&amp;quot;, זאת אומרת שאנחנו לא מכריחים את סביבת הריצה לשמור את האובייקט תמיד בזיכרון, זאת יותר מעין בקשה - תשמרו לי הפניה לאובייקט, אבל אם הזיכרון מתחיל להיגמר אתם יכולים למחוק אותו ואז ההפניה שלי תצביע לאובייקט שלא קיים... &lt;br /&gt;
זה כל הסיפור... שימו לב לקוד: 
&lt;/p&gt;
&lt;p class="code_area"&gt;
System.Drawing.&lt;span class="code_classes"&gt;Bitmap &lt;/span&gt;picture=&lt;span class="code_keywords"&gt;new&lt;/span&gt; System.Drawing.&lt;span class="code_classes"&gt;Bitmap&lt;/span&gt;(&lt;span class="code_text"&gt;&amp;quot;pic.gif&amp;quot;&lt;/span&gt;);&lt;span class="code_rem"&gt;//we save a big object in memory&lt;/span&gt; &lt;br /&gt;
&lt;span class="code_classes"&gt;WeakReference&lt;/span&gt; wr = &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;WeakReference&lt;/span&gt;(picture);&lt;span class="code_rem"&gt;//assign a weak reference to it&lt;/span&gt; &lt;br /&gt;
picture = &lt;span class="code_keywords"&gt;null&lt;/span&gt;;&lt;span class="code_rem"&gt;//dispose the strong reference&lt;/span&gt; &lt;br /&gt;
&lt;span class="code_rem"&gt;//do other stuff&lt;/span&gt; &lt;br /&gt;
System.Drawing.&lt;span class="code_classes"&gt;Bitmap &lt;/span&gt;mypicture = wr.Get() &lt;span class="code_keywords"&gt;as&lt;/span&gt; System.Drawing.Bitmap;&lt;span class="code_rem"&gt;//we try to get our picture&lt;/span&gt; &lt;br /&gt;
&lt;span class="code_keywords"&gt;if&lt;/span&gt; (mypicture == &lt;span class="code_keywords"&gt;null&lt;/span&gt;)&lt;span class="code_rem"&gt;//we check if it still exists... null? it has bee disposed already...&lt;/span&gt; &lt;br /&gt;
{ &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; mypicture = &lt;span class="code_keywords"&gt;new&lt;/span&gt; System.Drawing.&lt;span class="code_classes"&gt;Bitmap&lt;/span&gt;(&lt;span class="code_text"&gt;&amp;quot;pic.gif&amp;quot;&lt;/span&gt;); &lt;br /&gt;
}
&lt;/p&gt;
&lt;p&gt;
יצרתי אובייקט שתופס הרבה מקום וגם לוקח זמן לטעון אותו. &lt;br /&gt;
יצרתי הפניה חלשה אליו. &lt;br /&gt;
הודעתי שאני לא רוצה את ההפניה החזקה אליו. תזכרו שאם יש הפניה חזקה לאובייקט הוא לא ימחק וזה לא מה שאני רוצה! &lt;br /&gt;
כעת אני עושה דברים אחרים באפליקציה... &lt;br /&gt;
עכשיו כשאני רוצה להשתמש באובייקט התמונה שלי, אני שוב יוצר הפניה חזקה אליו בשם mypicture &lt;br /&gt;
אבל... וזה כל העניין פה... אני צרי לבדוק שעדיין יש לי אובייקט! כל הקטע הוא שאני הרשיתי לסביבת הריצה למחוק את האובייקט במקרה הצורך, ולכן אני צריך לבדוק שהוא לא נמחק... 
&lt;/p&gt;
&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:f75d0ec1-a57a-4216-b5c2-88441ac05c84" class="wlWriterEditableSmartContent" style="display: inline; float: none; margin: 0px; padding: 0px"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/WeakReference"&gt;WeakReference&lt;/a&gt;
&lt;/div&gt;
</description>
      <link>http://blog.talgiladi.net/post/Weak-Reference.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/Weak-Reference.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=15ce46f3-6dc1-435e-9e96-83e37409fe68</guid>
      <pubDate>Thu, 03 Apr 2008 20:49:00 +0400</pubDate>
      <category>C#</category>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=15ce46f3-6dc1-435e-9e96-83e37409fe68</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=15ce46f3-6dc1-435e-9e96-83e37409fe68</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/Weak-Reference.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=15ce46f3-6dc1-435e-9e96-83e37409fe68</wfw:commentRss>
    </item>
    <item>
      <title>מציאת מיקום אלמנט בדפדפן</title>
      <description>&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:d84ae7b2-7e48-4f7e-81cf-1b47c1a7e16c" class="wlWriterEditableSmartContent" style="float: none; margin: 0px; display: inline; padding: 0px"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/javascript"&gt;javascript&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/position"&gt;position&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;
מצאתי 2 פונקציות טובות למציאת מיקום מדויק של אלמנט על המסך , אך לצערי צריך לנסות את שתיהן, כי יש דפים שבם אחת מחזירה תוצאות יותר מדויקות ויש דפים שהשניה... ומכיוון שאינני מומחה כל כך גדול בג&amp;#39;אווה סקריפט, אני גם לא יכול לשפר אותן, אבל עדיין, הן טובות, רק תעשו ניסוי קטן בכל דף לבדוק איזו מהן מתאימה 
&lt;/p&gt;
&lt;p&gt;
הפונקציה הראשונה - שולחים לה את האובייקט (לא את השם שלו...) והיא מחזירה אובייקט עם ערך x וערך y
&lt;/p&gt;
&lt;p class="code_area"&gt;
function zxcPos(zxcobj){ &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var position = new Object; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; zxclft=zxcobj.offsetLeft; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; zxctop=zxcobj.offsetTop;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; while(zxcobj.offsetParent!=null){ &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; zxcpar=zxcobj.offsetParent; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; zxclft+=zxcpar.offsetLeft; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; zxctop+=zxcpar.offsetTop; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; zxcobj=zxcpar; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; position.x=zxctop; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; position.y=zxclft; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return position; &lt;br /&gt;
} 
&lt;/p&gt;
&lt;p&gt;
הפונקציה שניה בנויה משני פונקציות בעצם, אחת מחזירה את המיקום x ואחת את המיקום y
&lt;/p&gt;
&lt;p class="code_area"&gt;
function findPosX(obj) &lt;br /&gt;
{ &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var curleft = 0; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if(obj.offsetParent) &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while(1) &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; curleft += obj.offsetLeft; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(!obj.offsetParent) &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; obj = obj.offsetParent; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; else if(obj.x) &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; curleft += obj.x; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return curleft; &lt;br /&gt;
} &lt;br /&gt;
function findPosY(obj) &lt;br /&gt;
{ &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var curtop = 0; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if(obj.offsetParent) &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while(1) &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; curtop += obj.offsetTop; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(!obj.offsetParent) &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; obj = obj.offsetParent; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; else if(obj.y) &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; curtop += obj.y; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return curtop; &lt;br /&gt;
} 
&lt;/p&gt;
</description>
      <link>http://blog.talgiladi.net/post/d79ed7a6d799d790d7aa-d79ed799d7a7d795d79d-d790d79cd79ed7a0d798-d791d793d7a4d793d7a4d79f.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/d79ed7a6d799d790d7aa-d79ed799d7a7d795d79d-d790d79cd79ed7a0d798-d791d793d7a4d793d7a4d79f.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=1dd6961b-4094-4672-8d78-b1b111f98c2f</guid>
      <pubDate>Wed, 02 Apr 2008 09:46:00 +0400</pubDate>
      <category>JavaScript</category>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=1dd6961b-4094-4672-8d78-b1b111f98c2f</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=1dd6961b-4094-4672-8d78-b1b111f98c2f</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/d79ed7a6d799d790d7aa-d79ed799d7a7d795d79d-d790d79cd79ed7a0d798-d791d793d7a4d793d7a4d79f.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=1dd6961b-4094-4672-8d78-b1b111f98c2f</wfw:commentRss>
    </item>
    <item>
      <title>File Permissions</title>
      <description>&lt;p&gt;
הפעם נראה כיצד בקלות ניתן לשנות הרשאות של קובץ דרך הקוד. השימוש הוא די קל וברור. אנו נשתמש במחלקה FileSecurity. 
&lt;/p&gt;
&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:785d655b-53f7-411c-b40d-574e943dcc09" class="wlWriterEditableSmartContent" style="float: none; margin: 0px; display: inline; padding: 0px"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/File+Security"&gt;File Security&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/access+rights"&gt;access rights&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/permissions"&gt;permissions&lt;/a&gt;
&lt;/div&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_classes"&gt;&lt;/span&gt;fs = &lt;span class="code_classes"&gt;File&lt;/span&gt;.GetAccessControl(this.filename); 
&lt;/p&gt;
&lt;p&gt;
אנו בעצם מושכים את המידע עבור הקובץ שאנו רוצים. כעת אנו יכולים או לבדוק את ההרשאות דרך פונקציות שונות במחלקה הזאת, או שניתן לשנות אותן. כדי לשנות נוסיף חוק חדש שאוסר על כולם לקרוא מהקובץ
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_classes"&gt;FileSystemAccessRule &lt;/span&gt;ar = new &lt;span class="code_classes"&gt;FileSystemAccessRule&lt;/span&gt;(&amp;quot;Everyone&amp;quot;, &lt;span class="code_classes"&gt;FileSystemRights&lt;/span&gt;.FullControl, &lt;span class="code_classes"&gt;AccessControlType&lt;/span&gt;.Deny); 
&lt;/p&gt;
&lt;p&gt;
המחלקה זאת מקבלת את שם הקבוצה שעליה יחול הכלל - EVERYONE, את סוג הגישה לקובץ - FULLCONTROL, והאם להרשות/לאסור - DENY
&lt;/p&gt;
&lt;p&gt;
נוסיף את הכלל החדש לרשימת הכללים של הקובץ
&lt;/p&gt;
&lt;p class="code_area"&gt;
fs.AddAccessRule(ar);
&lt;/p&gt;
&lt;p&gt;
כעת רק נשאר לשמור את הכלל החדש
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_classes"&gt;File&lt;/span&gt;.SetAccessControl(this.filename, fs);
&lt;/p&gt;
&lt;p&gt;
והתוצאה
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.talgiladi.net/image.axd?picture=AccessDenied1.png"&gt;&lt;img style="display: inline; border: 0px" src="http://blog.talgiladi.net/image.axd?picture=AccessDenied1_thumb.png" border="0" alt="AccessDenied1" title="AccessDenied1" width="375" height="234" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
כעת כדי להסיר את הכלל שעשינו נבצע את אותו התהליך, רק הפוך
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_classes"&gt;FileSecurity &lt;/span&gt;fs = &lt;span class="code_classes"&gt;File&lt;/span&gt;.GetAccessControl(this.filename); &lt;br /&gt;
&lt;span class="code_classes"&gt;FileSystemAccessRule &lt;/span&gt;ar = new &lt;span class="code_classes"&gt;FileSystemAccessRule&lt;/span&gt;(&amp;quot;Everyone&amp;quot;, &lt;span class="code_classes"&gt;FileSystemRights&lt;/span&gt;.FullControl, &lt;span class="code_classes"&gt;AccessControlType&lt;/span&gt;.Deny); &lt;br /&gt;
fs.RemoveAccessRule(ar ); &lt;br /&gt;
&lt;span class="code_classes"&gt;File&lt;/span&gt;.SetAccessControl(this.filename, fs); 
&lt;/p&gt;
&lt;p&gt;
שימו לב שבנינו שוב את הכלל הזה שאוסר גישה לקובץ, רק הפעם השתמשנו בפונקציה RemoveAccessRule כדי להוריד אותו מהקובץ 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.talgiladi.net/examples/FilePermissions.zip"&gt;להורדת פרוייקט דוגמה&lt;/a&gt;
&lt;/p&gt;
</description>
      <link>http://blog.talgiladi.net/post/File-Permissions.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/File-Permissions.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=c661b335-236d-4825-b746-229e0293308d</guid>
      <pubDate>Fri, 07 Mar 2008 09:41:00 +0400</pubDate>
      <category>C#</category>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=c661b335-236d-4825-b746-229e0293308d</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=c661b335-236d-4825-b746-229e0293308d</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/File-Permissions.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=c661b335-236d-4825-b746-229e0293308d</wfw:commentRss>
    </item>
    <item>
      <title>Server Execute</title>
      <description>אם אני רוצה לשלב בתוך הדף שלי פלט של דפים אחרים במערכת(לא header&amp;nbsp; או footer שאותם ניתן לשלב ב masterpage...), משהו שיהיה תלוי באיזה משתנה למשל, אז בעבר הלא רחוק היה נהוג להשתמש ב include, למשל, אם נכנסתי לדף בתור משתמש רגיל אזי הייתי רוצה לכלול את הקובץ: &lt;br /&gt;
&amp;lt;-- #include File = &amp;quot;c:\Inetpub\wwwroot\MyApplication\userWelcome.asp&amp;quot; --&amp;gt; &lt;br /&gt;
ואם בתור מנהל אז קובץ אחר... &lt;br /&gt;
&amp;lt;-- #include File = &amp;quot;c:\Inetpub\wwwroot\MyApplication\ManagerWelcome.asp&amp;quot; --&amp;gt; &lt;br /&gt;
&lt;br /&gt;
הבעיה עם הקוד הזה היא שהשרת היה מריץ את הקובץ שאני רוצה להכליל, עוד לפני שהוא בודק את התנאי שלי, מה שאומר שהוא בעצם הריץ גם את הקובץ למנהל וגם את הקובץ למשתמש רגיל בעת הכניסה לדף, ורק אז היה בודק את התנאי והיה מציג את התוכן שרציתי. &lt;br /&gt;
ואם היו לי 8 כאלה בדף...? &lt;br /&gt;
&lt;br /&gt;
בשביל זה יש את Server.Execute... פשוט מאוד, פשוט להעביר לו את הכתובת של הדף (המקומי בלבד!) שאנו רוצים להריץ, והפלט שלו יתווסף לדף שאני מריץ עכשיו. נניח שאני רוצה לכלול בגוף הדף הודעה בהתאם לשפת המשתמש (למרות שיש שיטות טובות יותר כמובן...), אזי הקוד שלנו יהיה : &lt;br /&gt;
&lt;br /&gt;
&lt;div class="code_area"&gt;
&amp;lt;html&amp;gt; &lt;br /&gt;
&amp;lt;body&amp;gt; &lt;br /&gt;
&amp;lt;H1&amp;gt;Company Name&amp;lt;/H1&amp;gt; &lt;br /&gt;
&amp;nbsp;&lt;font style="background-color: #ffff00"&gt;&amp;lt;%&lt;/font&gt; &lt;font color="#0000ff"&gt;string&lt;/font&gt; lang = Request.ServerVariables[&lt;font color="#a52a2a"&gt;&amp;quot;HTTP_ACCEPT_LANGUAGE&amp;quot;&lt;/font&gt;]; &lt;br /&gt;
lang = lang.SubString(0,2); &lt;br /&gt;
Server.Execute(lang+&lt;font color="#a52a2a"&gt;&amp;quot;Welcome.asp&amp;quot;&lt;/font&gt;) ; &lt;font style="background-color: #ffff00"&gt;%&amp;gt;&lt;/font&gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/body&amp;gt; &amp;lt;/html&amp;gt; &lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;a href="http://www.talgiladi.net/examples/ServerTransfer.zip"&gt;להורדת הפרוייקט &lt;br /&gt;
&lt;/a&gt;&lt;br /&gt;
&lt;a id="fapq" href="http://msdn2.microsoft.com/en-us/library/ms525849.aspx" title="msdn at microsoft"&gt;msdn at microsoft&lt;/a&gt; 
&lt;/p&gt;
&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:2ea662ed-0a8d-4c81-af1f-1700215c0799" class="wlWriterEditableSmartContent" style="float: none; margin: 0px; display: inline; padding: 0px"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/ServerExecute"&gt;ServerExecute&lt;/a&gt;
&lt;/div&gt;
</description>
      <link>http://blog.talgiladi.net/post/Server-Execute.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/Server-Execute.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=9d8632d3-f490-44f2-8a30-e241f3102061</guid>
      <pubDate>Mon, 03 Mar 2008 09:26:00 +0400</pubDate>
      <category>C#</category>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=9d8632d3-f490-44f2-8a30-e241f3102061</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=9d8632d3-f490-44f2-8a30-e241f3102061</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/Server-Execute.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=9d8632d3-f490-44f2-8a30-e241f3102061</wfw:commentRss>
    </item>
    <item>
      <title>Reflection for Unit Testing</title>
      <description>&lt;p&gt;
רוב מה שאני כותב בקשר לרפלקשן אני משתמש לצורך ה unit testing שלי, בדרך כלל אני מנסה להימנע משימוש בזה בייצור. &lt;br /&gt;
עם כל ההנאה שיש בקוד דינאמי, לא תמיד אני יכול להרשות את זה לעצמי, בעיקר בגלל נושא הביצועים. 
&lt;/p&gt;
&lt;p&gt;
אז לפני כמה ימים, כשאני כותב כמה בדיקות לקוד, עלתה בדעתי מחשבה. &lt;br /&gt;
הרבה מהקוד שלי מבצע עידכון וטעינה של מידע מהדטה בייס לאובייקטים עסקיים. &lt;br /&gt;
הרבה משתמשים ב ORM לצורך ביצוע המשימות האלה, אך שוב, באפליקציה הראשית של החברה שבה אני עובד אין אפשרות להשתמש בתוכנות אלו, גם בגלל ביצועים, וגם בגלל מורכבות השאילתות והקשרים בין הטבלאות. &lt;br /&gt;
אז יוצא שהרבה בדיקות שאני כותב הם לפונקציות שלוקחות אובייקט עסקי ומעדכנות את הטבלאות המתאימות, ומצד שני פונקציות שמושכות מידע ויוצרות את האובייקטים העסקיים. &lt;br /&gt;
המטרה שלי בבדיקה היא לבדוק שאכן האובייקט שנטען מהדטה בייס מכיל את אותם הנתונים שהכיל האובייקט ששלחתי לשמירה. כך יצא שמאות פעמים אני צריך לכתוב משהו בסגנון 
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&lt;span class="code_classes"&gt;FieldInfo&lt;/span&gt; a;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;FieldInfo&lt;/span&gt; b;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;Assert&lt;/span&gt;.AreEqual(a.FieldType, b.FieldType, &lt;span class="code_text"&gt;&amp;quot;field type&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;Assert&lt;/span&gt;.AreEqual(a.IsAssembly, b.IsAssembly, &lt;span class="code_text"&gt;&amp;quot;is assembly&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
וכך עבור כל פרופרטי שיש לאובייקט. ואז אמרתי לעצמי, למה להיות חמור? בסך הכל אתה משווה ערכים, תכתוב כבר פונקציה שתעשה את זה בשבילך. וזה מה שיצא לי:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&lt;span class="code_classes"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;static&lt;/span&gt; &lt;span class="code_keywords"&gt;void&lt;/span&gt; CompareObjects(&lt;span class="code_keywords"&gt;object&lt;/span&gt; a, &lt;span class="code_keywords"&gt;object&lt;/span&gt; b)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;if&lt;/span&gt; (a == &lt;span class="code_keywords"&gt;null&lt;/span&gt;) &lt;span class="code_classes"&gt;Assert&lt;/span&gt;.Fail(&lt;span class="code_text"&gt;&amp;quot;a is null&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;if&lt;/span&gt; (b == &lt;span class="code_keywords"&gt;null&lt;/span&gt;) &lt;span class="code_classes"&gt;Assert&lt;/span&gt;.Fail(&lt;span class="code_text"&gt;&amp;quot;b is null&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;Type&lt;/span&gt; t1 = a.GetType();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;Type&lt;/span&gt; t2 = b.GetType();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;if&lt;/span&gt; (t1 != t2)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;Assert&lt;/span&gt;.Fail(&lt;span class="code_text"&gt;&amp;quot;Type a (&amp;quot;&lt;/span&gt; + t1.Name + &lt;span class="code_text"&gt;&amp;quot;) is not as type as type b(&amp;quot;&lt;/span&gt; t2.Name + &lt;span class="code_text"&gt;&amp;quot;)&amp;quot;&lt;/span&gt;); 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;PropertyInfo&lt;/span&gt;[] pi = t1.GetProperties();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;for&lt;/span&gt; (&lt;span class="code_keywords"&gt;int&lt;/span&gt; i = 0; i &amp;lt; pi.Length; i++)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;object&lt;/span&gt; val1 = pi[i].GetGetMethod().Invoke(a, &lt;span class="code_keywords"&gt;null&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;object&lt;/span&gt; val2 = pi[i].GetGetMethod().Invoke(b, &lt;span class="code_keywords"&gt;null&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;Assert&lt;/span&gt;.AreEqual(val1, val2, pi[i].Name);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
הסבר קטן למי צריך: קודם אני בודק שאכן המצביעים לאובייקטים לא ריקים. אחר כך אני בודק שהם בכלל מאותו סוג של אובייקט. רק עכשיו אני מושך את כל הפרופרטיס שלהם ומתחיל להשוות אחד אחד... נחמד, בכמה שורות חסכתי מאות שורות, או שבעצם לא נחמד, שעד עכשיו לא עלה על דעתי לעשות את זה... ישנה עוד תוספת קטנה לפונקציה. הרבה מהאובייקטים מכילים תאריך עדכון אחרון שניתן על ידי בסיס הנתונים באופן אוטומטי, וגם במקרה של הכנסה חדשה לבסיס הנתונים יש את הערך של השדה המזהה בדרך כלל, ערכים אלו יהיו שונים בין האובייקט לפני ההכנסה לדטה בייס לאובייקט שנטען לאחר ההכנסה ואז הפונקציה תמיד תזרוק הודעת כישלון.... אז הנה תיקון קטן לקוד: 
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
&lt;span class="code_keywords"&gt;public&lt;/span&gt; &lt;span class="code_keywords"&gt;static&lt;/span&gt; &lt;span class="code_keywords"&gt;void&lt;/span&gt; CompareObjects(&lt;span class="code_keywords"&gt;object&lt;/span&gt; a, &lt;span class="code_keywords"&gt;object&lt;/span&gt; b, &lt;span class="code_keywords"&gt;string&lt;/span&gt;[] exclude)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;if&lt;/span&gt; (a == &lt;span class="code_keywords"&gt;null&lt;/span&gt;) &lt;span class="code_classes"&gt;Assert&lt;/span&gt;.Fail(&lt;span class="code_text"&gt;&amp;quot;a is null&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;if&lt;/span&gt; (b == &lt;span class="code_keywords"&gt;null&lt;/span&gt;) &lt;span class="code_classes"&gt;Assert&lt;/span&gt;.Fail(&lt;span class="code_text"&gt;&amp;quot;b is null&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;Type&lt;/span&gt; t1 = a.GetType();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;Type&lt;/span&gt; t2 = b.GetType();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;if&lt;/span&gt; (t1 != t2)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;Assert&lt;/span&gt;.Fail(&lt;span class="code_text"&gt;&amp;quot;Type a (&amp;quot;&lt;/span&gt; + t1.Name + &lt;span class="code_text"&gt;&amp;quot;) is not as type b (&amp;quot;&lt;/span&gt; + t2.Name + &lt;span class="code_text"&gt;&amp;quot;)&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;PropertyInfo&lt;/span&gt;[] pi = t1.GetProperties();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;for&lt;/span&gt; (&lt;span class="code_keywords"&gt;int&lt;/span&gt; i = 0; i &amp;lt; pi.Length; i++)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;if&lt;/span&gt; (exclude != &lt;span class="code_keywords"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; &lt;span class="code_classes"&gt;Array&lt;/span&gt;.IndexOf&amp;lt;&lt;span class="code_keywords"&gt;string&lt;/span&gt;&amp;gt;(exclude, pi[i].Name) &amp;gt; -1)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;continue&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;object&lt;/span&gt; val1 = pi[i].GetGetMethod().Invoke(a, &lt;span class="code_keywords"&gt;null&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;object&lt;/span&gt; val2 = pi[i].GetGetMethod().Invoke(b, &lt;span class="code_keywords"&gt;null&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;Assert&lt;/span&gt;.AreEqual(val1, val2, pi[i].Name);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
כעת הפונקציה מקבלת רשימה של פרופרטיס שאותם לא צריך לבדוק לדוגמה: 
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&lt;span class="code_classes"&gt;Customer&lt;/span&gt; a;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_classes"&gt;Customer&lt;/span&gt; b;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CompareObjects(a, b, &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_keywords"&gt;string&lt;/span&gt;[] { &lt;span class="code_text"&gt;&amp;quot;Id&amp;quot;&lt;/span&gt;, &lt;span class="code_text"&gt;&amp;quot;LastUpdate&amp;quot;&lt;/span&gt; });
&lt;/p&gt;
&lt;/div&gt;
&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:18c5f760-6b90-46b2-8607-b10651566b6b" class="wlWriterEditableSmartContent" style="float: none; margin: 0px; display: inline; padding: 0px"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/Reflection"&gt;Reflection&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/UnitTesting"&gt;UnitTesting&lt;/a&gt;
&lt;/div&gt;
</description>
      <link>http://blog.talgiladi.net/post/Reflection-for-Unit-Testing.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/Reflection-for-Unit-Testing.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=9a4c35a9-6147-4345-a0f3-01fa13a34c22</guid>
      <pubDate>Sun, 02 Mar 2008 17:34:00 +0400</pubDate>
      <category>Reflection</category>
      <category>UnitTests</category>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=9a4c35a9-6147-4345-a0f3-01fa13a34c22</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=9a4c35a9-6147-4345-a0f3-01fa13a34c22</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/Reflection-for-Unit-Testing.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=9a4c35a9-6147-4345-a0f3-01fa13a34c22</wfw:commentRss>
    </item>
    <item>
      <title>מיון לפי עמודה משתנה ב Stored Procedures</title>
      <description>&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:7c120ea3-c6bf-4f63-b6fb-2172518844c9" class="wlWriterEditableSmartContent" style="float: none; margin: 0px; display: inline; padding: 0px"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/sql"&gt;sql&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/sort"&gt;sort&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/stored+procedure"&gt;stored procedure&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;
הזכרנו מספר פעמים את היתרון של stored procedures מנקודת אבטחת מידע. אולם אחת הבעיות שיש ב stored procedures היא שיש נתונים שלא ניתן להעביר כפרמטר, לדוגמה, העמודה לפיה ממיינים. נניח שיש לי דף שניתן למיון לפי מספר עמודות, לא ניתן להעביר ל stored procedure את שם העמודה למיון בצורה הבאה:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;span class="code_keywords"&gt;create procedure&lt;/span&gt; temp1 &lt;br /&gt;
@sortName varchar(20) &lt;br /&gt;
&lt;span class="code_keywords"&gt;as &lt;/span&gt;&lt;br /&gt;
&lt;span class="code_keywords"&gt;begin&lt;/span&gt; &lt;br /&gt;
&lt;span class="code_keywords"&gt;select &lt;/span&gt;* &lt;span class="code_keywords"&gt;from &lt;/span&gt;article &lt;span class="code_keywords"&gt;order by &lt;/span&gt;@sortName &lt;br /&gt;
&lt;span class="code_keywords"&gt;end&lt;/span&gt; &lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;
אז מה כן עושים אם אנו עדיין רוצים להמשיך להשתמש ב stored procedures וגם לאפשר מיונים לפי שדות שונים? &lt;br /&gt;
אז צריך קצת להתחכם, וגם לסרבל, אבל עדיין נראה לי שזה שווה את זה... &lt;br /&gt;
נניח שיש לי 2 עמודות שניתן למיין לפיהן, וגם ניתן למיין בסדר עולה או יורד. אז נכון שתמיד ניתן להשתמש ב sp_executesql , אבל אז הלכה כל התועלת של שימוש ב stored procedure... מישהו פעם הציע לי לבנות 4&amp;nbsp; stored procedures... כמובן שזה לא סביר... אבל נעשה משהו די דומה:)
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;span class="code_keywords"&gt;create procedure&lt;/span&gt; temp1 &lt;br /&gt;
@sortName varchar(20), &lt;br /&gt;
@sortDirection varchar(4)=&lt;span class="code_text"&gt;&amp;#39;asc&amp;#39;&lt;/span&gt; &lt;br /&gt;
&lt;span class="code_keywords"&gt;as &lt;br /&gt;
begin&lt;/span&gt; &lt;br /&gt;
&lt;span class="code_keywords"&gt;select &lt;/span&gt;* &lt;span class="code_keywords"&gt;from &lt;/span&gt;article &lt;span class="code_keywords"&gt;order by &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class="code_keywords"&gt;case WHEN &lt;/span&gt;@sortName =&lt;span class="code_text"&gt; &amp;#39;article_id&amp;#39; &lt;/span&gt;and @sortDirection=&lt;span class="code_text"&gt;&amp;#39;asc&amp;#39;&lt;/span&gt; &lt;span class="code_keywords"&gt;THEN &lt;/span&gt;article_id &lt;span class="code_keywords"&gt;end asc,&lt;/span&gt; &lt;br /&gt;
&lt;span class="code_keywords"&gt;case WHEN &lt;/span&gt;@sortName = &lt;span class="code_text"&gt;&amp;#39;article_id&amp;#39; &lt;/span&gt;and @sortDirection=&lt;span class="code_text"&gt;&amp;#39;desc&amp;#39;&lt;/span&gt; &lt;span class="code_keywords"&gt;THEN &lt;/span&gt;article_id &lt;span class="code_keywords"&gt;end desc&lt;/span&gt;, &lt;br /&gt;
&lt;span class="code_keywords"&gt;case WHEN &lt;/span&gt;@sortName =&lt;span class="code_text"&gt; &amp;#39;publish_date&amp;#39;&lt;/span&gt; and @sortDirection=&lt;span class="code_text"&gt;&amp;#39;asc&amp;#39; &lt;/span&gt;&lt;span class="code_keywords"&gt;THEN &lt;/span&gt;publish_date &lt;span class="code_keywords"&gt;end asc&lt;/span&gt;, &lt;br /&gt;
&lt;span class="code_keywords"&gt;case WHEN &lt;/span&gt;@sortName = &lt;span class="code_text"&gt;&amp;#39;publish_date&amp;#39; &lt;/span&gt;and @sortDirection=&lt;span class="code_text"&gt;&amp;#39;desc&amp;#39;&lt;/span&gt; &lt;span class="code_keywords"&gt;THEN &lt;/span&gt;publish_date &lt;span class="code_keywords"&gt;end desc&lt;/span&gt; &lt;br /&gt;
&lt;span class="code_keywords"&gt;end&lt;/span&gt; &lt;br /&gt;
&lt;/div&gt;
</description>
      <link>http://blog.talgiladi.net/post/d79ed799d795d79f-d79cd7a4d799-d7a2d79ed795d793d794-d79ed7a9d7aad7a0d794-d791-Stored-Procedures.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/d79ed799d795d79f-d79cd7a4d799-d7a2d79ed795d793d794-d79ed7a9d7aad7a0d794-d791-Stored-Procedures.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=77b6edbe-8ded-4efb-8291-d41cc1375bcd</guid>
      <pubDate>Wed, 23 Jan 2008 17:29:00 +0400</pubDate>
      <category>sql</category>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=77b6edbe-8ded-4efb-8291-d41cc1375bcd</pingback:target>
      <slash:comments>2</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=77b6edbe-8ded-4efb-8291-d41cc1375bcd</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/d79ed799d795d79f-d79cd7a4d799-d7a2d79ed795d793d794-d79ed7a9d7aad7a0d794-d791-Stored-Procedures.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=77b6edbe-8ded-4efb-8291-d41cc1375bcd</wfw:commentRss>
    </item>
    <item>
      <title>חתימה דיגיטלית</title>
      <description>&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:0d9843d3-0a5f-4364-b01e-b3e307996698" class="wlWriterEditableSmartContent" style="float: none; margin: 0px; display: inline; padding: 0px"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/digital+signature"&gt;digital signature&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/encryption"&gt;encryption&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;
חתימה דיגיטילית זה בעצם שילוב של מפתח ציבורי/פרטי עם האש. אני רוצה להשיג 2 מטרות בבת אחת- גם לוודא שהמכתב שהנמען קורא הוא המכתב שאני כתבתי והמידע בו לא השתנה, וגם שזהו אכן מכתב שאני כתבתי ולא מישהו אחר. כדי להשיג את המטרה הראשונה, אנחנו משתמשים בהאש &amp;ndash; כך אנו מוודאים שהמידע במכתב לא השתנה, והמטרה השניה מושגת על ידי שימוש בהצפנה על ידי המפתח הפרטי שלי- אבל הצפנה רק של ערך ההאש, לא של המכתב כולו.
&lt;/p&gt;
&lt;p&gt;
ועכשיו לקצת קוד:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p class="code_line"&gt;
&lt;span class="code_keywords"&gt;using&lt;/span&gt; System.Security.Cryptography;
&lt;/p&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&lt;span class="code_classes"&gt;DSACryptoServiceProvider&lt;/span&gt; dsa = &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;DSACryptoServiceProvider&lt;/span&gt;();
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
* ניתן באופן זהה במחלקה RSACryptoServiceProvider ושם ניתן גם לציין את האלגוריתם לביצוע ההאש.
&lt;/p&gt;
&lt;p&gt;
המחלקה הזאת תבצע בעצם את פעולת ההאש והחתימה ביחד. אם כבר יש לי מפתח פרטי אזי נאתחל את המחלקה איתו:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p class="code_line"&gt;
dsa.FromXmlString(privatekey);
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
אם לא אז המחלקה תיצור באופן אוטומטי זוג מפתחות. זיכרו שאנחנו אמורים לספק לצד שמקבל את המידע את המפתח הציבורי שלנו כדי שיוכל לוודא איתו את החתימה, אז אם אין לי עדיין מפתח ציבורי נקבל עכשיו אחד חדש:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&lt;span class="code_keywords"&gt;string&lt;/span&gt; publickey = dsa.ToXmlString(&lt;span class="code_keywords"&gt;false&lt;/span&gt;);
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
זהו בעצם, עכשיו פשוט נייצר את החתימה:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&lt;span class="code_keywords"&gt;byte&lt;/span&gt;[] signature = dsa.SignData(mydata);
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
וניתן להפוך לסטרינג כמובן:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p class="code_line"&gt;
&lt;span class="code_keywords"&gt;string&lt;/span&gt; result = &lt;span class="code_classes"&gt;Convert&lt;/span&gt;.ToBase64String(signature);
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
עכשיו אנחנו מפרסמים את המידע שכתבנו, את המפתח הציבורי ואת החתימה. הצד השני יבצע את הפעולות הבאות כדי לוודא שהחתימה מתאימה:
&lt;/p&gt;
&lt;p&gt;
1. ניצור אובייקט מהמחלקה המתאימה:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p class="code_line"&gt;
&lt;span class="code_classes"&gt;DSACryptoServiceProvider&lt;/span&gt; dsa = &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;DSACryptoServiceProvider&lt;/span&gt;();
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
2. ניתן לו את המפתח הציבורי שקיבלנו:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p class="code_line"&gt;
dsa.FromXmlString(publickey);
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
3. וכעת ניתן לו את המידע עצמו ואת החתימה ונקבל ערך בוליאני האם החתימה מתאימה או לא:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p class="code_line"&gt;
&amp;nbsp;&lt;span class="code_keywords"&gt;bool&lt;/span&gt; match = dsa.VerifySignature(data, signature);
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
וזהו...
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.talgiladi.net/examples/signature.zip"&gt;להורדת קבצי המקור והפרוייקט&lt;/a&gt;
&lt;/p&gt;
</description>
      <link>http://blog.talgiladi.net/post/d797d7aad799d79ed794-d793d799d792d799d798d79cd799d7aa.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/d797d7aad799d79ed794-d793d799d792d799d798d79cd799d7aa.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=0ea75569-a924-487b-81fd-8d36e02e0a46</guid>
      <pubDate>Fri, 18 Jan 2008 18:08:00 +0400</pubDate>
      <category>Security</category>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=0ea75569-a924-487b-81fd-8d36e02e0a46</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=0ea75569-a924-487b-81fd-8d36e02e0a46</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/d797d7aad799d79ed794-d793d799d792d799d798d79cd799d7aa.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=0ea75569-a924-487b-81fd-8d36e02e0a46</wfw:commentRss>
    </item>
    <item>
      <title>FCKEditor - עורך HTML</title>
      <description>&lt;p&gt;
ראיתי מספר פעמים ששאלו על &lt;a href="http://www.fckeditor.net/download"&gt;FCKEditor&lt;/a&gt; בקשר להתקנה ותיפעול אז צירפתי הוראות פשוטות אני מקווה שלא תתקלו בבעיות... 
&lt;/p&gt;
&lt;p&gt;
קודם נלך לאתר שלהם ונוריד את הגירסה הרגילה 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.talgiladi.net/image.axd?picture=fckdownload.png"&gt;&lt;img style="display: inline; border: 0px" src="http://blog.talgiladi.net/image.axd?picture=fckdownload_thumb.png" border="0" alt="fckdownload" title="fckdownload" width="570" height="141" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
אחר כך נוריד את התוסף לדוט נט 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.talgiladi.net/image.axd?picture=fcknet.png"&gt;&lt;img style="display: inline; border: 0px" src="http://blog.talgiladi.net/image.axd?picture=fcknet_thumb.png" border="0" alt="fcknet" title="fcknet" width="557" height="136" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
נפתח את קובץ הזיפ הראשון לתיקיה בשם fckeditor בתיקית ה root של האתר שלנו &lt;br /&gt;
לקובץ השני שהוא התוסף לדוט נט אנחנו צריכים להוסיף הפניה פשוט ולהראות לויז&amp;#39;ואל סטודיו את הקובץ המתאים (נמצא בתיקיית bin\Release\2.0 בזיפ השני שפתחנו) &lt;br /&gt;
כעת נלך לדף שבו אנו רוצים להוסיף את האדיטור, ונוסיף למעלה הפניה ל dll של האדיטור כך: 
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="code_yellow"&gt;&amp;lt;%&lt;/span&gt;&lt;span class="code_keywords"&gt;@&lt;/span&gt; &lt;span class="script_text"&gt;Page &lt;/span&gt;&lt;span class="script_type"&gt;Language&lt;/span&gt;&lt;span class="code_keywords"&gt;=&amp;quot;C#&amp;quot;&lt;/span&gt; &lt;span class="script_type"&gt;AutoEventWireup&lt;/span&gt;&lt;span class="code_keywords"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt; &lt;span class="script_type"&gt;CodeFile&lt;/span&gt;&lt;span class="code_keywords"&gt;=&amp;quot;Default.aspx.cs&amp;quot; &lt;/span&gt;&lt;span class="script_type"&gt;Inherits&lt;/span&gt;&lt;span class="code_keywords"&gt;=&amp;quot;_Default&amp;quot;&lt;/span&gt;&lt;span class="code_yellow"&gt; %&amp;gt;&lt;/span&gt; &lt;br /&gt;
&lt;span class="code_yellow"&gt;&amp;lt;%&lt;/span&gt;&lt;span class="code_keywords"&gt;@&lt;/span&gt; &lt;span class="script_text"&gt;Register &lt;/span&gt;&lt;span class="script_type"&gt;Assembly&lt;/span&gt;&lt;span class="code_keywords"&gt;=&amp;quot;FredCK.FCKeditorV2&amp;quot;&lt;/span&gt; &lt;span class="script_type"&gt;Namespace&lt;/span&gt;&lt;span class="code_keywords"&gt;=&amp;quot;FredCK.FCKeditorV2&amp;quot;&lt;/span&gt; &lt;span class="script_type"&gt;TagPrefix&lt;/span&gt;&lt;span class="code_keywords"&gt;=&amp;quot;FCKeditorV2&amp;quot; &lt;/span&gt;&lt;span class="code_yellow"&gt;%&amp;gt;&lt;/span&gt; 
&lt;/p&gt;
&lt;p&gt;
ונוסיף את האדיטור במקום שאנו רוצים בדף כמו כל קונטרול אחר 
&lt;/p&gt;
&lt;p class="code_area"&gt;
&amp;lt;&lt;span class="script_text"&gt;FCKeditorV2&lt;/span&gt;:&lt;span class="script_text"&gt;FCKeditor &lt;/span&gt;&lt;span class="script_type"&gt;ID&lt;/span&gt;&lt;span class="code_keywords"&gt;=&amp;quot;FCKeditor1&amp;quot;&lt;/span&gt;&lt;span class="script_type"&gt; BasePath&lt;/span&gt;=&lt;span class="code_keywords"&gt;&amp;quot;fckeditor\&amp;quot;&lt;/span&gt; &lt;span class="script_type"&gt;runat&lt;/span&gt;&lt;span class="code_keywords"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span class="script_type"&gt;Height&lt;/span&gt;&lt;span class="code_keywords"&gt;=&amp;quot;345px&amp;quot;&amp;gt;&lt;/span&gt; &amp;lt;/&lt;span class="script_text"&gt;FCKeditorV2&lt;/span&gt;:&lt;span class="script_text"&gt;FCKeditor&lt;/span&gt;&amp;gt; 
&lt;/p&gt;
&lt;p&gt;
הפרמטר הכי חשוב כאן זה בעצם הנתיב לספריה שלו - שזה אצלנו fckeditor ששם הוא מוצא את כל הקבצים שלו &lt;br /&gt;
בקוד שלנו אנו ניגשים אליו לפי ה ID כמובן וכך אפשר להכניס לו HTML מראש ולמשוך אחר כך את ה HTML שהמשתמש ערך בו &lt;br /&gt;
ישנה עוד נקודה אחת רק... קטנה אבל בעייתית, למרות שבגירסה האחרונה היא לא התעוררה, אז אתם יכולים להתפלל שהיא גם לא תופיע... אבל בכל מקרה טוב לדעת על הנושא. &lt;br /&gt;
כידוע יש את אלמנט ההתקפה שנקרא XSS ומתבצע דרך סקריפטים שנשלחים לשרת ואז מוצגים שוב למשתמשים. שרת הדוט נט, במטרה להפחית את הסבירות, זורק exception אם הוא מקבל לשרת כל מידע שמתחיל עם &amp;gt; ואחריו איזושהי אות ,מה שאומר שזה בעצם כל תגית ב html. כך שאם תנסו בטקסט בוקס רגיל או באיזה פרמטר בשורת הכתובת להכניס את המילה &amp;lt;script&amp;gt; תקבלו שגיאה מאוד נחמדה מהשרת: 
&lt;/p&gt;
&lt;p class="code_area"&gt;
&amp;quot;A potentially dengerous Request...&amp;quot; 
&lt;/p&gt;
&lt;p&gt;
קוראים לתכונה הזאת Request Validation וניתן לבטל את זה, רק שתדעו שפעם מישהו אמר: 
&lt;/p&gt;
&lt;p&gt;
&amp;quot; אתה חייב לדעת טוב מאוד מה אתה עושה כדי לבטל את ה Request Validation, ואם אתה אכן יודע טוב מאוד מה אתה עושה, אז אתה לא תבטל את ה Request Validation&amp;quot; &lt;br /&gt;
אני ביטלתי כמה פעמים :) 
&lt;/p&gt;
&lt;p&gt;
בכל מקרה כדי לעשות זה פשוט נוסף בשורה הראשונה של הגדרת הדף את הפרמטרים 
&lt;/p&gt;
&lt;p class="code_area"&gt;
&lt;span class="script_type"&gt;ValidateRequest&lt;/span&gt;&lt;span class="code_keywords"&gt;=&amp;quot;false&amp;quot;&lt;/span&gt; &lt;span class="script_type"&gt;EnableEventValidation&lt;/span&gt;&lt;span class="code_keywords"&gt;=&amp;quot;false&amp;quot;&lt;/span&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.talgiladi.net/examples/fckeditorExample.zip"&gt;להורדת פרוייקט דוגמה&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:0dbab7be-03e1-4778-b601-9aaae34b03b5" class="wlWriterEditableSmartContent" style="float: none; margin: 0px; display: inline; padding: 0px"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/fckeditor"&gt;fckeditor&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/html+editor"&gt;html editor&lt;/a&gt; 
&lt;/div&gt;
</description>
      <link>http://blog.talgiladi.net/post/FCKEditor-d7a2d795d7a8d79a-HTML.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/FCKEditor-d7a2d795d7a8d79a-HTML.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=0e536c27-bb64-4b32-b689-560b5b8b1da4</guid>
      <pubDate>Tue, 25 Dec 2007 09:44:00 +0400</pubDate>
      <category>C#</category>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=0e536c27-bb64-4b32-b689-560b5b8b1da4</pingback:target>
      <slash:comments>2</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=0e536c27-bb64-4b32-b689-560b5b8b1da4</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/FCKEditor-d7a2d795d7a8d79a-HTML.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=0e536c27-bb64-4b32-b689-560b5b8b1da4</wfw:commentRss>
    </item>
    <item>
      <title>Custom web controls</title>
      <description>&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:eff0afd4-2857-4ebe-bb74-b615508d5b8b" class="wlWriterEditableSmartContent" style="float: none; margin: 0px; display: inline; padding: 0px"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/custom+web+control"&gt;custom web control&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;
יצא לי בזמן האחרון לבנות כמה קונטרולים נחמדים. אני נוהג לעיתים תכופות להשתמש בקונטרולים שאני בונה, אך לאחרונים הייתי צריך כמה תכונות נוספות, שלא כל כך ברור לכולם כיצד ליצור אותם, אז חשבתי להראות קצת את המהלכים הנדרשים. &lt;br /&gt;
נתחיל הפעם ביצירת הקונטרול בעזרת השם אני אמשיך אחר כך עם הדברים שרציתי להראות. &lt;br /&gt;
ישנם 2 סוגים של ווב קונטרולים שאנו יכולים ליצור. ניתן ליצור את הקונטרול באתר שלנו כמו כל דף אחר, על ידי הוספת פריט חדש 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;&lt;a href="http://blog.talgiladi.net/image.axd?picture=wc_addControl.png"&gt;&lt;img style="display: inline; border: 0px" src="http://blog.talgiladi.net/image.axd?picture=wc_addControl_thumb.png" border="0" alt="wc_addControl" title="wc_addControl" width="612" height="149" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
או שניתן ליצור פרוייקט חדש, והתוצאה שלו תהיה dll שניתן להוסיף לאתר שלנו 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;&lt;a href="http://blog.talgiladi.net/image.axd?picture=wc_createProject.png"&gt;&lt;img style="display: inline; border: 0px" src="http://blog.talgiladi.net/image.axd?picture=wc_createProject_thumb.png" border="0" alt="wc_createProject" title="wc_createProject" width="577" height="213" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
יש הבדלים בין השיטות. בדרך הראשונה, הקונטרול יהיה זמין רק לאתר שבו יצרתי אותו, אני לא אוכל להשתמש בו באתרים אחרים. מצד שני, כל תהליך הבניה הוא קל יותר כי לא צריך לקמפל מחדש כל פעם , הוא מתקפל אוטומטית כמו כל שאר הדפים באתר. הקונטרול בצורה הזאת יורש מהמחלקה &lt;span style="margin: 0px"&gt;System.Web.UI.&lt;span style="color: #2b91af"&gt;UserControl&lt;/span&gt;&lt;/span&gt; &lt;br /&gt;
בשיטה השניה זה הפוך כמובן... אני יכול להוסיף הפניה ל dll שנוצר מכל פרוייקט ווב שארצה, אך מצד שני פחות נוח בתהליך הפיתוח לקמפל מחדש כל פעם את הפרוייקט. ישנם עוד הבדלים קטנים בצורת כתיבת הקוד ובקריאת לאירועים של הקונטרול . הקונטרול בצורה הזאת יורש מ &lt;span style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;WebControl&lt;/span&gt;&lt;/span&gt; 
&lt;/p&gt;
&lt;p&gt;
אנו נבחר בשיטה הראשונה... ניצור פרוייקט מסוג WebCustomControl . &lt;br /&gt;
כעת נשנה את השם של המחלקה שנוצרה באופן אוטומטי כי השם הזה הוא חלק ממה שהמשתמש יראה כשהוא ירצה לזרוק את הקונטרול על דף הווב שלו, וניבחר משהו כמו LightCaptchaValidator &lt;br /&gt;
קיבלנו מחלקה שנראית כך: 
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
[&lt;span style="color: #2b91af"&gt;ToolboxData&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;&amp;lt;{0}:LightCaptchaControl runat=server&amp;gt;&amp;lt;/{0}:LightCaptchaControl&amp;gt;&amp;quot;&lt;/span&gt;)]
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;LightCaptchaControl&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;WebControl&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
רק לפני שנמשיך צריכים לעשות איזו שינוי קטן, תוסיפו עוד Interface כך שהגדרת המחלקה תיראה כך:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;LightCaptchaControl&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;WebControl&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;INamingContainer&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
שאינה רלוונטית לקונטרול שלנו. כפי שניתן לנחש, התגית ToolboxData אומרת כיצד יראה הקוד בדף ה aspx לאחר שנזרוק את הקונטרול על הדף, כש {0} זה הערך שניתן בדף ל TagPrefix
&lt;/p&gt;
&lt;p&gt;
עוד יש לנו במחלקה דוגמה לפרופרטי שניתן לערוך ב Form Designer. ה Form Designer בעצם מציג את כל הפרופרטיס שיש לנו במחלקה ולכן אם אנו רוצים &amp;quot;להעלים&amp;quot; מהמשתמש משהו, יש להוסיף תגית 
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
[&lt;span style="color: #2b91af"&gt;Browsable&lt;/span&gt;(&lt;span style="color: blue"&gt;false&lt;/span&gt;)]
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
מעל פרופרטי שאמור להיות מוחבא. התגית: 
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
[&lt;span style="color: #2b91af"&gt;Category&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;Appearance&amp;quot;&lt;/span&gt;)]
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
אומרת פשוט באיזה קטגוריה יוצג הפרופרטי הזה ו DefaultValue הוא כמובן ערך ברירת המחדל... שימו לב שבפרופרטיס של ווב קונטרול, שלא כמו בפרופרטיס של מחלקה רגילה, אנו שומרים ומושכים את המידע מה ViewState, ולא ממשתנה מחלקה, כי הרי הקונטרול הזה נוצר מחדש בכל פעם שהמשתמש מבקש את הדף או עושה פוסטבאק לשרת, והדרך היחידה לשמור על ערך המשתנים הוא ב ViewState. &lt;br /&gt;
המתודה שיש לנו במחלקה: 
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;protected&lt;/span&gt; &lt;span style="color: blue"&gt;override&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; RenderContents(&lt;span style="color: #2b91af"&gt;HtmlTextWriter&lt;/span&gt; output)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; output.Write(Text);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
המתודה הזאת נקראת על ידי הדף כשהוא מוכן לשלב את פלט ה HTML של הקונטרול שלנו בתוכו. היא המתודה שבה אנו כותבים את הפלט הסופי של הקונטרול שלנו וזהו בעצם ה HTML שיוצג על הדף. כפי שניתן לראות המחלקה מקבלת פרמטר מסוג HtmlTextWriter(כתבתי עליו כמה מילים במקום אחר). &lt;br /&gt;
אם נשים את הקונטרול עכשיו על דף ונריץ, נקבל בעצם טקסט ריק, כי זה מה שהמתודה הזאת מדפיסה לדף &lt;br /&gt;
טוב, נמשיך. מה יעשה הקונטרול שלנו? הוא יהיה כמו captcha זולה... אנו נציג טקסט בוקס, עם שאלה במתמטיקה לידו, והגולש אמור להכניס את התשובה. כשעושים פוסטבאק לשרת הקונטרול שלנו בודק את התשובה ויכול להודיע לדף שאכן היא נכונה ורוב הסיכויים שהגולש איננו סקריפט אוטומטי. כמובן שאי אפשר להציג את השאלה בצורת טקסט פשוט כי אז הסקריפט פשוט ימצא את הפיתרון, אבל זו כבר בעיה אחרת שאולי יהיה לנו זמן גם לפתור... &lt;br /&gt;
אז אנחנו צריכים לייבל, שיודיע לגולש שהוא אמור לענות על השאלה שלנו, טקסט בוקס שאליו יכניסו את התשובה, ועוד לייבל שיציג את התרגיל במתמטיקה. כמובן שאפשר להוסיף ולידטור, ואפשר אפילו להוסיף לינק כדי שאפשר יהיה לבחור תרגיל אחר אבל זה לא עכשיו... &lt;br /&gt;
כדי להוסיף קונטרולים אחרים לקונטרול שלי , אני צריך להוסיף מתודה אחרת שנקראת על ידי הדף והיא: 
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;protected&lt;/span&gt; &lt;span style="color: blue"&gt;override&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; CreateChildControls()
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
שימו לב שכאן אנו רק מוסיפים את הקונטרולים, אבל במתודה RenderContents אנו גם נבקש מכל אחד מהם לרנדר את עצמו לתוך ה HTML של כל הקונטרול שלנו... 
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;protected&lt;/span&gt; &lt;span style="color: blue"&gt;override&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; CreateChildControls()
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;////the label with the text asking &lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt;the user to answer the question&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;Label&lt;/span&gt; lblText = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Label&lt;/span&gt;();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lblText.Text = &lt;span style="color: blue"&gt;this&lt;/span&gt;.Text;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lblText.ID = &lt;span style="color: #a31515"&gt;&amp;quot;lblText&amp;quot;&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;this&lt;/span&gt;.Controls.Add(lblText);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;////the text box with the answer&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;TextBox&lt;/span&gt; txtAnswer = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;TextBox&lt;/span&gt;();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; txtAnswer.ID = &lt;span style="color: #a31515"&gt;&amp;quot;txtAnswer&amp;quot;&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;this&lt;/span&gt;.Controls.Add(txtAnswer);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;////The label with the methematics question&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;Label&lt;/span&gt; lblQuestion = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Label&lt;/span&gt;();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lblQuestion.ID = &lt;span style="color: #a31515"&gt;&amp;quot;lblQuestion&amp;quot;&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;this&lt;/span&gt;.Controls.Add(lblQuestion);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
ללייבל lblQuestion עדיין לא שמתי ערך טקסט כי עדיין לא חשבנו איך ניצור את התרגיל המתמטי, אבל נחזור לזה אחר כך. lblText קיבלה את ערך הטקסט של הפרופרטי Text מהקונטרול שלנו, כך שכשהמשתמש יעצב את הקונטורל וישנה לו את ערך הטקסט, זה מה שיוצג לגולש. 
&lt;/p&gt;
&lt;p&gt;
בואו נוסיף אתר לפרוייקט שלנו, כדי שנוכל לראות את הקונטרול שלנו בפעולה(או שאפשר להוסיף הפניה ל dll מאתר קיים כמובן)&lt;a href="http://blog.talgiladi.net/image.axd?picture=addWebSite.png"&gt;&lt;img style="display: inline; border: 0px" src="http://blog.talgiladi.net/image.axd?picture=addWebSite_thumb.png" border="0" alt="addWebSite" title="addWebSite" width="519" height="90" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
נלך לעיצוב הדף, ארגז כלים, לחצן ימני - choose items כדי להוסיף את הקונטרול שלנו לארגז הכלים 
&lt;/p&gt;
&lt;a href="http://blog.talgiladi.net/image.axd?picture=ChooseItems.png"&gt;&lt;img style="display: inline; border: 0px" src="http://blog.talgiladi.net/image.axd?picture=ChooseItems_thumb.png" border="0" alt="ChooseItems" title="ChooseItems" width="245" height="226" /&gt;&lt;/a&gt; 
&lt;p&gt;
בחלון שנפתח נלחץ על Browse ונחפש את תיקיית הפרוייקט שלנו, שם בתוך תיקיית bin\debug נמצא את ה dll שלנו. אם הוא לא שם אז לא עשיתם build לפרוייקט או שתחפשו בספריית release. לחיצה על OK והקונטרול מופיע בארגז הכלים. תמשכו אותו לדף. אם יש איזו בעיה אז אתם תראו, אם לא, אז אנו רואים דף חלק... ואיפה הקונטרולים שלנו? זה שהוספנו אותם זה לא מספיק עדיין, אנו צריכים לרנדר אותם... &lt;br /&gt;
אז בחזרה לקונטרול שלנו, כבר יש שם פונקציה מתאימה: 
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&lt;span style="color: blue"&gt;protected&lt;/span&gt; &lt;span style="color: blue"&gt;override&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; RenderContents(&lt;span style="color: #2b91af"&gt;HtmlTextWriter&lt;/span&gt; output)
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
אפשר לרנדר בריצה בלולאה: 
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;for&lt;/span&gt; (&lt;span style="color: blue"&gt;int&lt;/span&gt; i = 0; i &amp;lt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.Controls.Count; i++)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;this&lt;/span&gt;.Controls[i].RenderControl(output);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
אבל אני מעדיף למצוא כל אחד מהקונטרולים ולרנדר אותו:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&lt;span style="color: #2b91af"&gt;Label&lt;/span&gt; lbl = (&lt;span style="color: #2b91af"&gt;Label&lt;/span&gt;)&lt;span style="color: blue"&gt;this&lt;/span&gt;.FindControl(&lt;span style="color: #a31515"&gt;&amp;quot;lblText&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lbl.RenderControl(output);
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
כך תעברו על כל הקונטרולים שלנו. בצורה הזאת נוכל לשנות מאפיינים בהמשך... &lt;br /&gt;
עכשיו אם נחזור לטופס שלנו אנו אמורים לראות טקסט בוקס (את הלייבלים לא נראה כי לא נתנו להם ערך טקסט) אם אתם לא רואים תעתיקו מחדש את ה dll של הקונטרול לתיקית bin של הפרוייקט( &lt;br /&gt;
תנו ערך למאפיין טקסט על הטופס שלכם 
&lt;/p&gt;
&lt;a href="http://blog.talgiladi.net/image.axd?picture=setTextValue.png"&gt;&lt;img style="display: inline; border: 0px" src="http://blog.talgiladi.net/image.axd?picture=setTextValue_thumb.png" border="0" alt="setTextValue" title="setTextValue" width="248" height="89" /&gt;&lt;/a&gt; 
&lt;p&gt;
רפרש קטן על הדף )לחצן ימני( ואתם אמורים גם לראות את הטקסט ליד הטקסט בוקס. זה יהיה גם רעיון טוב לתת ערך ברירת מחדל למאפיין הזה, אז בחזרה לקונטרול, תלכו למאפיין Text, יש שם תגית בשם DefaultValue, תנו לה איזה ערך שתרצו, וגם ב Get של המאפיין תחזירו את אותו טקסט במקרה והוא ריק: 
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
[&lt;span style="color: #2b91af"&gt;Bindable&lt;/span&gt;(&lt;span style="color: blue"&gt;true&lt;/span&gt;)]
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af"&gt;Category&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;Appearance&amp;quot;&lt;/span&gt;)]
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af"&gt;DefaultValue&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;Please enter the answer&amp;quot;&lt;/span&gt;)]
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af"&gt;Localizable&lt;/span&gt;(&lt;span style="color: blue"&gt;true&lt;/span&gt;)]&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; Text
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;get&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;String&lt;/span&gt; s = (&lt;span style="color: #2b91af"&gt;String&lt;/span&gt;)ViewState[&lt;span style="color: #a31515"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;];
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; ((s == &lt;span style="color: blue"&gt;null&lt;/span&gt;) ? &lt;span style="color: #a31515"&gt;&amp;quot;Please enter the answer&amp;quot;&lt;/span&gt; : s);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;set&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ViewState[&lt;span style="color: #a31515"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;] = &lt;span style="color: blue"&gt;value&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
יופי, עכשיו אפשר להתקדם. אנו רוצים להציג לגולש איזה תרגיל מתמטי כדי לבדוק שאכן זה אדם ולא סקריפט. נבנה מחלקה שתבנה תרגיל מתמטי. רק קודם נבנה איזה מחלקה קטנה שתייצג לנו את התרגיל. 
&lt;/p&gt;
&lt;p&gt;
והמחלקה שלנו: 
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Question&lt;/span&gt;:&lt;span style="color: #2b91af"&gt;ICloneable&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;double&lt;/span&gt; _answer;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;double&lt;/span&gt; Answer
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;get&lt;/span&gt; { &lt;span style="color: blue"&gt;return&lt;/span&gt; _answer; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;set&lt;/span&gt; { _answer = &lt;span style="color: blue"&gt;value&lt;/span&gt;; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt; _items;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt; Items
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;get&lt;/span&gt; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (_items == &lt;span style="color: blue"&gt;null&lt;/span&gt;)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _items = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt;();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; _items; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;set&lt;/span&gt; { _items = &lt;span style="color: blue"&gt;value&lt;/span&gt;; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region&lt;/span&gt; ICloneable Members
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;object&lt;/span&gt; Clone()
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;Question&lt;/span&gt; q = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Question&lt;/span&gt;();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; q.Answer = &lt;span style="color: blue"&gt;this&lt;/span&gt;.Answer;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; q.Items = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt;();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; q.Items.AddRange(&lt;span style="color: blue"&gt;this&lt;/span&gt;.Items);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; q;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
המחלקה מכילה בעצם מערך עם הנתונים שצריך להציג לגולש (מספרים וסימני חשבון) ואת התוצאה הסופית של התרגיל. &lt;br /&gt;
עכשיו ניצור לנו מחלקה שתייצר את התרגיל ותמלא אותו בנתונים: 
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;QuestionsGenerator&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Question&lt;/span&gt; _question;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Question&lt;/span&gt; Question
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;get&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (_question == &lt;span style="color: blue"&gt;null&lt;/span&gt;)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Generate();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; _question;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;int&lt;/span&gt; _itemsCount;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;int&lt;/span&gt; ItemsCount
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;get&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; (&lt;span style="color: blue"&gt;int&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;Math&lt;/span&gt;.Max(_itemsCount, 2);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;set&lt;/span&gt; { _itemsCount = &lt;span style="color: blue"&gt;value&lt;/span&gt;; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;int&lt;/span&gt; _maxNumber;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;int&lt;/span&gt; MaxNumber
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;get&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; (&lt;span style="color: blue"&gt;int&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;Math&lt;/span&gt;.Max(10, _maxNumber);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;set&lt;/span&gt; { _maxNumber = &lt;span style="color: blue"&gt;value&lt;/span&gt;; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; QuestionsGenerator()
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;this&lt;/span&gt;.MaxNumber = 10;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;this&lt;/span&gt;.ItemsCount = 4;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;double&lt;/span&gt; Result
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;get&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; Question.Answer;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Question&lt;/span&gt; Source
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;get&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;Question&lt;/span&gt;)Question.Clone();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;override&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; ToString()
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;StringBuilder&lt;/span&gt; sb = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;StringBuilder&lt;/span&gt;();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;for&lt;/span&gt; (&lt;span style="color: blue"&gt;int&lt;/span&gt; i = 0; i &amp;lt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.Question.Items.Count; i++)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(Question.Items[i]);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(&lt;span style="color: #a31515"&gt;&amp;quot; &amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; sb.ToString();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Generate()
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;this&lt;/span&gt;._question = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Question&lt;/span&gt;();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Question.Answer = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Random&lt;/span&gt;().Next(0, MaxNumber);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Question.Items.Add(Question.Answer.ToString());
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;for&lt;/span&gt; (&lt;span style="color: blue"&gt;int&lt;/span&gt; i = 0; i &amp;lt; ItemsCount-1; i++)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AddPair();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;enum&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Sign&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Plus,
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Minus,
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Multiply,
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Divide
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; AddPair()
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Security.Cryptography.&lt;span style="color: #2b91af"&gt;RandomNumberGenerator&lt;/span&gt; rng = System.Security.Cryptography.&lt;span style="color: #2b91af"&gt;RandomNumberGenerator&lt;/span&gt;.Create();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;byte&lt;/span&gt;[] b=&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: blue"&gt;byte&lt;/span&gt;[1];
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rng.GetBytes(b);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;int&lt;/span&gt; next = (&lt;span style="color: blue"&gt;int&lt;/span&gt;)b[0] % MaxNumber;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;Sign&lt;/span&gt; s = (&lt;span style="color: #2b91af"&gt;Sign&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;Enum&lt;/span&gt;.Parse(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Sign&lt;/span&gt;), ((&lt;span style="color: blue"&gt;int&lt;/span&gt;)b[0]%4).ToString());
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;switch&lt;/span&gt; (s)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;case&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Sign&lt;/span&gt;.Plus:
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Question.Answer = Question.Answer + next;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Question.Items.Add(&lt;span style="color: #a31515"&gt;&amp;quot;+&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;break&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;case&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Sign&lt;/span&gt;.Minus:
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Question.Answer = Question.Answer - next;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Question.Items.Add(&lt;span style="color: #a31515"&gt;&amp;quot;-&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;break&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;case&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Sign&lt;/span&gt;.Multiply:
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Question.Answer = Question.Answer * next;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Question.Items.Add(&lt;span style="color: #a31515"&gt;&amp;quot;*&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;break&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;case&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Sign&lt;/span&gt;.Divide:
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;bool&lt;/span&gt; found = &lt;span style="color: blue"&gt;false&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;for&lt;/span&gt; (&lt;span style="color: blue"&gt;int&lt;/span&gt; i = 0; i &amp;lt; 5; i++)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (Question.Answer % next != 0)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; next++;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;else&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; found = &lt;span style="color: blue"&gt;true&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;break&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (!found)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; next = 1;&lt;span style="color: green"&gt;//dont&amp;#39; get complicated now...&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Question.Answer = (&lt;span style="color: blue"&gt;int&lt;/span&gt;)(Question.Answer / next);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Question.Items.Add(&lt;span style="color: #a31515"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;break&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Question.Items.Add(next.ToString());
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
מחלקה פשוטה שמגרילה כמה מספרים וכמה פעולות מתמטיות ומחשבת את התוצאה. &lt;br /&gt;
כעת נחזור לקונטרול שלנו וניתן לליבל שמכילה את התרגיל את הטקסט שלה, בדיוק לפני הרינדור 
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
lbl = (&lt;span style="color: #2b91af"&gt;Label&lt;/span&gt;)&lt;span style="color: blue"&gt;this&lt;/span&gt;.FindControl(&lt;span style="color: #a31515"&gt;&amp;quot;lblQuestion&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;QuestionsGenerator&lt;/span&gt; qg = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;QuestionsGenerator&lt;/span&gt;();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lbl.Text = qg.ToString();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lbl.RenderControl(output);
&lt;/p&gt;
&lt;/div&gt;
&lt;a href="http://blog.talgiladi.net/image.axd?picture=mathquestion.png"&gt;&lt;img style="display: inline; border: 0px" src="http://blog.talgiladi.net/image.axd?picture=mathquestion_thumb.png" border="0" alt="mathquestion" title="mathquestion" width="395" height="77" /&gt;&lt;/a&gt; 
&lt;p&gt;
נמשיך... אנו צריכים לשמור את התוצאה של התרגיל ב Session של הגולש כדי שנידע אם הוא ענה נכון, אז נוסיף עוד שורה קטנה: 
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
lbl = (&lt;span style="color: #2b91af"&gt;Label&lt;/span&gt;)&lt;span style="color: blue"&gt;this&lt;/span&gt;.FindControl(&lt;span style="color: #a31515"&gt;&amp;quot;lblQuestion&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;QuestionsGenerator&lt;/span&gt; qg = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;QuestionsGenerator&lt;/span&gt;();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;HttpContext&lt;/span&gt;.Current.Session.Add(&lt;span style="color: #a31515"&gt;&amp;quot;LightCaptchaControl_answer&amp;quot;&lt;/span&gt;, qg.Result);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lbl.Text = qg.ToString();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lbl.RenderControl(output);
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
עכשיו נוסיף פרופרטי שיאפשר לדף שבתוכו הקונטרול לבדוק אם התוצאה אכן תקינה
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
[&lt;span style="color: #2b91af"&gt;Browsable&lt;/span&gt;(&lt;span style="color: blue"&gt;false&lt;/span&gt;)]
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;bool&lt;/span&gt; IsValid
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;get&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;double&lt;/span&gt; result;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: blue"&gt;double&lt;/span&gt;.TryParse(((&lt;span style="color: #2b91af"&gt;TextBox&lt;/span&gt;)&lt;span style="color: blue"&gt;this&lt;/span&gt;.FindControl(&lt;span style="color: #a31515"&gt;&amp;quot;txtAnswer&amp;quot;&lt;/span&gt;)).Text, &lt;span style="color: blue"&gt;out&lt;/span&gt; result))
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;HttpContext&lt;/span&gt;.Current.Session[&lt;span style="color: #a31515"&gt;&amp;quot;LightCaptchaControl_answer&amp;quot;&lt;/span&gt;] != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; result == (&lt;span style="color: blue"&gt;double&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;HttpContext&lt;/span&gt;.Current.Session[&lt;span style="color: #a31515"&gt;&amp;quot;LightCaptchaControl_answer&amp;quot;&lt;/span&gt;];
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: blue"&gt;false&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
וזהו... עכשיו מי שמשתמש בקונטרול צריך בסך הכל לבדוק את הפרופרטי הזה:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&lt;span style="color: blue"&gt;protected&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; btnSubmit_Click(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af"&gt;EventArgs&lt;/span&gt; e)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;bool&lt;/span&gt; valid = &lt;span style="color: blue"&gt;this&lt;/span&gt;.LightCaptchaControl1.IsValid;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
נראה לי שעדיף לנו גם ליצור פונקציה שתערבל קצת את התצוגה של התרגיל, כי הרי מי שבונה סקריפט אוטומטי למילוי טפסים יצטרך בסך הכל להשקיע עוד 5 דקות כדי לקרוא את התרגיל שלנו ולהכניס את התשובה הנכונה, אז הוספתי פונקציה פשוטה, אבל שתדרוש קצת יותר מאמץ מבונה הסקריפטים, אתם יכולים לסבך אותה עוד לפי אותו עיקרון:&amp;nbsp; 
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; ToRandomHtml()
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;char&lt;/span&gt;[] chars=&lt;span style="color: #a31515"&gt;&amp;quot;abcdefghijklmnopqrstuvwxyz1234567890&amp;quot;&lt;/span&gt;.ToCharArray();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;StringBuilder&lt;/span&gt; sb = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;StringBuilder&lt;/span&gt;();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;for&lt;/span&gt; (&lt;span style="color: blue"&gt;int&lt;/span&gt; i = 0; i &amp;lt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.Question.Items.Count; i++)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Security.Cryptography.&lt;span style="color: #2b91af"&gt;RandomNumberGenerator&lt;/span&gt; rng = System.Security.Cryptography.&lt;span style="color: #2b91af"&gt;RandomNumberGenerator&lt;/span&gt;.Create();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;byte&lt;/span&gt;[] b = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: blue"&gt;byte&lt;/span&gt;[1];
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rng.GetBytes(b);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;int&lt;/span&gt; ran = (&lt;span style="color: blue"&gt;int&lt;/span&gt;)b[0] % 5;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;switch&lt;/span&gt; (ran)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;case&lt;/span&gt; 0:
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(Question.Items[i]);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;String&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;#39; &amp;#39;&lt;/span&gt;,&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Random&lt;/span&gt;().Next(4)));
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;break&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;case&lt;/span&gt; 1:
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(Question.Items[i]);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(&lt;span style="color: #a31515"&gt;&amp;quot;&amp;lt;span style=\&amp;quot;display:none\&amp;quot;&amp;gt;&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(Question.Items[i]);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(&lt;span style="color: #a31515"&gt;&amp;quot;&amp;lt;/span&amp;gt;&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;break&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;case&lt;/span&gt; 2:
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(&lt;span style="color: #a31515"&gt;&amp;quot;&amp;lt;span style=\&amp;quot;display:none\&amp;quot;&amp;gt;&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(Question.Items[i]);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(&lt;span style="color: #a31515"&gt;&amp;quot;&amp;lt;/span&amp;gt;&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(Question.Items[i]);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;break&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;case&lt;/span&gt; 3:
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(&lt;span style="color: #a31515"&gt;&amp;quot;&amp;lt;b&amp;gt;&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(Question.Items[i]);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(&lt;span style="color: #a31515"&gt;&amp;quot;&amp;lt;/b&amp;gt;&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;break&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;case&lt;/span&gt; 4:
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(&lt;span style="color: #a31515"&gt;&amp;quot;&amp;lt;u&amp;gt;&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(Question.Items[i]);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(&lt;span style="color: #a31515"&gt;&amp;quot;&amp;lt;/u&amp;gt;&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;break&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; sb.ToString();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
אז רק צריך לשנות את הלייבל שמציגה את התרגיל כך שתקבל את הטקסט מהפונקציה הזאת. &lt;br /&gt;
כמובן שאפשר להרחיב ולהוסיף שליטה על העיצוב על ידי המשתמש, שליטה על אורך התרגיל להצגה וכו&amp;#39;, בזמנכם החופשי...
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.talgiladi.net/examples/LightCaptchaControl.zip" title="download"&gt;להורדת הפרוייקט ודוגמה&lt;/a&gt;
&lt;/p&gt;
</description>
      <link>http://blog.talgiladi.net/post/Custom-web-controls.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/Custom-web-controls.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=4d32dfd3-681b-466c-96cc-8302f520f808</guid>
      <pubDate>Sun, 09 Dec 2007 17:04:00 +0400</pubDate>
      <category>Controls</category>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=4d32dfd3-681b-466c-96cc-8302f520f808</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=4d32dfd3-681b-466c-96cc-8302f520f808</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/Custom-web-controls.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=4d32dfd3-681b-466c-96cc-8302f520f808</wfw:commentRss>
    </item>
    <item>
      <title>דיפדוף באמצעות אג'קס</title>
      <description>&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:3ed397ff-42f1-43d5-bf33-c03dd39d321f" class="wlWriterEditableSmartContent" style="float: none; margin: 0px; display: inline; padding: 0px"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/javascript"&gt;javascript&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/paging"&gt;paging&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/ajax"&gt;ajax&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;
.התחלנו כבר לדבר על &lt;a href="http://www.talgiladi.net/paging.aspx"&gt;דיפדוף יעיל&lt;/a&gt; בדטה בייס בעבר, עכשיו נמשיך את זה לצד הלקוח &lt;br /&gt;
נשתמש באג&amp;#39;קס ליישום הדיפדוף (אני משתמש ב &lt;a href="http://www.prototypejs.org/"&gt;framework&lt;/a&gt; לנוחות, אבל כל &lt;a href="http://www.talgiladi.net/Ajax.aspx"&gt;אג&amp;#39;קס&lt;/a&gt; יעשה את העבודה) &lt;br /&gt;
נתחיל בבניית הטבלה בדף, אנחנו כבר יודעים איך למשוך את הנתונים כך שנקבל רק את השורות המתאימות לדף שלנו, אז פשוט נזרוק את כל הנתונים לדף בצורת טבלה. את הטבלה נשים בתוך div עם id 
&lt;/p&gt;
&lt;p&gt;
נבנה בדף פונקציה שתמשוך לנו את הנתונים מה ADP
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;span class="code_keywords"&gt;private string&lt;/span&gt; GetTable() &lt;br /&gt;
{ &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int&lt;/span&gt; pagenum; &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/span&gt; (!&lt;span class="code_keywords"&gt;int&lt;/span&gt;.TryParse(Request.Params[&amp;quot;pagenum&amp;quot;], &lt;span class="code_keywords"&gt;out&lt;/span&gt; pagenum)) &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pagenum = 1; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int&lt;/span&gt; rowsPerPage = 10; &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; string&lt;/span&gt; sortByColumn = Request.Params[&lt;span class="code_text"&gt;&amp;quot;sortName&amp;quot;&lt;/span&gt;]; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (&lt;span class="code_keywords"&gt;string&lt;/span&gt;.IsNullOrEmpty(sortByColumn)) sortByColumn = &lt;span class="code_text"&gt;&amp;quot;id&amp;quot;&lt;/span&gt;; &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; string&lt;/span&gt; sortOrder = Request.Params[&lt;span class="code_text"&gt;&amp;quot;sortOrder&amp;quot;&lt;/span&gt;]; &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/span&gt; (&lt;span class="code_keywords"&gt;string&lt;/span&gt;.IsNullOrEmpty(sortOrder)) sortOrder = &lt;span class="code_text"&gt;&amp;quot;asc&amp;quot;&lt;/span&gt;; &lt;br /&gt;
&lt;span class="code_classes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DataTable&lt;/span&gt; table = ADP.GetUsers(pagenum, rowsPerPage, sortByColumn, sortOrder); &lt;br /&gt;
&lt;span class="code_classes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; StringBuilder&lt;/span&gt; sb = &lt;span class="code_keywords"&gt;new&lt;/span&gt; &lt;span class="code_classes"&gt;StringBuilder&lt;/span&gt;(); &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(&lt;span class="code_text"&gt;&amp;quot;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;id&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;name&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;quot;&lt;/span&gt;); &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach&lt;/span&gt; (&lt;span class="code_classes"&gt;DataRow&lt;/span&gt; dr &lt;span class="code_keywords"&gt;in&lt;/span&gt; table.Rows) &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(&lt;span class="code_text"&gt;&amp;quot;&amp;lt;tr&amp;gt;&amp;quot;&lt;/span&gt;); &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(&lt;span class="code_text"&gt;&amp;quot;&amp;lt;td&amp;gt;&amp;quot;&lt;/span&gt;); &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(dr[&lt;span class="code_text"&gt;&amp;quot;id&amp;quot;&lt;/span&gt;]); &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(&lt;span class="code_text"&gt;&amp;quot;&amp;lt;/td&amp;gt;&amp;quot;&lt;/span&gt;); &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(&lt;span class="code_text"&gt;&amp;quot;&amp;lt;td&amp;gt;&amp;quot;&lt;/span&gt;); &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(dr[&lt;span class="code_text"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;]); &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(&lt;span class="code_text"&gt;&amp;quot;&amp;lt;/td&amp;gt;&amp;quot;&lt;/span&gt;); &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(&lt;span class="code_text"&gt;&amp;quot;&amp;lt;/tr&amp;gt;&amp;quot;&lt;/span&gt;); &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(&lt;span class="code_text"&gt;&amp;quot;&amp;lt;/table&amp;gt;&amp;quot;&lt;/span&gt;); &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/span&gt; sb.ToString(); &lt;br /&gt;
} 
&lt;/div&gt;
&lt;p&gt;
הפונקציה הזאת בעצם בונה לנו את הטבלה לפי פרמטרים שהיא מקבלת מהדף כמו מספר הדף ולפי מה למיין. אם זו כניסה ראשונה לדף ואין עדיין נתונים היא משתמשת בערכי ברירת מחדל. קבענו כאן גם את מספר השורות להציג בכל דף. כעת ניקח את התוצאה של הפונקציה הזאת ונציב את הסטרינג הזה בתוך הdiv שלנו
&lt;/p&gt;
&lt;div class="code_area"&gt;
&amp;lt;div id=&amp;quot;div_data&amp;quot;&amp;gt;&lt;span class="code_yellow"&gt;&amp;lt;%&lt;/span&gt;=myTable&lt;span class="code_yellow"&gt;%&amp;gt;&lt;/span&gt; &lt;br /&gt;
&amp;lt;/div&amp;gt;
&lt;/div&gt;
&lt;p&gt;
כעת נבנה את שורת הדפדוף, אני אשתמש בפשוטה ביותר כרגע. קודם צריכים לדעת כמה נתונים יש בדטה בייס, נמשוך את מספר השורות ונחלק במספר השורות שאנו מציגים בדף כדי לדעת את מספר הדפים
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;span class="code_keywords"&gt;int&lt;/span&gt; rowsCount =&lt;span class="code_classes"&gt;ADP&lt;/span&gt;.GetUsersCount(); &lt;br /&gt;
&lt;span class="code_keywords"&gt;int&lt;/span&gt; rowsPerPage = 10; &lt;br /&gt;
&lt;span class="code_keywords"&gt;int&lt;/span&gt; totalPages=(&lt;span class="code_keywords"&gt;int&lt;/span&gt;)&lt;span class="code_classes"&gt;Math&lt;/span&gt;.Ceiling((double)rowsCount / rowsPerPage); &lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;
הפייג&amp;#39;ר עצמו בדף html:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;span class="code_yellow"&gt;&amp;lt;%&lt;/span&gt;for (int i=0;i&amp;lt;totalPages;i++) &lt;br /&gt;
{ &lt;span class="code_yellow"&gt;%&amp;gt;&lt;/span&gt; &lt;br /&gt;
&amp;lt;a href=&amp;quot;javascript:doPaging(&lt;span class="code_yellow"&gt;&amp;lt;%&lt;/span&gt;=(i+1)&lt;span class="code_yellow"&gt;%&amp;gt;&lt;/span&gt;)&amp;quot;&amp;gt;&lt;span class="code_yellow"&gt;&amp;lt;%&lt;/span&gt;=(i+1)&lt;span class="code_yellow"&gt;%&amp;gt;&lt;/span&gt;&amp;lt;/a&amp;gt; &lt;br /&gt;
&lt;span class="code_yellow"&gt;%&amp;lt;&lt;/span&gt;}&lt;span class="code_yellow"&gt;%&amp;gt;&lt;/span&gt;
&lt;/div&gt;
&lt;p&gt;
ופונקציית ג&amp;#39;אווה קטנה
&lt;/p&gt;
&lt;div class="code_area"&gt;
&amp;lt;&lt;span class="script_text"&gt;script&lt;/span&gt; &lt;span class="script_type"&gt;type&lt;/span&gt;=&lt;span class="code_keywords"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&amp;gt; &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var&lt;/span&gt; curpage=1; &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var&lt;/span&gt; sortName=&lt;span class="script_text"&gt;&amp;#39;id&amp;#39;&lt;/span&gt;; &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var&lt;/span&gt; sortDirection=&lt;span class="script_text"&gt;&amp;#39;asc&amp;#39;&lt;/span&gt;; &lt;br /&gt;
&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;function&lt;/span&gt; doPaging(pagenum){ &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; curpage=pagenum; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var&lt;/span&gt; url=&lt;span class="script_text"&gt;&amp;#39;mypage.aspx?action=paging&amp;amp;pagenum=&amp;#39;&lt;/span&gt;+curpage+&lt;span class="script_text"&gt;&amp;#39;&amp;amp;sortName=&amp;#39;&lt;/span&gt;+ sortName+&lt;span class="script_text"&gt;&amp;#39;&amp;amp;sortOrder&amp;#39;&lt;/span&gt;+sortDirection; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;new&lt;/span&gt; Ajax.Request(url,{onSuccess:function(t){ &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;if&lt;/span&gt; (t.responseText==&amp;#39;error&amp;#39;){ &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; alert(&lt;span class="script_text"&gt;&amp;#39;error!&amp;#39;&lt;/span&gt;); &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;span class="code_keywords"&gt;else&lt;/span&gt;{ &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; document.getElementById(&lt;span class="script_text"&gt;&amp;#39;div_data&amp;#39;&lt;/span&gt;).innerHTML=t.responseText; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }}); &lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/&lt;span class="script_text"&gt;script&lt;/span&gt;&amp;gt;
&lt;/div&gt;
&lt;p&gt;
זהו, בשביל הדפדוף זה מספיק... רק בשביל המיון צריך עוד 2 דברים קטנים לעשות. קודם כל כשאנו בונים את הטבלה, אז בכותרות להוסיף הפניה לפונקציה של ג&amp;#39;אווה סקריפט כדי שכשמקליקים על הכותרת יתבצע מיון &lt;br /&gt;
נשנה מעט את איך שבנינו את הטבלה מקודם במקום לכתוב id בכותרת נכתוב &amp;lt;a href=\&amp;quot;javascript:doSort(&amp;#39;id&amp;#39;);\&amp;quot;&amp;gt;id&amp;lt;/a&amp;gt;&amp;nbsp; ,וכך לגבי שאר הכותרות, ונבנה את הפונקציה המתאימה בג&amp;#39;אווה סקריפט
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;span class="code_keywords"&gt;function&lt;/span&gt; doSort(columnName){ &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/span&gt; (sortName==columnName){ &lt;br /&gt;
&lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/span&gt; (sortDirection==&lt;span class="script_text"&gt;&amp;#39;asc&amp;#39;&lt;/span&gt;){ &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sortDirection=&lt;span class="script_text"&gt;&amp;#39;desc&amp;#39;&lt;/span&gt;; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;span class="code_keywords"&gt;else&lt;/span&gt;{ &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sortDirection=&lt;span class="script_text"&gt;&amp;#39;asc&amp;#39;&lt;/span&gt;; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;span class="code_keywords"&gt;else&lt;/span&gt;{ &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sortName=columnName; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sortDirection=&amp;#39;asc&amp;#39;; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var&lt;/span&gt; url=&lt;span class="script_text"&gt;&amp;#39;mypage.aspx?action=paging&amp;amp;pagenum=&amp;#39;&lt;/span&gt;+curpage+&lt;span class="script_text"&gt;&amp;#39;&amp;amp;sortName=&amp;#39;&lt;/span&gt;+ sortName+&lt;span class="script_text"&gt;&amp;#39;&amp;amp;sortOrder&amp;#39;&lt;/span&gt;+sortDirection; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;new&lt;/span&gt; Ajax.Request(url,{onSuccess:function(t){ &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="code_keywords"&gt;if&lt;/span&gt; (t.responseText==&amp;#39;error&amp;#39;){ &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; alert(&lt;span class="script_text"&gt;&amp;#39;error!&amp;#39;&lt;/span&gt;); &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;span class="code_keywords"&gt;else&lt;/span&gt;{ &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; document.getElementById(&lt;span class="script_text"&gt;&amp;#39;div_data&amp;#39;&lt;/span&gt;).innerHTML=t.responseText; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }}); &lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/&lt;span class="script_text"&gt;script&lt;/span&gt;&amp;gt;
&lt;/div&gt;
&lt;p&gt;
הפונקציה הזאת רק מסדרת את הפרמטר של שם העמודה למיון והסדר (עולה יורד) וממשיכה כרגיל כמו הפונקציה הקודמת. זהו בעיקרון, ניתן להוסיף גם חיפוש באותה שיטה&amp;nbsp; למי שרוצה...
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.talgiladi.net/examples/AjaxPagingExample.zip"&gt;להורדת דוגמה&lt;/a&gt; (ללא דטה בייס כמובן)
&lt;/p&gt;
</description>
      <link>http://blog.talgiladi.net/post/d793d799d7a4d793d795d7a3-d791d790d79ed7a6d7a2d795d7aa-d790d792d7a7d7a1.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/d793d799d7a4d793d795d7a3-d791d790d79ed7a6d7a2d795d7aa-d790d792d7a7d7a1.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=a1071b9e-f407-4b46-af28-be7c059f2b29</guid>
      <pubDate>Tue, 04 Dec 2007 15:40:00 +0400</pubDate>
      <category>JavaScript</category>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=a1071b9e-f407-4b46-af28-be7c059f2b29</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=a1071b9e-f407-4b46-af28-be7c059f2b29</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/d793d799d7a4d793d795d7a3-d791d790d79ed7a6d7a2d795d7aa-d790d792d7a7d7a1.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=a1071b9e-f407-4b46-af28-be7c059f2b29</wfw:commentRss>
    </item>
    <item>
      <title>ILMerge - לאיחוד קבצים</title>
      <description>&lt;p&gt;
קרה לי מספר פעמים שכתבתי תוכנה שמשתמשת ב dll מצד שלישי, ושלא רציתי שהצד שמקבל את התוכנה יראה את הקבצים האלה, מסיבות שלי... ואז חיפשתי ומצאתי את הכלי הזה שבעצם מאחד dllים... חוץ מזה שלפעמים זה נחמד שיש לך קובץ אחד ולא 10 מפוזרים... &lt;br /&gt;
השימוש מאוד פשוט - פשוט תנו לתוכנה הזאת את הקבצים שאתם רוצים לאחד ואת שם הקובץ הסופי והיא כבר תאחד אותם. &lt;br /&gt;
רק שימו לב למספר נקודות: 
&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
	&lt;p&gt;
	לנקודה חשובה, התוכנה לא מתריעה על שגיאות שהיו! אתם צריכים לשים שגודל הקובץ הסופי אכן השתנה ושהוא לא 0... 
	&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;
	&lt;p&gt;
	לעשות גיבוי לספריה של הקבצים כי אם כן היו שגיאות הלך לכם הקובץ (אבל ברור שהיא לא נוגעת בקבצי המקור) 
	&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;
	&lt;p&gt;
	כמו כן התוכנה קצת מתעצבנת אם יש באותה תיקיה קבצי pdb שנשארו מהפיתוח, אז תמחקו אותם קודם 
	&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;
	&lt;p&gt;
	התוכנה מקבלת רשימת קבצים לאיחוד, הקובץ הראשון הוא הקובץ העיקרי - זה שמשתמש באחרים 
	&lt;/p&gt;
	&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
לאחר ההתקנה השימוש פשוט מאוד , פשוט תריצו אותה עם רשימת הקבצים לאיחוד ואת השם שאתם רוצים שיינתן לקובץ הסופי:
&lt;/p&gt;
&lt;div class="code_area"&gt;
&lt;p&gt;
Ilmerge MyApplication.exe ThirdPartyApplication.dll /out:MyApplication.exe 
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
ניתן להוריד את &lt;a href="http://research.microsoft.com/%7Embarnett/ILMerge.aspx"&gt;התוכנה מאתר מיקרוסופט&lt;/a&gt; , וראיתי שכבר כתבו כלים גרפיים להריץ אותה, כשהראשון נכתב על ידי ישראלים :) 
&lt;/p&gt;
&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:05a13ae7-6e74-4c49-baae-5807fa7ea660" class="wlWriterEditableSmartContent" style="float: none; margin: 0px; display: inline; padding: 0px"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/Ilmerge"&gt;Ilmerge&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/join+dlls"&gt;join dlls&lt;/a&gt;
&lt;/div&gt;
</description>
      <link>http://blog.talgiladi.net/post/ILMerge-d79cd790d799d797d795d793-d7a7d791d7a6d799d79d.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/ILMerge-d79cd790d799d797d795d793-d7a7d791d7a6d799d79d.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=d5cdbef3-ef99-4cbc-821e-8497ab4aee11</guid>
      <pubDate>Sun, 02 Dec 2007 10:02:00 +0400</pubDate>
      <category>C#</category>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=d5cdbef3-ef99-4cbc-821e-8497ab4aee11</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=d5cdbef3-ef99-4cbc-821e-8497ab4aee11</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/ILMerge-d79cd790d799d797d795d793-d7a7d791d7a6d799d79d.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=d5cdbef3-ef99-4cbc-821e-8497ab4aee11</wfw:commentRss>
    </item>
    <item>
      <title>דיפדוף יעיל</title>
      <description>&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:736e83d1-7e9e-43f1-91b9-83c3b9529ead" class="wlWriterEditableSmartContent" style="float: none; margin: 0px; display: inline; padding: 0px"&gt;
Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/sql"&gt;sql&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/paging"&gt;paging&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;
לעיתים אנו רוצים להציג למשתמשים מידע רב מבסיס הנתונים, ולא רוצים להציג את כולו בדף אחד. אז נכון שקיימים הפקדים של הדוט נט שחלקם מכילים כבר אופציה לדיפדוף, אבל זה בעצם דיפדוף &amp;quot;מדומה&amp;quot;, הם לא באמת מושכים את המידע שאנחנו צריכים מהדטה בייס, הם מושכים את כל הרשומות, ומציגים לנו את מה שאנחנו צריכים, לכן, אם יש לי מיליון רשומות ואני רוצה להציג 50 כל פעם, אזי כל פעם שאני מדפדף דרך הקונטרול, הוא מושך את כל המיליון רשומות מהדטה בייס ופשוט מציג את ה 50 הבאות. אז השיטה הזו טובה כשרוצים בזריזות לבנות איזה דף עם כמה נתונים, אבל לשרת אמיתי שמשרת עשרות אלפי לקוחות צריך למצוא שיטה טובה יותר. &lt;br /&gt;
הכתבה תתרכז בצד של השאילתות לדטה בייס ולא בצד הלקוח. בפעם הבאה נדבר על ישום אג`קסי של הדפדוף ואז גם ניתן יהיה להוריד את הפרוייקט. 
&lt;/p&gt;
&lt;p&gt;
השיטה הקלה, אם נתמזל מזלנו ואנחנו לא צריכים אפשרות למיין, או מאפשרים מיון רק לפי עמודה שהיא ייחודית כמו אינדקס, אז פשוט נבנה את הדיפדוף כך שימשוך כל פעם את מספר הרשומות שאנחנו רוצים עם תנאי שמספר האינדקס יהיה גדול (או קטן במקרה של מיון מהגדול לקטן) ממספר כלשהו - האינדקס האחרון מהדף הקודם ( שאותו נשמור בדף או בסשן ). לדוגמא:
&lt;/p&gt;
&lt;p&gt;
ניצור טבלה בשם t1 עם 3 עמודות:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.talgiladi.net/image.axd?picture=tbl1.jpg"&gt;&lt;img style="display: inline; border: 0px" src="http://blog.talgiladi.net/image.axd?picture=tbl1_thumb.jpg" border="0" alt="tbl1" title="tbl1" width="607" height="212" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
מספר השורות שאנחנו רוצים להציג בדף
&lt;/p&gt;
&lt;p align="left"&gt;
const int rowsPerPage=2;
&lt;/p&gt;
&lt;p&gt;
משתנה שמכיל את מספר המזהה של השורה האחרונה שמשכנו (בפעם הראשונה הוא יהיה 0 כמובן):
&lt;/p&gt;
&lt;p align="left"&gt;
int lastid=0;
&lt;/p&gt;
&lt;p&gt;
השאילתה :
&lt;/p&gt;
&lt;p align="left"&gt;
sql:Sel ect top [rowsPerPage] from t1 where id&amp;gt;[lastid] order by id
&lt;/p&gt;
&lt;p align="left"&gt;
MySql : Sel ect * from t1 where id&amp;gt;[lastid] order by id limit [rowsPerPage]
&lt;/p&gt;
&lt;p&gt;
כעת נשמור לנו את המספר המזהה של הרשומה האחרונה שמשכנו&amp;nbsp; -3 את המספר כאמור ניתן לשמור או בסשן (לא מומלץ) או בדף עצמו - למשל בלחצן שמעביר לדף הבא - להוסיף לו את הפרמטר הזה.
&lt;/p&gt;
&lt;p&gt;
כשהלקוח ילחץ על דיפדוף לדף הבא או הקודם, נקבל בשרת את הערך הזה ולפיו נדע איזה רשומות למשוך עכשיו. במקרה שלנו נקבל את המספר 3 לשרת והשאילתה תהיה:
&lt;/p&gt;
&lt;p align="left"&gt;
Sql :Sel ect top 2 * from t1 where id&amp;gt;3 order by id
&lt;/p&gt;
&lt;p align="left"&gt;
MySql: Sel ect * from t1 where id&amp;gt;3 order by id limit 2 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.talgiladi.net/image.axd?picture=tbl2.jpg"&gt;&lt;img style="display: inline; border: 0px" src="http://blog.talgiladi.net/image.axd?picture=tbl2_thumb.jpg" border="0" alt="tbl2" title="tbl2" width="626" height="72" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
וכך הלאה לשאר הדפים. 
&lt;/p&gt;
&lt;p&gt;
החסרונות ברורים:
&lt;/p&gt;
&lt;p&gt;
לא ניתן למיין לפי עמודות אחרות שכן אנחנו חייבים עמודה עם מזהה יחודי
&lt;/p&gt;
&lt;p&gt;
לא ניתן לקפוץ לעמוד מסויים, שכן אנחנו יודעים את האינדקס של העמוד הבא&amp;nbsp; והקודם בלבד
&lt;/p&gt;
&lt;p&gt;
כדי לנסות לפתור את 2 המגבלות האלה, ניתן לשכלל קצת את הפיתרון שלנו כפי שמופיע &lt;a href="http://msdn2.microsoft.com/en-us/library/ms979197.aspx"&gt;באתר של מיקרוסופט&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
בשיטה זו נוכל גם למיין לפי עמודות אחרות&amp;nbsp; וגם נוכל לקפוץ לכל עמוד שנרצה: &lt;br /&gt;
נגדיר משתנה שישמור את מספר הדף:
&lt;/p&gt;
&lt;p align="left"&gt;
int pageNum=1;
&lt;/p&gt;
&lt;p align="left"&gt;
Sql : select top [rowsPerPage] * from (select top [rowsPerPage*pageNum] * from t1 order by name desc) as t2 order by name &lt;br /&gt;
Mysql : select * from (select * from t1 order by name desc limit [rowsPerPage*pageNum]) as t2 order by name limit [rowsPerPage]
&lt;/p&gt;
&lt;p&gt;
דבר נוסף שחסכנו זה את הצורך לשמור את האינדקס של העמודה האחרונה, אנחנו ישר בוחרים לפי מספר הדף שהלקוח לחץ עליו. נניח שהוא לחץ על דף מספר 3, ואנו כאמור רוצים להציג 2 שורות בכל דף, אזי השאילתה תהיה :
&lt;/p&gt;
&lt;p align="left"&gt;
MySql : sel ect * from (SEL ECT * FROM t1 order by name desc limit 6) as t2 order by name limit 2
&lt;/p&gt;
&lt;p align="left"&gt;
Sql :sel ect top 2* from( sel ect top 6 * from t1 order by name desc) as&amp;nbsp; t2 order by name
&lt;/p&gt;
&lt;a href="http://blog.talgiladi.net/image.axd?picture=tbl3.jpg"&gt;&lt;img style="display: inline; border: 0px" src="http://blog.talgiladi.net/image.axd?picture=tbl3_thumb.jpg" border="0" alt="tbl3" title="tbl3" width="627" height="71" /&gt;&lt;/a&gt; 
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
אולם גם זה פיתרון חלקי ( מיקרוסופט כנראה לא שמה לב...) , כי עבור עמודות עם ערכים זהים, כמו עמודת &amp;quot;מין&amp;quot;, תתקבלנה תוצאות מוזרות :
&lt;/p&gt;
&lt;p align="left"&gt;
MySql : sel ect * from (SEL ECT * FROM t1 order by gender desc limit 6) as t2 order by gender limit 2
&lt;/p&gt;
&lt;p align="left"&gt;
Sql : sel ect top 2 * from (sel ect top 6 from t1 order by gender desc) as t2 order by gender
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.talgiladi.net/image.axd?picture=tbl4.jpg"&gt;&lt;img style="display: inline; border: 0px" src="http://blog.talgiladi.net/image.axd?picture=tbl4_thumb.jpg" border="0" alt="tbl4" title="tbl4" width="629" height="72" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
עדיין אנחנו לא יכולים למיין לפי עמודת &amp;quot;מין&amp;quot;...
&lt;/p&gt;
&lt;p&gt;
אז מה כן עושים? טוב, אז אם יש לנו Sql Server 2005 או MySql הפיתרון יעיל וקל. לא משנה לפי איזו עמודה אני רוצה למיין:
&lt;/p&gt;
&lt;p&gt;
ב sql server 2005 נכתוב
&lt;/p&gt;
&lt;p align="left"&gt;
select * ,rank from (select *, row_number() over(order by gender desc) as rank from t1) as t2 where rank between [(pageNum-1)*rowsPerPage+1] and [(pageNum-1)*rowsPerPage+rowsPerPage]
&lt;/p&gt;
&lt;p&gt;
וב MySql הרבה יותר פשוט, פשוט נכתוב
&lt;/p&gt;
&lt;p align="left"&gt;
select * from clients limit [(pageNum-1)*rowsPerPage],[rowsPerPage]
&lt;/p&gt;
&lt;p&gt;
והתוצאה כצפוי:
&lt;/p&gt;
&lt;p align="left"&gt;
MySql : sel ect * from t1 order by gender limit 2,2
&lt;/p&gt;
&lt;p align="left"&gt;
Sql : sel ect *,rank from
&lt;/p&gt;
&lt;p align="left"&gt;
(sel ect *,row_number() over(order by gender desc) as rank from t1 ) as t2
&lt;/p&gt;
&lt;p align="left"&gt;
where rank between 7 and 8
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.talgiladi.net/image.axd?picture=tbl5.jpg"&gt;&lt;img style="display: inline; border: 0px" src="http://blog.talgiladi.net/image.axd?picture=tbl5_thumb.jpg" border="0" alt="tbl5" title="tbl5" width="632" height="72" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
אבל מה עושים אם אני עובד עם שרת אחר?
&lt;/p&gt;
&lt;p&gt;
אז הפיתרון קצת יותר איטי ויותר מסובך, אבל עדיין יותר יעיל מלמשוך את כל הרשומות אלי לדף...
&lt;/p&gt;
&lt;p&gt;
כל פעם אני רוצה לבצע שאילתה, אני אצור טבלה זמנית, עם עמודה אחת של מיספור אוטומטי ועמודה נוספת שתשמור את מספר האינדקס מהטבלה הראשית.
&lt;/p&gt;
&lt;p align="left"&gt;
Create table temp1 (tid int not null primary key auto_increment/identity,foreign_id int)
&lt;/p&gt;
&lt;p&gt;
* אם אני לא סוגר את החיבור לדטה בייס במהלך הפונקציה אז ניתן ליצור את הטבלה בתור טבלה זמנית ואז היא תימחק אוטומטית בעת סגירת החיבור- יותר מהיר ויותר נקי....
&lt;/p&gt;
&lt;p&gt;
כעת נעביר לטבלה הזאת את מספרי האינדקס מהטבלה המקורית, כשהם כבר ממויינים לפי העמודה שאני רוצה:
&lt;/p&gt;
&lt;p align="left"&gt;
Insert into temp1 (foreign_id) select id from t1 order by gender
&lt;/p&gt;
&lt;p&gt;
וכעת אני יכול לבחור את מספרי השורות שאני רוצה:
&lt;/p&gt;
&lt;p align="left"&gt;
Select * from t1, temp1 where t1.id=temp1.foreign_id and temp1.tid between [(pageNumber-1)*rowsPerPage+1] and [(pageNumber-1)* rowsPerPage+rowsPerPage]
&lt;/p&gt;
&lt;p&gt;
והתוצאה כצפוי:
&lt;/p&gt;
&lt;p align="left"&gt;
sel ect t1.* from temp1,t1 where t1.id=temp1.foreign_id and temp1.tid between ((2-1)*2+1) and ((2-1)*2+2) order by gender
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.talgiladi.net/image.axd?picture=tbl6.jpg"&gt;&lt;img style="display: inline; border: 0px" src="http://blog.talgiladi.net/image.axd?picture=tbl6_thumb.jpg" border="0" alt="tbl6" title="tbl6" width="624" height="71" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
רק לא לשכוח בסוף למחוק את הטבלה אם לא השתמשנו בטבלה זמנית...
&lt;/p&gt;
&lt;p&gt;
* יש דרך לשיפור המהירות של השיטה האחרונה באתר &lt;a href="http://www.4guysfromrolla.com/webtech/042606-1.shtml"&gt;4guysfromrolla&lt;/a&gt; &lt;br /&gt;
* ניתן להשתמש ב stored procedures ליעול המהירות
&lt;/p&gt;
</description>
      <link>http://blog.talgiladi.net/post/d793d799d7a4d793d795d7a3-d799d7a2d799d79c.aspx</link>
      <author>tal.nospam@nospam.talgiladi.net (talgiladi)</author>
      <comments>http://blog.talgiladi.net/post/d793d799d7a4d793d795d7a3-d799d7a2d799d79c.aspx#comment</comments>
      <guid>http://blog.talgiladi.net/post.aspx?id=a438a891-0b6a-472d-b30e-f263bb867cb3</guid>
      <pubDate>Sat, 01 Dec 2007 15:30:00 +0400</pubDate>
      <category>sql</category>
      <dc:publisher>talgiladi</dc:publisher>
      <pingback:server>http://blog.talgiladi.net/pingback.axd</pingback:server>
      <pingback:target>http://blog.talgiladi.net/post.aspx?id=a438a891-0b6a-472d-b30e-f263bb867cb3</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://blog.talgiladi.net/trackback.axd?id=a438a891-0b6a-472d-b30e-f263bb867cb3</trackback:ping>
      <wfw:comment>http://blog.talgiladi.net/post/d793d799d7a4d793d795d7a3-d799d7a2d799d79c.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.talgiladi.net/syndication.axd?post=a438a891-0b6a-472d-b30e-f263bb867cb3</wfw:commentRss>
    </item>
  </channel>
</rss>
