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

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

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

December 2010 - Posts

WCF (Windows Communication Foundation) for Beginner - part 3

 

ללמוד WCF פרק 3 - לתקשר עם Service שבאויר.
 
דוגמת הקוד של הפרק - להורדה
 
 
רשימת נושאים בפרק 3:
סיכום דוגמת קוד מהפרק הקודם.
מה Client צריך לעשות כדי לתקשר עם ה - Service.
יצירת Client ראשון בעזרת ChannelFactory.
יצירת Client שני בעזרת Service Reference.
 
 
סיכום דוגמת קוד מהפרק הקודם
בפרק הקודם למדנו מה צריך לעשות כדי להרים Service לאוויר,
ראשית: לכתוב את ה - Contract (בסך הכול Interface עם Attribute של ServiceContract)
שנית: לממש אותו (בסך הכול מחלקה רגילה המממשת Interface)
שלישית: להחליט מי ה - Host שלנו (בדוגמא מהפרק הקודם הלכנו על Console Application), להגדיר בקובץ הקונפיג את ההגדרות המתאימות (באיזה פרוטוקול, את מה חושפים וכו'), ולהשתמש במחלקה ServiceHost כדי להרים את השירות לאוויר.
 
כל הקוד ביחד נראה כך:
Contract:
 

namespace Contarcts

{

    [ServiceContract]

    public interface ICalc

    {

        [OperationContract]

        int Add(int a, int b);

 

        [OperationContract]

        int Sub(int a, int b);

    }

}

Service:
 

namespace Service

{

    public class Calc : ICalc

    {

        public int Add(int a, int b)

        {

            return a + b;

        }

 

        public int Sub(int a, int b)

        {

            return a - b;

        }

    }

}

 

 
Host - Config:
 

  <system.serviceModel>

    <services>

      <service name="Service.Calc" >

        <endpoint address="http://localhost:8412/MyCalcService"

                  binding="basicHttpBinding"

                  contract="Contarcts.ICalc"></endpoint>

      </service>

    </services>

  </system.serviceModel>

 
Host - Code:
 

namespace Host

{

    class Program

    {

        static void Main(string[] args)

        {

            ServiceHost calcHost = new ServiceHost(typeof(Calc));

            calcHost.Open();

 

            Console.ReadLine();

        }

    }

}

 

 
כשהקשרים בינייהם נראים כך:
יש לנו שלושה פרוייקטים, Contract, Service, Host
Contract לא מכיר אף אחד ויש לו Reference ל - System.ServiceModel
Service מכיר את Contract
Host מכיר את שניהם  ויש לו Reference ל - System.ServiceModel
 
אחרי שהחלק הזה קיים, ניתן להריץ את ה - host והוא מחכה לפניות, ברגע שהוא יקבל פניה שמתאימה לאחת מהמתודות שנחשפו דרך ה - Contract הוא יפעיל אותם.
 
כעת נגש לצד הלקוח.
 
 
מה Client צריך לעשות כדי לתקשר עם ה - Service
כדי שלקוח יוכל לפנות לשירות הוא צריך להכיר את ההגדרות של ה - Endpoint שה - Service נחשף דרכו, הוא צריך לדעת באיזה כתובת כמובן ה - Service מאזין ובאיזה פרוטוקולים הוא מוכן לקבל בקשות וכמובן עליו לדעת מה ה - Contract כלומר אילו מתודות אפשר להפעיל.
 
יצירת Client ראשון בעזרת ChannelFactory
למעשה יש שתי דרכים להגדיר את הלקוח כדי שהוא יוכל לעבוד עם השירות המרוחק, אחת אוטומטית ואחת ידנית, נתחיל עם הידנית:
הלקוח יכול לתקשר עם השירות בעזרת מחלקה מיוחדת הנקראת ChannelFactory, אנחנו נשתמש בה במידה ויש לנו Reference ישיר לפרוייקט ה - Contract (וזה אחת הסיבות שמומלץ להפריד בין הפרוייקטים של ה - Service לבין ה - Contract - מכיון שרק כך הלקוח יכול להחזיק Reference ל - Contract).
 
נייצר פרוייקט חדש מסוג Console Application ונקרא לו בשם ClientWithChannelFactory.
נוסיף לו Reference לפרוייקט של ה - Contract.
ונכתוב בקונפיג קוד מאוד דומה למה שכתבנו בפרוייקט של ה - Host
 

  <system.serviceModel>

    <client>

      <endpoint name="calcEndpoint"

              address="http://localhost:8412/MyCalcService"

              binding="basicHttpBinding"

              contract="Contarcts.ICalc"></endpoint>

    </client>

  </system.serviceModel>

 

אפשר לראות שה - Endpoint מוגדר באותה צורה שבה ה - Host הגדיר, ההבדל היחיד הוא שכאן ה - Endpoint עטוף באלמנט client וב - Host הוא היה עטוף באלמנט service.
בנוסף כאן ה - Endpoint קבל ערך למאפיין name - מיד נבין למה.
 
כעת נכתוב את הקוד הבא
 

namespace Client

{

    class Program

    {

        static void Main(string[] args)

        {

            ChannelFactory<ICalc> channel = new ChannelFactory<ICalc>("calcEndpoint");

            ICalc proxy = channel.CreateChannel();

 

            int res = proxy.Add(2, 4);

 

            channel.Close();

        }

    }

}

 
נשתמש במחלקה ChannelFactory כדי לייצר מופע שמתייחס ל - ICalc, בבנאי שלו הוא מקבל את השם של ה - Endpoint, לאחר מכן נשתמש במתודה CreateChannel כדי לקבל מופע של ICalc.
ונוכל להתחיל להשתמש במתודות - כמובן שה - Host חייב להיות באויר בזמן שמבצעים את השורות האלו.
 
 
יצירת Client שני בעזרת Service Reference
הרבה פעמים אין לנו Reference ישיר מהפרוייקט של ה - Client ל - Contract (או שאנחנו מתעצלים לכתוב לבד) ואנחנו רוצים שזה יקרה בצורה אוטומטית.
 
אפשר להשתמש בשירות של Visual Studio שנקרא Service Reference כדי לקבל את ה - Proxy, כדי לעשות זאת ה - Host שלנו חייב לחשוף את ה - wsdl (מסמך xml המתאר את השירות), נחזור לפרוייקט של ה - Host ונוסיף בקונפיג את הקוד הבא (מיד אחרי שהאלמנט services נסגר)
 

<behaviors>

  <serviceBehaviors>

    <behavior>

      <serviceMetadata httpGetEnabled="true"

                      httpGetUrl="http://localhost:8412/MyCalcService/Help"/>

    </behavior>

  </serviceBehaviors>

</behaviors>

 
בפרק הבא אני אסביר על המושג behaviors - כרגע כל מה שאני אגיד שמדובר בהגדרות שונות על השירות שאנחנו חושפים.
 
כעת נוסיף פרוייקט חדש מסוג Console Application ונקרא לו ClientWithServiceReference
בשלב הזה אנחנו חייבים להריץ את ה - Host (כדי ש - Visual Studio יוכל לקבל את קובץ ה - wsdl)
 
נלחץ קליק ימין על Add Reference בפרוייקט החדש ונבחר ב - Add Service Reference.
בתיבת הטקסט נוסיף את ה - url הבא - http://localhost:8412/MyCalcService/Help (הוא אותו כתובת שחשפנו במאפיין httpGetUrl)
נלחץ על GO ולאחר שהוא הוא ימצא את השירות, נכתוב בתיבת הטקסט (למטה) את השם CalcProxy.
 
Add Service Reference
 
 
כשנלחץ OK - הוא יצור עבורנו Proxy וכעת נוכל לכתוב את הקוד הבא:
 

namespace ClientWithServiceReference

{

    class Program

    {

        static void Main(string[] args)

        {

            CalcClient proxy = new CalcClient();

            int res = proxy.Add(2, 4);

        }

    }

}

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

<system.serviceModel>

    <bindings>

        <basicHttpBinding>

            <binding name="BasicHttpBinding_ICalc" closeTimeout="00:01:00"

                openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"

                allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"

                maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"

                messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"

                useDefaultWebProxy="true">

                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"

                    maxBytesPerRead="4096" maxNameTableCharCount="16384" />

                <security mode="None">

                    <transport clientCredentialType="None" proxyCredentialType="None"

                        realm="" />

                    <message clientCredentialType="UserName" algorithmSuite="Default" />

                </security>

            </binding>

        </basicHttpBinding>

    </bindings>

    <client>

        <endpoint address="http://localhost:8412/MyCalcService" binding="basicHttpBinding"

            bindingConfiguration="BasicHttpBinding_ICalc" contract="CalcProxy.ICalc"

            name="BasicHttpBinding_ICalc" />

    </client>

</system.serviceModel>

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

<system.serviceModel>

  <client>

    <endpoint address="http://localhost:8412/MyCalcService"

              binding="basicHttpBinding"

              contract="CalcProxy.ICalc"

              name="BasicHttpBinding_ICalc" />

  </client>

</system.serviceModel>

שזה די דומה למה שאנחנו עשינו.
 
 
 
בפרק הבא נכנס קצת יותר לעומק למושגים Binding ו - Behaviors
Posted: Dec 30 2010, 08:50 AM by Shlomo | with 9 comment(s)
תגים:,

WCF (Windows Communication Foundation) for Beginner - part 2

 

ללמוד WCF פרק 2 - להרים Services לאויר (Hosting)
 
דוגמת הקוד של הפרק - להורדה
 
רשימת נושאים בפרק 2:
סיכום דוגמת קוד להגדרה של Service מהפרק הקודם.
מי מחזיק את השירות באויר.
מה זה Endpoint.
הגדרה של Endpoint בקונפיג.
מה זה Binding.
הגדרה של Service Host והרמת השירות הראשון שלנו לאויר.
 
 
סיכום דוגמת קוד להגדרה של Service מהפרק הקודם
אז בפרק הקודם דברנו על ההגדרה של שירות והכרנו את המושגים ServiceContract ו - OperationContract והנה לנו דוגמא להגדרה של שירות המבצע חישובים.
 
ראשית יש לנו פרוייקט אחד בשם Contract המכיל את ה - Interface שאותו נחשוף החוצה (הפרוייקט צריך להכיל Reference ל - System.ServiceModel)
 
 

namespace Contarcts

{

    [ServiceContract]

    public interface ICalc

    {

        [OperationContract]

        int Add(int a, int b);

 

        [OperationContract]

        int Sub(int a, int b);

    }

}

 
לאחר מכן בפרוייקט נפרד נכתוב מימוש לאותו Interface (הפרוייקט צריך להכיל Reference לפרוייקט Contract)
 

namespace Service

{

    public class Calc : ICalc

    {

        public int Add(int a, int b)

        {

            return a + b;

        }

 

        public int Sub(int a, int b)

        {

            return a - b;

        }

    }

}

 
עד כאן מהשיעור הקודם.
 
 
מי מחזיק את השירות באויר
לאחר שיש לנו Contract ומימוש שלו ב - Service אנחנו צריכים לחשוב מה הלאה, ברור שכרגע ה - Service הוא בסך הכול מחלקה המממשת ממשק כלשהו, כדי שהוא יהיה באוויר ויהיה ניתן לתקשר איתו ולהפעיל את המתודות שלו, מישהו צריך לארח אותו ולהחזיק אותו בחיים, המישהו הזה נקרא Host.
 
Host יכול להיות כל אפליקציה שרצה ב - Windows החל מ - Console Application או Windows Forms Application ואפילו IIS, כל מה שצריך לעשות, זה להגדיר ל - Host מספר הגדרות כגון באיזה פרוטוקול הוא מאזין (http, tcp ועוד) מה הכתובת שאליו הוא מאזין ועוד מספר הגדרות שנכיר בפרק הזה ובפרקים הבאים.
 
 
מה זה Endpoint
כדי שנוכל לספר ל - Host שהשירות מתאכסן אצלו מה אנחנו רוצים לעשות - אנחנו צריכים להגדיר Endpoint.
 
Endpoint - מכיל את שלושת ההגדרות הבאות:
Address - שמספר מה הכתובת שה - Host מאיזן לקבל בקשות ולהעביר אותם לשירות.
Binding - שמגדיר הגדרות חשובות, כמו באיזה פרוטוקל נשתמש, האם נעביר מידע טקסטואלי או בינארי הגדרות Security ועוד.
Contract - המספר לעולם איזה Interface מוחצן החוצה מהשירות.
 
למעשה אפשר להגיד שה - Endpoint מספר היכן (Address) למצוא את השירות שזה הכתובת שלו, איך (Binding) שזה מספר כיצד לבצע את ההתקשרות, ומה (Contract) שמספר מה השירות מספק.
 
 
הגדרה של Endpoint בקונפיג
למעשה אפשר להגדיר Endpoint מקוד או מקובץ הקופיג של ה - Host, בדוגמאות אני אצמד לקובץ הקונפיג.
 
נוסיף פרוייקט חדש בשם Host מסוג Console Application ונוסיף לו Reference לשני הפרוייקטים שלנו וכמובן גם ל - System.ServiceModel)
נוסיף קובץ קונפיג ונכתוב את הקוד הבא
 

<system.serviceModel>

  <services>

    <service name="Service.Calc" >

      <endpoint address="http://localhost:8412/MyCalcService"

                binding="basicHttpBinding"

                contract="Contarcts.ICalc"></endpoint>

    </service>

  </services>

</system.serviceModel>

 
כל ההגדרות בקונפיג אודות WCF יושבות תחת system.serviceModel
 
היות ש - host אחד יכול להכיל יותר משירות אחד אנחנו צריכים עבור כל שירות להגדיר מקטע של service שהמאפיין name הוא השם המלא של השירות (כלומר namespace.className)
 
לאחר מכן נפתח מקטע של endpoint ונגדיר את ההגדרות שיעזרו ל - host להאזין לבקשות, נגדיר כמובן address כשהקידומת (http) היא יוצא פועל של סוג ה - binding, כמו שאפשר לראות בדוגמא בחרתי ב - basicHttpBinding ולכן גם הקידומת של הכתובת תתחיל ב - http.
בנוסף נגדיר מה ה - contract שאותו השירות חושף, שהוא יהיה השם המלא של ה - interface כלומר (namespace.interfaceName)
 
למעשה זה כל מה שצריך כדי להגדיר host בסיסי, בפועל כמובן שיש עוד הרבה הגדרות שונות, למשל בדוגמא השתמשתי ב - basicHttpBinding כלומר רציתי שהתקשורת תעשה בפרוטוקול http פשוט בלי יותר מידי פיצ'רים כמו שמירה על Session ועוד.
ויש עוד רשימה ארוכה של Bindings מוגדרים מראש (כל אחת והתכונות שלה) בנוסף אפשר לשנות הגדרות של כל Binding (מה שנתמך) ואם זה לא מספיק אפשר לייצר אחד כזה לבד, אנחנו נתעמק ב - Binding בפרקים הבאים.
 
 
 
הגדרה של Service Host והרמת השירות הראשון שלנו לאויר
כעת כל מה שנשאר לנו לעשות זה להרים את השירות שלנו לאויר, נוסיף ל - host את הקוד הבא
 

static void Main(string[] args)

{

    ServiceHost calcHost = new ServiceHost(typeof(Calc));

    calcHost.Open();

 

    Console.ReadLine();

}

 
המחלקה ServiceHost מקבלת את סוג השירות, ומתחילה להאזין - את שאר הקונפיגורציה (איך להאזין איך התקשורת מתבצעת וכו') לוקחים בצורה אוטומטית מקובץ הקונפיג.
כמובן שצריך לכתוב שורה כמו ReadLine כדי לגרום ל - host להישאר באוויר.
 
יש חלק מה - hosts (כמו IIS) שלא צריך לקרוא ל - open, אנחנו נדבר עליהם בפוסטים הבאים.
 
 
בפרק הבא אנחנו נגדיר גם את הצד השני (Clients) ונראה כיצד התקשורת אכן עובדת.
Posted: Dec 29 2010, 02:31 PM by Shlomo | with 9 comment(s)
תגים:,

WCF (Wndows Communication Foundation) for Beginner - part 1

הקדמה:
כרגיל כמו בנושאים אחרים אין ברשת פוסטים בעברית המסבירים WCF למתחילים מהנקודה הראשונה ועד הנושאים המעמיקים.
בתקופה הקרובה אני אשתדל לפרסם מידי יום פרק נוסף על WCF ואני מקווה שסדרה זו תואיל לאנשים המחפשים מידע על WCF.
 
למי שלא יודע מה זה WCF, לפני שנתחיל נעשה יישור קו קטן, WCF זה ראשי תיבות של Wndows Communication Foundation, הרבה לפני ש - WCF הגיע לאויר העולם יכולנו לכתוב אפליקציות מבוזרות - כלומר - אפליקציות שבצד אחד יש לקוח ובצד שני יש שרת והם מתקשרים ביניהם, התקשורת התבצעה במגוון דרכים , הפופולרית היא כמובן WebService אבל יש עוד הרבה דרכים כמו Remoting ואחרים, כמובן שבכל צורת תקשורת צריך לבחור את הפרוטוקול ולכל צורת תקשורת יש את היתרונות והחסרונות שלה, החל מניהול תהליכים עד לעניני Security.
 
WCF זה לא המצאה חדשה או דרך חדשה ליצירת תקשורת בין מחשבים, זה בא פשוט לעשות סדר בבלגן ולתת דרך אחת שבה אנו כמפתחים יוצרים תקשורת בין מחשבים ובצורה מאוד פשוטה על ידי הגדרות בקונפיג או מקוד נוכל להחליט מה היא צורת ההתקשרות ובאיזה פרוטוקול ומה הם התכונות שיש בתקשורת.
 
כמובן שזה נשמע פשוט מאוד, אך בפועל למי שלא מכיר WCF קובץ הקונפיג יכול להיות סיבוך אחד גדול, ולכן בסדרת פוסטים זאת ,אני אנסה לתת הסבר פשוט על מה זה ואיך משתמשים ב - WCF.
 
 
ללמוד WCF פרק 1 - מה זה Service ומה זה Contract.
 
 
רשימת נושאים בפרק 1:
מה המשמעות של Service.
מה זה Contract ומה ההבדל בין ServiceContract לבין OperationContract.
כיצד מתחילים לכתוב Service.
מה זה DataContract ומה זה DataMember.
 
 
מה המשמעות של Service.
כדי לכתוב שירות כלשהו בשרת שלקוחות יוכלו לפנות אליו ולהפעיל אותו, אנחנו צריכים כמובן לכתוב אחד כזה, Service הוא בסך הכול מחלקה שמממשת מתודות שהוחלט מראש שהשירות הזה צריך לממש.
למשל - נניח שאננו רוצים שירות של מחשבון נצטרך לממש מתודה שמקבלת שני מספרים ומחזירה מספר.
 
מה זה Contract ומה ההבדל בין ServiceContract לבין OperationContract.
בחיים אנו כותבים הרבה מחלקות שיש להם פונקציונליות כלשהו, ברור שלא כל אחד מאותם מחלקות הוא Service שכל אחד יכול לגשת ולהפעיל אותו, כדי שמחלקה מסוימת תוכר כשירות היא צריכה לממש Contract.
Contract זה בסך הכול מילה אחרת ל - Interface, למעשה אנחנו צריכים להגדיר Interface שמחצין את אותם מתודות שיהיה ניתן להפעיל מרחוק, כמובן שלא כל Interface מוכר כ - Contarct שמייצא שירותים החוצה, כדי להגדיר שה - Interface הוא WCF Contract צריך להוסיף מעל ה - Intreface את ה - Attribute של ServiceContarct, למשל
 

[ServiceContract]

public interface ICalc

{

 

}

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

[ServiceContract]

public interface ICalc

{

    [OperationContract]

    public int Add(int a, int b);

}

 
כיצד מתחילים לכתוב Service.
בשלב ראשון צריך להגדיר את ה - Contract, מאוד מומלץ לעשות את זה בפרוייקט נפרד (Assembly) ולא לכתוב באותו פרוייקט גם את ה - Contract וגם את המימוש שלו.
 
לאחר מכן צריך לממש את ה - Contract, נוסיף פרוייקט חדש ואחד מהמחלקות צריך לממש את ה - Interface, למעשה זה כל מה שצריך לעשות - תיאורטית המימוש לא צריך לדעת שהוא WCF Service, בחיים האמיתיים זה לא בדיוק ככה ולרוב המחלקה שמממשת את ה - Contract צריכה לדעת מידע על סוג השירות, נדבר על הנושא בפוסטים אחרים.
 
 
מה זה DataContract ומה זה DataMember.
לפעמים המתודות שמוגדרות ב - Contract צריכות לקבל או להחזיר אובייקטים, למשל:
 

[ServiceContract]

public interface ICalc

{

    [OperationContract]

    public int Add(int a, int b);

 

    [OperationContract]

    public int Add2(Dolar a, Shekel b);

}

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

[DataContract]

public class Dolar

{

    [DataMember]

    public int Value { get; set; }

}

 

[DataContract]

public class Shekel

{

    [DataMember]

    public int Value { get; set; }

}

 
למעשה כל אובייקט (שלנו) שנרצה להעביר ב - WCF צריך את ה - Attribute של DataContract ובנוסף כל מאפיין של אותו מחלקה שנרצה שיעבור בין הלקוח לשרת צריך להוסיף לו DataMember.
 
 
בחלק הבא - אסביר כיצד מארחים שירות של WCF ברשת כך שלקוחות יוכלו אכן לפנות אליו.
Posted: Dec 28 2010, 09:37 AM by Shlomo | with 11 comment(s)
תגים:,

InvalidRegistryStoreValueException: Could not retrieve the solution identified by the following subscriptionId

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

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

 

Microsoft.VisualStudio.Tools.Applications.Deployment.InvalidRegistryStoreValueException: Could not retrieve the solution identified by the following subscriptionId: Reporter.vsto, Culture=neutral, PublicKeyToken=8544e63e2a5abba0, processorArchitecture=msil. The subscriptionId was found but one or more of the identifying properties is corrupted or missing. ---> Microsoft.VisualStudio.Tools.Applications.Deployment.InvalidRegistryStoreValueException: Some values for current solution configuration are invalid in the registry ---> System.ArgumentNullException: Value cannot be null. Parameter name: value at System.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument) at System.BitConverter.ToInt64(Byte[] value, Int32 startIndex) at Microsoft.VisualStudio.Tools.Applications.Deployment.StoreEntryRegistryHelper.LoadFrom(RegistryKey source) --- End of inner exception stack trace --- at Microsoft.VisualStudio.Tools.Applications.Deployment.StoreEntryRegistryHelper.LoadFrom(RegistryKey source) at Microsoft.VisualStudio.Tools.Applications.Deployment.MetadataStore.Retrieve(String subscriptionID) --- End of inner exception stack trace --- at Microsoft.VisualStudio.Tools.Applications.Deployment.MetadataStore.Retrieve(String subscriptionID) at Microsoft.VisualStudio.Tools.Applications.Deployment.ClickOnceAddInDeploymentManager.VerifySolutionCodebaseIsUnchanged(Uri uri, String subscriptionId, Boolean previouslyInstalled) at Microsoft.VisualStudio.Tools.Applications.Deployment.ClickOnceAddInDeploymentManager.InstallAddIn()
 
 
למעשה חיפוש של השגיאה בגוגל עם הודעת השגיאה מחזיר אפס תוצאות - כנראה שהיינו הראשונים בעולם עם השגיאה הזאת, בכל מקרה התחלתי לחפש ב - registry את שם האפליקציה ובסוף החיפוש מצאתי את הערך הבא:
 
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Microsoft\VSTA\Solutions\8f614cce-c8e3-43e8-9236-9646884a71b9] "
Url"="file://Reporter/Reporter.vsto" "
SubscriptionID"="Reporter.vsto, Culture=neutral, ...., processorArchitecture=msil" "
ApplicationID"="file://Reporter.vsto#eporter.vsto, .....,
processorArchitecture=msil/Reporter.dll, Version=1.0.0.51,....,
processorArchitecture=msil, type=win32" "
SolutionID"="歶 ”"
"UpdateEnabled"=dword:00000001
"UpdateEnabled"=dword:00000001
"UpdateIntervalUnits"="days"
 
 
כמו שאפשר לראות יש מאפיין בשם SolutionID שיש לו ערך לא ברור, מחקתי את כל הערך מעורך הרישום, הרצתי התקנה ובא לציון גואל.
 
לא ברור לי לחלוטין מה היה שם, אני רק יכול להניח שהתקינו פעם אחת את האפליקציה וההתקנה הפסיקה באמצע התהליך ולכן הערכים נכנסו בצורה מעוותת.

#if DEBUG in javascript

 

כיצד לדעת האם האפליקציה בשלבי פיתוח או שהיא בשרת - בצד הלקוח

 
באתר "ערוץ השידורים של מכללת סלע" רציתי לדעת האם אני במוד DEBUG או לא.
 
ראיתי פוסט של פיני בנושא, אבל להשתמש עם Sys.Debug עושה לי כמה בעיות.
ראשית הוא עובד רק במידה ומגדירים את המאפיין ScripMode ל - Debug או ל - Release, במידה וזה מוגדר ב - Auto המאפיין isDebug בצד הלקוח תמיד מחזיר true,
 
בנוסף אצלי זה מוגדר תמיד ב - Release בגלל הבעיה שתארתי כאן.
 
 
כדי שאוכל לדעת באיזה מוד האפליקצייה נמצאת כתבתי את הקוד הבא:
 

        protected void Page_Load(object sender, EventArgs e)

        {

#if DEBUG

        string DEBUG =  "var DEBUG=true; ";

#else

        string DEBUG = "var DEBUG=false; ";

#endif

 

            ClientScript.RegisterClientScriptBlock(GetType(), "key", DEBUG, true);

        }

 
 
כעת בצד הלקוח אפשר לכתוב את הקוד הבא
 

<script type="text/javascript">

    if (DEBUG) {

    }

    else {

    }

</script>

הוספה של פונט מקוד

 

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

PrivateFontCollection MyFonts = new PrivateFontCollection();

FontFamily UnicodeArial;

 

MyFonts.AddFontFile(@"..\..\Resources\ARIALUNI.TTF");

UnicodeArial = MyFonts.Families[0];

Posted: Dec 16 2010, 09:17 AM by Shlomo | with 6 comment(s)
תגים:,

Rcycling application pool programmatically

 

כיצד אפשר להפעיל את פעולת ה - restart על application pool מקוד.

 
מצאתי ב - Code Project את התשובה.
 
כל מה שצריך לעשות זה להוסיף reference ל - System.DirectoryServices ולכתוב את הקוד הבא
 
DirectoryEntry w3svc = new DirectoryEntry(string.Format("IIS://{0}/W3SVC/AppPools/appPool Name", Environment.MachineName));
w3svc.Invoke("Recycle", null); 
 
וזה הכול
Posted: Dec 15 2010, 09:45 PM by Shlomo | with 2 comment(s)
תגים:,

Sela College Channel in The Marker

 

ערוץ השידורים של סלע הידוע בכינויו SCC סוקר ב - The Marker
 
 
לקריאת הכתבה:
Posted: Dec 14 2010, 04:12 PM by Shlomo | with 2 comment(s)
תגים:, ,

Sela College Channel (beta) is up and running

 

ערוץ מכללת סלע יוצא לדרך.

 
אני שמח לבשר כמו שכתבתי בעבר שמכללת סלע יוצאת עם פרוייקט ערוץ אינטרנט שישדר תוכניות על נשואים הקשורים למחשבים (בעיקר פיתוח ובדיקות כמובן), וכמו כן יספק שירות לקהילה וייתן את האפשרות לכל אחד להעלות הרצאות בעצמו למערכת (דורש רישום קצר).
 
הנה הלינקים למערכת:
 
 
 
 
הלינק הישיר למערכת הוא: http://scc.sela.co.il/scc - במקרה שתגלשו ללינק הזה המערכת תנסה לזהות בצורה אוטומטית את השפה הרצוייה, והיות שהערוץ האנגלי מביא תוצאות שונות מהערוץ העברי, אני ממליץ לעבוד עם הלינקים הישירים לעברית או לאנגלית, אחרי הפעם הראושנה המערכת תזכור את הבחירה שלכם ותוכלו להכנס עם הלינק הישיר.
 
 
המערכת היא כמובן בבטא ואשמח לקבל כל פידבק עליה. (אפשר לשלוח מיילים ל - scc@sela.co.il)
Posted: Dec 12 2010, 11:35 AM by Shlomo | with 4 comment(s)
תגים:,

פתיחת PopUp בפעם השניה לא מגיעה לשרת

כיצד לגרום ל - Post Back בכל פעם שפותחים Pop Up מצד הלקוח.

 
 
כשמשתמשים במתודה showModalDialog ב - Java Script - בפעם הראשונה החלון נפתח ויש ריצה לשרת, אך בפעמים הבאות החלון נשמר אצל הלקוח ואין ריצה לשרת.
 
במקרים שאתם רוצים בכל זאת לרוץ לשרת בכל פעם תצטרכו להוסיף את השורה הבאה (ב - Page_Load)
 

Response.Cache.SetCacheability(HttpCacheability.NoCache);