Tags: | Categories: C#, linq Posted by talgiladi on 5/25/2011 2:08 PM | Comments (0)

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

var accounts= table.Rows.Cast<DataRow>().Select(a => Convert.ToInt32(a["CustomerId"], CultureInfo.InvariantCulture));

עכשיו כדי למצוא כמה פעמים מופיע כל ערך ברשימה, נשתמש ב LINQ פשוט:

var items = accounts.GroupBy(a => a);
                    foreach (var group in items)
                    {
                     
                        int customerId= group.Key;
                        int numberOfActions= group.Count();

 }

 

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags: | Categories: C# Posted by talgiladi on 5/25/2010 2:03 PM | Comments (0)
  1. Find the path to the 'InstallUtil.exe' program. It should be found on the .NET framework path, usually on 'C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727'
  2. Browse to the directory with your service files
  3. Open a command prompt
  4. To install, write the 'InstallUtil' path and 'MyService.exe'. For example : "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe" MyService.exe
  5. To uninstall, write the 'InstallUtil' path, /u , and 'MyService.exe'. For example : "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe" /U MyService.exe

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags: | Categories: C# Posted by talgiladi on 10/3/2008 8:47 PM | Comments (5)

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

הבשורה הרעה שכולנו לא אוהבים לשמוע, זה שצריך להוריד משהו מהאינטרנט... כן, זה עדיין לא בא בתור סטנדרט בתוך הפריימוורק, אולי בעתיד...
אז תגשו לגוגל ותחפשו wse, בפעם האחרונה שבדקתי הגירסה הייתה 3.0 ולינק ההורדה ממיקרוסופט הוא כאן
לאחר ההתקנה יהיו לכם כמה דוגמאות קוד והוראות שימוש די נוחות...
הדבר הראשון שצריך לעשות אם אנחנו רוצים להשתמש בחתימה דיגיטלית זה להתקין מפתח אסימטרי.
למזלנו הקובץ מגיע עם 4 מפתחות לצורך הדוגמה, והדבר היחיד שצריך לעשות זה להריץ את הקובץ setup.bat שנמצא בתוך ספריית ההתקנה, בתוך ספריית samples, רק שימו לב שצריך לפתוח את שורת הפקודה של ויזואל סטודיו קודם:

cmd

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

אם ממש בא לראות אותן, ניתן להקיש בשורת הפקודה mmc כדי לפתוח את הקונסול, אחר כך להקיש על file->Add/Remove snap in->Add->certificates->Add
ואז תראו שם את כל המפתחות שמותקנות אצלכם על המחשב מהגלישה באינטרנט... אלו שעכשיו התקנו -  אחת מופיע תחת personal , עוד אחת תחת other people ועוד 2 איפשהו שם...

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

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

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

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

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

הגדרת צד השרת

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

    openConfiguration

    אבל אז תצטרכו למקם את הקובץ שנוצר לבד בתוך תיקיית האתר שלכם)

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

    enableWSE
  3. בטאב ה security בחלק של seucrity tokens manager נוסיף מנהל חדש על ידי לחיצה על add

    AddToken

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

  4. אנחנו צריכים לעשות זה ליצור מחלקה שאליה יעביר ה wse את שם המשתמש, והיא תחזיר לו את הסיסמה
    כדי שהוא יוכל לבדוק את החתימה הדיגיטלית. המחלקה הזאת במצב רגיל מן הסתם תמשוך את המידע מדטה בייס או קובץ.
    את שם המחלקה, שעוד מעט נראה איך ליצור, אנו כותבים בתיבת הטקסט Type. אני קראתי למחלקה UserNameTokenHandler

    UserNameTokenHandler

    תקליקו על אישור

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

    יש לסמן צ'ק בוקס בשם Allow test roots
    allowTestRoots


  6. עלינו ליצור קובץ שיכיל את ה Policy. הקובץ הזה מכיל הגדרות שונות לגבי החתימה הדיגיטלית. אתם יכולים להעתיק את הקובץ מספריית הדוגמאות שהגיעה עם התקנה ה wse, שם הקובץ הוא wse3policyCache.config והתוכן שלו הוא

    <policies xmlns="http://schemas.microsoft.com/wse/2005/06/policy">

      <extensions>

        <extension name="usernameForCertificateSecurity" type="Microsoft.Web.Services3.Design.UsernameForCertificateAssertion, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

        <extension name="x509" type="Microsoft.Web.Services3.Design.X509TokenProvider, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

        <extension name="requireActionHeader" type="Microsoft.Web.Services3.Design.RequireActionHeaderAssertion, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

      </extensions>

      <policy name="ServerPolicy">

        <usernameForCertificateSecurity establishSecurityContext="false" requireSignatureConfirmation="false" messageProtectionOrder="SignBeforeEncrypt" requireDerivedKeys="true" ttlInSeconds="300">

          <serviceToken>

            <x509 storeLocation="LocalMachine" storeName="My" findValue="CN=WSE2QuickStartServer" findType="FindBySubjectDistinguishedName" />

          </serviceToken>

          <protection>

            <request signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="true" />

            <response signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="true" />

            <fault signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="false" />

          </protection>

        </usernameForCertificateSecurity>

        <requireActionHeader />

      </policy>

    </policies>

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

    7. כעת נראה למנהל ה Policy  היכן ניתן למצוא את הקובץ. לכו לטאב של ה Policy, תסמנו את הצ'ק בוקס כדי לאפשר Policy, תקליקו על Browse ותמצאו את הקובץ הנ"ל.
    כעת תנו שם ל Policy. אצלנו השם הוא ServerPolicy
    AllowPolicy

    תלחצו על אישור
  7. בואו ניצור את המחלקה שתטפל בשם המשתמש:
    ניצור מחלקה בשם UserNameTokenHandler שתירש מהמחלקה UsernameTokenManager. נדרוס את הפונקציה AuthenticateToken שהחתימה שלה היא

    protected override string AuthenticateToken(UsernameToken token)


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

     protected override string AuthenticateToken(UsernameToken token)

        {

            if (token.Username == "talg")

            {

                return "mypassword";

            }

            else

            {

                return null;

            }

        }

     

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

    [Policy("ServerPolicy")]

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

    להורדת קוד והגדרות השרת

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

  1. ניצור פרוייקט, אני יצרתי אפליקציית קונסול.
  2. לחצן ימני על הגדרות פרוייקט-> wse settings
  3. לסמן את הצ'ק בוקס הראשון שמופיע, שבעצם מאפשר שימוש ב wse בפרוייקט הזה:

     enableWSEClient
  4. כעת ניצור הפנייה לווב סרביס בשרת שלנו על ידי הוספת web reference כרגיל. כעת לנקודה הכי חשובה! הפנייה רגילה לווב סרביס יורשת מהמחלקה SoapHttpClientProtocol , אנו צריכים לשנות כך שההפניה שלנו תירש מ WebServicesClientProtocol, שום שינוי אחר לא נדרש בקוד של ההפניה. רק שימו לב שכדאי לכם להוציא את ההפניה מהתיקיה של web references, אחרת כל פעם כשיבוצע עידכון הקוד הישן ימחק ותיצטרכו שוב לשנות את שם המחלקה.
  5. הפנייה בקוד לווב סרביס

    SecureWebService.WebService ws = new WebServiceClient.SecureWebService.WebService();

  6. יצירת מקבילה בקוד לקובץ הפוליסי שיצרנו בשרת:

     UsernameForCertificateAssertion assertion = new UsernameForCertificateAssertion();

  7. נגדיר עם איזו חתימה להשתמש, ואיך למצוא אותה

    assertion.X509TokenProvider = new X509TokenProvider(StoreLocation.CurrentUser,

                                                                    StoreName.AddressBook,

                                                                    "CN=WSE2QuickStartServer",

                                                                    X509FindType.FindBySubjectDistinguishedName);

  8. עוד הגדרה שמופיעה אצלנו בקובץ הפוליסי בשרת:

      assertion.RequireDerivedKeys = true;

  9. כעת נכניס את השם המשתמש והסיסמה:

    assertion.UsernameTokenProvider = new UsernameTokenProvider("talg", "mypassword");

  10. ונוסיף את הפוליסי לווב סרביס:

      Policy policy = new Policy();

                policy.Assertions.Add(assertion);

                ws.SetPolicy(policy);

  11. ונקרא לשירות:

     string result = ws.HelloWorld();

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

    להורדת קוד פרוייקט הלקוח
Technorati Tags:

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags: , | Categories: C# Posted by talgiladi on 6/3/2008 7:56 PM | Comments (6)

, לשם כך יש צורך ביצירת אתר חדש או ספריה וירטואלית חדשה (אלא אם כן השתמשתם בקאסיני...)
יוצא לפעמים שאנחנו צריכים להכין תוכנת התקנה של אתר ללקוחות הקוד לא ארוך ומסובך אבל מעצבן קצת.
קודם נוסיף הפניה לשם המתחם using System.DirectoryServices; שמשמש בעצם גם לגישה ל active directory. שימו לב שההפניה צריכה להיות דרך Add Reference :

addreferenceactivedirectory

כעת נפנה ל IIS:

 DirectoryEntry iisRoot = new DirectoryEntry("IIS://" +

                    serverUrl + "/W3SVC/1/Root");

כש serverUrl זו הכתובת של המחשב שעליו מתקינים, במקרה של התקנה אצל הלקוח זה בדרך localhost
כעת, מכיוון שאנחנו רוצים ליצור ספריה וירטואלית ולא ליצור אתר חדש, אנחנו צריכים הפניה לאיזה אתר קיים כבר, אני אפנה לאתר הדיפולטי ושם אצור את הספריה:

 DirectoryEntries defaultSite = iisRoot.Children; ;//default site

כעת ניצור את הספריה החדשה:

 DirectoryEntry newVirtualDirectory =  defaultSite.Add(virtualDirectoryName,iisRoot.SchemaClassName.ToString());//add new site

newVirtualDirectory.CommitChanges();

ו virtualDirectoryName הוא כמובן שם הספריה החדשה

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

newVirtualDirectory.Properties["Path"].Value = physicalPath;//the path to the files

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

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

newVirtualDirectory.Properties["AccessRead"][0] = false;

            newVirtualDirectory.Properties["AccessWrite"][0] = true;

            newVirtualDirectory.Invoke("AppCreate", true);

            newVirtualDirectory.Properties["AppFriendlyName"][0] = virtualDirectoryName;

ובסוף לשמור

newVirtualDirectory.CommitChanges();//save the changes

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

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

newVirtualDirectory = defaultSite.Find(virtualDirectoryName, oDE.SchemaClassName.ToString());

רק שימו לב שהפונקציה הזאת לא כל כך נחמדה, היא לא מחזירה null אלא זורקת exception אם לא נמצאה הספרייה, אז להקיף ב try catch בבקשה... תיהנו!

להורדת פרוייקט דוגמה

 

Technorati Tags: ,

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5