2007. augusztus havi bejegyzések

Dátumok standard módon

Aki az életben már legalább egyszer megnyerte azt a nemes feladatot, hogy egy weboldalhoz RSS feedet készítsen, biztosan belefutott a dátumformázással kapcsolatos macerákba. Az RSS 2.0 szabvány szerint a dátumoknak, például a pubDate mezőnek az RFC 822 "szabványt" (ami 1982. augusztus 13. óta létezik!) kell követniük:

All date-times in RSS conform to the Date and Time Specification of RFC 822, with the exception that the year may be expressed with two characters or four characters (four preferred).

Azaz például (szintén a szabványból):

Sat, 07 Sep 2002 00:00:01 GMT

Nézzünk egy kicsit jobban utána ennek, konkrétan az RFC 822 (STANDARD FOR THE FORMAT OF ARPA INTERNET TEXT MESSAGES) ötödik, Date and Time Specification fejezete foglalkozik a dátum- és idő formátummal. Nem hoszzú, idemásolom:

     5.  DATE AND TIME SPECIFICATION

     5.1.  SYNTAX

     date-time   =  [ day "," ] date time        ; dd mm yy
                                                 ;  hh:mm:ss zzz

     day         =  "Mon"  / "Tue" /  "Wed"  / "Thu"
                 /  "Fri"  / "Sat" /  "Sun"

     date        =  1*2DIGIT month 2DIGIT        ; day month year
                                                 ;  e.g. 20 Jun 82

     month       =  "Jan"  /  "Feb" /  "Mar"  /  "Apr"
                 /  "May"  /  "Jun" /  "Jul"  /  "Aug"
                 /  "Sep"  /  "Oct" /  "Nov"  /  "Dec"

     time        =  hour zone                    ; ANSI and Military

     hour        =  2DIGIT ":" 2DIGIT [":" 2DIGIT]
                                                 ; 00:00:00 - 23:59:59

     zone        =  "UT"  / "GMT"                ; Universal Time
                                                 ; North American : UT
                 /  "EST" / "EDT"                ;  Eastern:  - 5/ - 4
                 /  "CST" / "CDT"                ;  Central:  - 6/ - 5
                 /  "MST" / "MDT"                ;  Mountain: - 7/ - 6
                 /  "PST" / "PDT"                ;  Pacific:  - 8/ - 7
                 /  1ALPHA                       ; Military: Z = UT;
                                                 ;  A:-1; (J not used)
                                                 ;  M:-12; N:+1; Y:+12
                 / ( ("+" / "-") 4DIGIT )        ; Local differential
                                                 ;  hours+min. (HHMM)

     5.2.  SEMANTICS

          If included, day-of-week must be the day implied by the date
     specification.

          Time zone may be indicated in several ways.  "UT" is Univer-
     sal  Time  (formerly called "Greenwich Mean Time"); "GMT" is per-
     mitted as a reference to Universal Time.  The  military  standard
     uses  a  single  character for each zone.  "Z" is Universal Time.
     "A" indicates one hour earlier, and "M" indicates 12  hours  ear-
     lier;  "N"  is  one  hour  later, and "Y" is 12 hours later.  The
     letter "J" is not used.  The other remaining two forms are  taken
     from ANSI standard X3.51-1975.  One allows explicit indication of
     the amount of offset from UT; the other uses  common  3-character
     strings for indicating time zones in North America.

Hogyan lehetne ezt előállítani .NET-ben, hiszen nincs közvetlenül olyan dátumformátumunk, ami pont ilyen lenne. Próbáljuk összerakni:

    Console.WriteLine( DateTime.Now.ToString("ddd, dd MMM yyyy HH:mm:ss zzz") );

Ebből ez lesz a konzolon, ami nem éppen az igazi:

Cs, 30 aug. 2007 11:41:39 +02:00

Írhatunk hozzá hosszabb kódot, például így (vagy akár szebben is): 

    public static string ToRfc822String( DateTime date )
    {
        int offset = TimeZone.CurrentTimeZone.GetUtcOffset( DateTime.Now ).Hours;
        char sign = '+';

        if( offset < 0 )
        {
            sign = '-';
            offset = offset * -1;
        }

        string zone = ( sign + offset.ToString().PadLeft( 2, '0' ) ).PadRight( 5, '0' );
        return date.ToString( "ddd, dd MMM yyyy HH:mm:ss " + zone, CultureInfo.InvariantCulture );
    }

Külön figyelmet érdemel az InvariantCulture alkalmazása, enélkül ugyanis szép magyar hónap és nap nevek jönnének, mivel azonban a kultúra információkért felelős .NET fejlesztő csapat szerint, ha valami invariáns, akkor legyen angol, éppen rendben vagyunk:

Thu, 30 Aug 2007 11:05:13 +0200

Bár a fenti kódrészletet valószínűleg meg lehet írni szebben és tömörebben, rutinos .NET fejlesztő nehezen hiszi el, hogy erre nem gondoltak a keretrendszer fejlesztői és saját függvény írására vagyunk kárhoztatva. Alaposabban nézegetve az MSDN Standard DateTime Format Strings fejezetét feltűnhet egy formátum, ami kilóg a sorból:

R or r:  RFC1123 pattern

Represents a custom DateTime format string defined by the current RFC1123Pattern property. The pattern is a defined standard and the property is read-only. Therefore, it is always the same regardless of the culture used or the format provider supplied.

The custom format string is "ddd, dd MMM yyyy HH’:’mm’:’ss ‘GMT’".

Formatting does not modify the value of the DateTime object that is being formatted. Therefore, the application must convert the value to Coordinated Universal Time (UTC) before using this format specifier.

Hm, ez a formátum kísértetiesen hasonlít az RFC 822 formátumára, nézzük csak meg, hogy mit mond az 1989. októberéből származó RFC 1123, ami a "Requirements for Internet Hosts – Application and Support" címre hallgat! Ennek az 5.2.14 Date and Time Specification fejezete közvetlenül hivatkozik az RFC 822 Section 5-re, némi kiegészítéssel:

         The syntax for the date is hereby changed to:

            date = 1*2DIGIT month 2*4DIGIT

         All mail software SHOULD use 4-digit years in dates, to ease
         the transition to the next century.

         There is a strong trend towards the use of numeric timezone
         indicators, and implementations SHOULD use numeric timezones
         instead of timezone names.  However, all implementations MUST
         accept either notation.  If timezone names are used, they MUST
         be exactly as defined in RFC-822.

         The military time zones are specified incorrectly in RFC-822:
         they count the wrong way from UT (the signs are reversed).  As
         a result, military time zones in RFC-822 headers carry no
         information.

         Finally, note that there is a typo in the definition of "zone"
         in the syntax summary of appendix D; the correct definition
         occurs in Section 3 of RFC-822.

Tehát a különbségek:

  • 4 digites évszámokat kell használni
  • Számokkal kell leírni az időzónákat.

Ez kibírható, próbáljuk ki!

    Console.WriteLine( DateTime.Now.ToUniversalTime().ToString( "R" ) );

A kimenet pedig ez lesz:

Thu, 30 Aug 2007 09:23:15 GMT

A kérdés tehát: kell-e saját dátumformázó függvényt írnunk, vagy jó lesz a ToString("R") is?

A fentiek alapján elmondhatjuk, hogy a beépített dátumformátum megfelel az RSS előírásainak, tehát használható, sőt valószínűleg ez a legegyszerűbb megoldás. Ugyanakkor meg kell jegyeznünk, hogy a keretrendszer nem követi teljesen az RFC 1123-at, mert nem numerikus időzóna meghatározásokat használ.

 

Technorati tags: ,

E-mail küldés kódból

.NET-es kódból e-mailt küldeni nem éppen atomfizikusnak való feladat, mindenki hamar rájön, hogy milyen egyszerű spam gyárat írni a System.Net.Mail névtér segítségével:

    MailMessage msg = new MailMessage(
        "felado@example.com",
        "cimzett@example.com",
        "Próba levél tárgysora kódból",
        "Ide jön az érdekes tartalom..." );

    SmtpClient smtp = new SmtpClient( "mail.example.com" );
    smtp.Send( msg );

Ez eddig ment .NET 1.0-n is, ami viszont macerás volt, az a feladó és a címzettek megadása, amire a megoldást a .NET 2.0-ban megjelent MailAddress osztály hozta meg. Így már barátságosabban címezhetünk levelet:

    MailMessage msg = new MailMessage();
    msg.From = new MailAddress( "felado@example.com", "Feladó szép neve" );
    msg.To.Add( new MailAddress( "cimzett@example.com", "Címzett szép neve" ) );
    msg.Subject = "Próba levél tárgysora";
    msg.Body = "A tartalom helye...";

Ez mind szép, de a címzettel kár sokat erőlködni, egy Exchange Serverre kötött Outlook ragaszkodik az AD-ben lévő Display Name-hez. Egyébként pedig a webes levelező kliensek közül egyik-másik (pl. a Freemail biztosan) nem tud megbírkózni a címmezőkben lévő ékezetekkel, hiába adunk meg a MailAddress konstruktornak harmadik paraméterben egy Encodingot. Érdekes módon a Gmailnek meg se kottyan…

Ha már a címzetteknél járunk, bizony mindenkinek akadnak olyan levelezőpartnerei, akiknél nem ártana a kézbesítési és az olvasási nyugta használata. Örüljünk, mert kézbesítési nyugtát kérhetünk a DeliveryNotificationOptions tulajdonság használatával. Mivel ez flages enum bátran összevagyolhatjuk az egyes elemeit, például:

    msg.DeliveryNotificationOptions =
        DeliveryNotificationOptions.OnFailure |
        DeliveryNotificationOptions.OnSuccess;

Az olvasási nyugtára viszont nincs közvetlenül property, így nincs más lehetőségünk, mint kézzel beletúrni a fejléc mezőkbe:

    msg.Headers.Add( "Disposition-Notification-To", "felado@example.com" );

Ennyit a címzésről, lépjünk tovább a tartalomra, például legyen inkább HTML:

  msg.Body =
    "<html><body><h1>Hello Szivi!</h1>Hoztál <i>nekem</i> kismajmot?</body></html>";
  msg.IsBodyHtml = true;

Na ezt már nem sikerült elküldeni az Exchange-en keresztül:

Unhandled Exception: System.Net.Mail.SmtpException: Mailbox unavailable. The server response was: 5.7.1 Requested action not taken: message refused

A finnyás mindenit, túl spam gyanúsnak találta a levelet, ezért kénytelen voltam a lokális SMTP szerveremen keresztül elküldeni. Mert XP-n még van olyan, Vistán nincs, de majd a Windows Server 2008-ban lesz.

Az AlternateView osztály segítségével még arra is van lehetőségünk, hogy egyetlen levélben különböző formátumokban küldjük el a mondandónkat.

    string htmlBody =
      "<html><body><h1>Hello Szivi!</h1>Hoztál <i>nekem</i> kismajmot?</body></html>";
    string textBody = "Szia Szivi! Hoztál nekem kismajmot?";

    AlternateView htmlView = AlternateView.CreateAlternateViewFromString(
        htmlBody, Encoding.Default, MediaTypeNames.Text.Html );
    msg.AlternateViews.Add( htmlView );

    AlternateView textView = AlternateView.CreateAlternateViewFromString(
        textBody, Encoding.Default, MediaTypeNames.Text.Plain );
    msg.AlternateViews.Add( textView );

Ez (legalább) két ok miatt érdekes:

  1. Az AlternateView osztálynak van olyan konstruktora, amelyet fájl név vagy stream megadásával használhatunk, ha tehát nem változik a szöveg, akkor egyszerűen felnyalhatjuk fájlrendszerből.
  2. Így van lehetőségünk arra, hogy a HTML változathoz – és csak ahhoz – képet fűzzünk. Nosza!
    string htmlBody =
      @"<html><body><h1>Képes</h1><img src=""cid:Kep1""></body></html>";

    AlternateView htmlView = AlternateView.CreateAlternateViewFromString(
        htmlBody, Encoding.Default, MediaTypeNames.Text.Html );

    LinkedResource pic = new LinkedResource(
        @"C:\WINDOWS\Web\Wallpaper\Crystal.jpg", MediaTypeNames.Image.Jpeg );
    pic.ContentId = "Kep1";
    htmlView.LinkedResources.Add( pic );

    msg.AlternateViews.Add( htmlView );

Aláhúztam a trükkös részeket, a ContentId tulajdonságra kell figyelni, és az IMG elem SRC attribútumában cid:ContentId formátumban hivatkozhatunk a képre.

Így már persze jó nagy leveleket fogunk küldözgetni, nem is fog gyorsan menni. Küldjük hát aszinkron módon, mert 2.0-ban már azt is lehet:

    smtp.SendCompleted += new SendCompletedEventHandler( OnSendCompleted );
    smtp.SendAsync( msg, "Levél a Kedvesnek" );

A küldés eredményét pedig egy eseménykezelővel tudhatjuk meg:

    static void OnSendCompleted( object sender, AsyncCompletedEventArgs e )
    {
        string state = e.UserState as string;
        if( e.Cancelled )
        {
            Console.WriteLine( @"""{0}"" küldése megszakítva.", state );
        }
        if( e.Error != null )
        {
            Console.WriteLine( @"Hiba a ""{0}"" küldése közben: {1}",
              state, e.Error.Message );
        }
        else
        {
            Console.WriteLine( @"A ""{0}"" elküldve.", state );
        }
    }

A teljességhez hozzátartozik, hogy az SmtpClient.SendAsyncCancel() metódus hívásával leállíthatjuk a levél elküldését. Ezt jelenlegi formájában a valóságban aligha fogjuk használni, hiszen nem tudunk hivatkozni egy konkrét MailMessage objektumra.

Ha valami miatt mégis ragaszkodnánk a szinkron küldéshez, ne feledkezzünk meg a Timeout tulajdonságról, ami alapértelmezés szerint 100 másodperc, addig próbálkozik a küldéssel. Apropó, ha már a küldésnél tartunk, igen örvendetes, hogy már van lehetőségünk a kapcsolat titkosítására (SmtpClient.EnableSsl) és hitelesítésre is (SmtpClient.Credentials).

Aki pedig arra kíváncsi, hogy mi történik a háttérben, ne habozzon felhúzni néhány trace listenert az app.config fájlban, egészen részletes olvasnivalóban lehet része:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <system.diagnostics>
            <trace autoflush="true" />

            <sources>
                <source name="System.Net" >
                    <listeners>
                        <add name="MyTraceFile"/>
                    </listeners>
                </source>
                <source name="System.Net.Sockets">
                    <listeners>
                        <add name="MyTraceFile"/>
                    </listeners>
                </source>
            </sources>

            <sharedListeners>
                <add
                    name="MyTraceFile"
                    type="System.Diagnostics.TextWriterTraceListener"
                    initializeData="System.Net.trace.log" />
            </sharedListeners>

            <switches>
                <add name="System.Net" value="Verbose" />
                <add name="System.Net.Sockets" value="Verbose" />
            </switches>

        </system.diagnostics>
    </configuration>

És hogy valami stílszerű maradjon a végére, ezt soha ne felejtsük el:

    msg.Dispose();

Technorati tags: , ,

70-528 vizsgatippek

Múlt héten voltam Web-Based Client Development (70-528) vizsgán, gondoltam megosztom a tapasztalataimat, másnak még jól jöhet.

Helyszín

Vizsgaközpontként a TrainerC-t választottam, pontosabban nem volt választási lehetőségem. Az ügyintézés kedves, korrekt és gyors volt, igazán csak jót tudok mondani róla.

Mindössze két problémám akadt:

  • Nem találtam meg elsőre a helyszínt, de ezt csak magamnak köszönhetem, mert nem jegyeztem meg a weblapról, hogy a Delta Irodaházat kell keresni, sőt még a GPS koordinátákat sem írtam fel. Megjegyzem az utcán nem láttam kiírva, hogy Delta Irodaház, csak az épület oldalán, a harmadik emelet magasságában egy hirdetésen láttam kiírva. Legalább lehetett parkolni a szomszédos lakótelepen.
  • Nem vagyok elragadtatva az oktatóközpont weblapjától. A frame-ek nehezen átláthatóak és közvetlen linkeket nem lehet elmenteni, de legalább meg lehet találni rajta a vizsgázáshoz szükséges információkat.

Hogy az oktatóközpontban dolgozók munkáján és hozzáállásán kívül mást is dícsérjek: nagyságrendekkel jobb a büfé, mint az Egyetemen! 😉

Felkészülés

A felkészüléshez két forrást tudok nagyon ajánlani:

  • MCTS Self-Paced Training Kit (Exam 70-528): Microsoft® .NET Framework 2.0 Web-Based Client Development című vizsgafelkészítő könyv. Nem is a könyv az érdekes, hanem a CD mellékleten található vizsgáztató program, amiből fel lehet deríteni, hogy mire szeretnek rákérdezni. Azt hiszen nem árulok el titkot azzal, ha ideírom, hogy peer-to-peer hálózatokon megtalálható a CD melléklet anyaga.
    A könyvhöz egyébként tetemes hibajegyzék van, amit kissé nehéz megtalálni, hiszen a KB930739 tudásbázis cikkben érhető el. Nekem is csak az MS Press support tudta elküldeni a linket, a kérdésem háromszori forwardolása után. A CD mellékletből nincs javított verzió, pedig van hiba a példa kérdésekben is.
  • Lehet vásárolni a neten minta vizsgasorokat, vagy Uram bocsá’ akár P2P hálózatokon is lehet ilyeneket találni. Nekem az ActualTests bejött.

A fenti két forrás együttesen lefedte a vizsgakérdések 100%-át, méghozzá szó szerint, amin nagyon meglepődtem.

Témakörök

A Microsoft természetesen publikálta, hogy mire kíváncsi a vizsgán, mégis íme néhány személyes tipp az egyes témakörökhöz, hogy mire érdemes kiemelten koncentrálni:

  1. Creating and Programming a Web Application
    • Kontrollok dinamikus hozzáadása az oldalhoz
    • Állapotkezelés, mikor viewstate, session vagy query string
    • Oldalak életciklusa
    • Erőforrásfájlok használata (lokalizáció), szintaktika.
    • Validátorok: mikor melyik, kikapcsolás.
    • Hierarchikus vezérlők (menu, treeview, sitemap)
    • Átirányítás (Redirect vagy Transfer)
  2. Integrating Data in a Web Application by Using ADO.NET, XML, and Data-Bound Controls
    • XPath kifejezések értelmezése és a megadott XML dokumentum egy node-jának kiolvasásához szükséges XPath kifejezés megalkotása
    • Az összes XML-lel kapcsolatos osztály, mikor melyiket célszerű használni, melyik gyors, melyikben lehet ugrálni, melyik csak szekvenciális, melyik tud XPath-t stb.
    • Táblák összekapcsolása, idegen kulcsok, kényszerek DataSetben.
    • Táblákon belül nézetek használata és RowStateFilter.
    • Adatkötés folyamata.
    • Expression column szintaktika DataTable-ben.
  3. Creating Custom Web Controls
    • Custom-, user- és composite kontrollok közötti különbségek, mikor melyiket célszerű használni.
    • Mikor melyik ősosztályból érdemes származtatni.
    • Tulajdonságok állapotkezelése (viewstate és control state).
    • Template-es vezérlők készítése.
    • Attribútumok használata (Designer, Category, Description).
  4. Tracing, Configuring, and Deploying Applications
    • Mikor kell Copy Web, Publish Web és Web Setup eszközt használni, melyik mit másol fel, milyen protokollon keresztül.
    • aspnetcompiler.exe
    • Trace lehetőségek.
  5. Customizing and Personalizing a Web Application
    • Master page-content page szintaktika, nested master készítése.
    • Masteren elhelyezett kontroll elérése content page-ről.
    • Webkijelzők: kijelzők összekapcsolása, mikor milyen part (editor, catalog stb.) kell az oldal szerkesztéséhez.
    • Mikor lehet témát és master page-et kódból állítani (PreInit-ben).
  6. Implementing Authentication and Authorization
    • Megszemélyesítés.
    • Szerepkör alapú jogosultság osztás web.configban (allow, deny, ?, *).
    • Hitelesítéshez kapcsolódó ASP.NET 2.0 vezérlők alapszolgáltatásai (pl. levélküldés, password reset vagy elküldés).
  7. Creating ASP.NET Mobile Web Applications
    • Kliens specifikus renderelés.
    • Böngésző képességek detektálása.
    • Egyedi device filter készítése.
    • Lapozás megvalósítása.
    • Form vs. Page.

A fentiek közül szerintem az ADO.NET és az XML a legnagyobb kiszúrás, az XPath bűvölést és az XML osztályok használatát én simán áttettem volna egy adatkezeléssel kapcsolatos vizsgába. Sajnos nem elég az ASP.NET-et ismerni, akadnak kérdések, amik egyértelműen a VS 2005 IDE ismeretére mennek rá, például a Server Explorer használatára, ráadásul pont az adatkezelős részre (pl. SQL query írás), amit a Visual Web Developer Express nem tud 😦

A vizsga egyébként 45 kérdésből áll és 2,5 órás, ami szerintem bőségesen elegendő, én kb. 30 perc alatt végeztem. Nem állítom, hogy a vizsga tökéletesen leméri, hogy az illető mennyire ismeri az ASP.NET-et, de az tény, hogy elég szerteágazóan, elég apró dolgokra kérdez rá, tehát nagyon nem árt, ha az embernek valóban van gyakorlati tapasztalata.

Sok sikert!

Technorati tags: ,

Tartalom mozgatás WSS-ben

Bár a Windows SharePoint Services 3.0-ban már nincsenek igazán komoly korlátok a tartalom mennyiségére vonatkozóan az egyes listákban, dokumentumtárakban és webhelyeken, mégis van néhány olyan szám, amit érdemes szem előtt tartani. A Microsoft például nem javasolja 2000-nél több elem tárolását egy listában, 20GB-nál nagyobb webhely gyűjtemények és tartalom adatbázisok létrehozását vagy éppen 50MB-nál nagyobb fájlok tárolását. Akit érdekel a téma, a Plan for software boundaries című cikkben talál hasznos információkat, külön tudom ajánlani a Guidelines for acceptable performance fejezetet.

Ezen cikk apropóját az adja, hogy a tanszéki intraneten bizony belefutottunk a 20GB-os tartalom adatbázis korlátba az egyik webhely gyűjteményen. Íme néhány kérdés, válasz és workaround, ami ilyenkor felmerül az emberben:

1. Hogyan lehet egy listát vagy dokumentumtárat átmozgatni egyik webhelyről a másikra?

Ha a mérete nem túl nagy, akkor ki kell menteni sablonként tartalommal együtt, majd a lista sablontárból letölteni a sablont, átvinni a másik webhely lista sablontárába és az alapján ott létrehozni az új listát.

Vigyázat: saját tapasztalatom az, hogy az összekapcsolt listák (amelyben egy oszlop másik listában lévő oszlopra hivatkozik) nem jönnek át tökéletesen, gyakorlatilag újra kell definiálnunk a hivatkozó oszlopot és Excellel átvinni a tartalmat. Ez szívás.

2. Hogyan lehet egy nagy dokumentumtárat egyik webhelyről átmozgatni másik webhelyre?

Gondban vagyunk, ha a doktárban nagy fájlok vannak, mert a sablon mérete nem haladhatja meg a 10MB-ot. Ez szívás, nincs rá GUI és az stsadm se tudja. A fájlokat át lehet vinni WebDAV-on keresztül, a metaadatokat pedig Excelen keresztül.

3. Hol lehet megadni/megváltoztatni, hogy egy webhely gyűjtemény melyik tartalom adatbázisban tárolódjon?

Sehol. Ez is szívás.

4. Mi alapján dől el, hogy egy új webhely gyűjtemény melyik tartalom adatbázisban jön létre?

Na, ezt szépen bedrótozták a fejlesztők. Egy újonnan létrehozott vagy backupból visszaállított webhely gyűjtemény abban a tartalom adatbázisban jön létre, amelyben több a hely. A "több hely" a webhelyek számára vonatkozik. Amelyik tartalom adatbázisban nagyobb az alábbi delta, ott fog létrejönni:

delta = Webhelyek maximális száma – Webhelyek száma (jelenleg az adatbázisban)

A fenti képlet változói a Központi felügyelet > Alkalmazáskezelés > Tartalom-adatbázisok oldalon találhatóak meg. Emiatt tessék korlátozni a webhelyek számát a tartalom adatbázisokban, különben összevissza jönnek létre a webhelyek!

5. Hogyan lehet egy webhelyet egyik tartalom adatbázisból átvinni másik tartalom adatbázisba?

Erre sincs GUI és az stsadm se tudja. Miután megértettük, mi alapján dől el, hogy egy webhely gyűjtemény melyik tartalom adatbázisban jön létre, már tudjuk, hogy nincs más dolgunk, mint:

  1. stsadm segítségével backupot készíteni az adott webhely gyűjteményről.
  2. Készíteni egy új tartalom adatbázist és a többinek úgy állítani a korlátait, hogy ennek legyen a legnagyobb a deltája.
  3. Letörölni az eredeti webhelyet.
  4. Visszaállítani a mentést stsadm-mel, ami magától a jó helyen jön létre.
  5. A tartalom adatbázisok korlátait úgy módosítani, hogy a jövőben webhelyek a megfelelő adatbázisban jöjjenek létre.

6. Hogyan lehet egy tartalom adatbázis kettéválasztani?

Túl nagy lett, jó lenne szétosztani. Sajnos ez sem fog menni egyszerűen. Meg kell találni, hogy melyik a nagy méretű webhely gyűjtemény, azt le kell menteni, majd vissza kell állítani másik útvonalra, másik tartalom adatbázisba. Mivel ebben a fázisban ugyanaz a tartalom két példányban van meg, nincs más dolgunk, mint a tartalom felét innen, a tartalom másik felét onnan kitörölni.

7. Kitöröltem egy nagy méretű dokumentumtárat, de nem csökkent a tartalom adatbázisom mérete. Mi a gond?

Gond egy szál se, a WSS 3.0-ban már van Lomtár, ki kell üríteni.

8. Kiürítettem a Lomtárat, de még mindig nem csökkent a tartalom adatbázisom mérete. Mi a gond?

Gond egy szál se, a WSS 3.0-ban már van Lomtár, mégpedig kétszintű: felhasználó és webhely rendszergazda szintű. Mindkettőt ki kell üríteni.

9. A lomtár kiürítésekor vagy webhely törlésekor 0x80040E14 hibát kapok, meg egy semmitmondó Ismeretlen hiba üzenetet. Mi a gond?

Az Ismeretelen hiba valóban semmitmondó, a 80040E14 viszont Syntax error in INSERT INTO statement, tehát egyáltalán nem ismeretlen, csak ijesztő. Talán ezért nem merik megmutatni az átlagfelhasználónak? Rosszul írták meg a WSS-t?! A jelek szerint ez egyszerű timeout esetén következik be, ha túl nagy mennyiségű adatot próbálsz egyszerre törölni.

Ha nagy a webhely, próbálj doktáranként törölni előbb. Ha nagy a doktár, próbálj kisebb méretű mappákat vagy fájlokat külön törölni, vagy ne egyben az egész lomtárat kiüríteni, akkor menni fog. Nálam egy egygépes környezetben 3GB körüli doktárakat tudtam törölni gond nélkül, nagyobbakat nem.

Megjegyzem a WSS 2.0-ban is volt hasonló probléma a nagy mappákkal (lásd KB827930).

10. Backup visszaállításakor valami .tmp fájlra vonatkozó írási hibát kapok. Mi a gond?

Érdemes megnézni a SharePoint nyomkövetési naplóját, ami a C:Program FilesCommon FilesMicrosoft SharedWeb Server Extensions12LOGS mappában található. A naplózás beállításait a Központi felügyelet > Tevékenység > Diagnosztikai naplózás oldalon találjuk meg. Itt a .log fájlokban kutatva megtalálhatjuk az írási hibaüzenetet, például:

Írási hiba a(z) "wss0CFC021441D14DE580F5B9B698AA34D5_1.tmp" fájlon.

Rögtön az előtte lévő sorban találunk egy 0x80070070 hibakódot, amire ha rákeresünk megtudhatjuk, hogy a kevés szabad helyre utal:

Error 80070070: There is not enough space on the disk.

Elsőre kicsit érthetetlen, hiszen amikor elindítottuk a visszaállítást, akkor jó sok hely volt, most meg nincs semmilyen wss….tmp fájl a diszken.

Kicsit feljebb olvasva a logban rájöhetünk a dolog nyitjára: a restore művelet az stsadm-et futtató felhasználó saját temp mappájába ír. Ha nem hagyjuk ott a visszaállítást egyedül futni, hanem folyamatosan szugeráljuk a szabad helyet, akkor azt fogjuk látni, hogy nem az adat partíciónkon, hanem a C:-n fogy el a hely!

A megoldás: át kell tenni az aktuális felhasználó Temp mappáját másik partícióra. Hogyan? My Computer > Properties > Advanced > Environment variables és ott írjuk át a TEMP és TMP értékét egy másik partíción lévő mappára. Visszaállítás végeztével ne felejtsük el visszaírni!

Egyébként pedig a visszaállítás idejére lehet, hogy célszerű kikapcsolni a WSS nyomkövetési naplózását, mert nálam például több száz MB logot írt. Kikapcsolni legegyszerűbben úgy lehet, ha leállítjuk a Windows SharePoint Services Tracing (SPTrace) szolgáltatást.

 

Nekem a fenti tapasztalatok összegyűjtése nagyjából 2 napot vett el az életemből. Egy nem túl fürge szerveren ennyi idő alatt sikerült egy 25GB-os tartalom adatbázist kettévágni és a tartalmát két új adatbázisba áttenni. Az én konfigurációmon a backup kb. 2,5-3 óra volt, a törlési hibaüzenetek pedig fél-háromnegyed óra alatt jöttek elő, ami után persze kezdhettem elölről 😦  Remélem másnak már nem fog ekkora gondot okozni és még talán szeretni is fogja a SharePointot.

 

Technorati tags: ,

WSS 2.0 migrálása 3.0-ra

A héten megugrottam a tanszéki intranetünk migrálását Windows SharePoint Services 2.0-ról 3.0-ra. Íme néhány tapasztalat, hátha megkönnyítem vele mások életét:

1. PreScan

Létezik a WSS-hez és az SPS-hez egy ún. Upgrade Pre-scan tool, amelyet még a régi WSS 2.0 installáción kell lefuttatnunk és megmondja, hogy mi lehet gond a migrálásnál. Egyszerű parancssori kis eszköz, XML kimenetet generál. Nálam azért jött jól, mert remekül kilistázta az összes unghosted page-et, és megnyugtatott, hogy ezen kívül más gond valószínűleg nincsen. Arra nem jött rá, hogy felülírtuk az eredeti template és stílus fájlokat 😦

2. Upgrade

Nálam a telepítő upgrade módban teljesen simán lefutott, majd bejött a SharePoint Központi Felügyelet oldalon a frissítés követését biztosító oldal. Kéretik elolvasni a leírásban, hogy a frissítés nagy része csak ilyenkor történik meg, tehát amíg ez a böngészős rész le nem fut, addig biztosan nem vagyunk készen.

Meglepő módon a FrontPage 2003-mal készített Data View Webpartok tökéletesen működnek a migráció után is.

Amit nem sikerült migrálni:

  • A SmartPartos webkijelzők nem működnek, valószínűleg az egész SmartPartot újra kell telepítenem a WSS 3.0-hoz kijött verzióval.
  • A WSS 3.0 nem ismeri a PDF ikont, PDF dokumentumok mellett fehér papírlap ikon jelenik meg, ezt újra kellett konfigurálnom.
  • A kereső nem működött frissítés után.
  • A kezdőoldal nem akart hostname alapján bejönni, mindig átirányított IP címes URL-re, aminél persze nem volt jó az SSL tanúsítvány, ráadásul authentikációt is kért.
  • Korábbi backup szkript hibaüzenettel elszállt.
  • A szerver rendszergazdája nem lett rendszergazda a WSS-ben.
  • Engedélyezett fájltípusok listája törlődött. 

3. Upgrade fixek

3.1 PDF ikon telepítése

Szerencsére WSS 3.0 alatt nem kell nagy trükközés ahhoz, hogy új dokumentum ikont telepítsünk, mindössze 4 lépésre van szükség:

  1. Keressünk egy 16×16-is PDF ikont GIF formátumban és az egységesség kedvéért nevezzük el icpdf.gif-nek.
  2. Másoljuk be az ikon fájlt a C:Program FilesCommon FilesMicrosoft Sharedweb server extensions12TEMPLATEIMAGES mappába.
  3. Nyissuk meg a C:Program FilesCommon FilesMicrosoft Sharedweb server extensions12TEMPLATEXML mappában található docicon.xml fájlt és másoljuk be a következő sort:
    <Mapping Key="pdf" Value="icpdf.gif"/>
    Hogy hova, az tisztán látszik, nálam a 83. sorba került.
  4. Mi más lehet az utolsó lépés egy SharePoint konfigurálásnál, mint iisreset.

3.2 Kereső beizzítása

A kereső elindításához két lépésre volt szükség:

  1. A Központi Felügyelet > Tevékenység > Kiszolgáló szolgáltatásai oldalon be kellett konfigurálni és el kellett indítani a kereső szolgáltatást.
  2. A Központi felügyelet > Alkalmazáskezelés > Tartalom-adatbázisok oldalon a tartalom adatbázishoz kereső kiszolgálót kellett rendelni.

Már éppen el akartam indítani egy teljes bejárást az stsadm spsearch opciójával, mikor elkezdtek megjelenni a találatok, tehát ment magától.

3.3 Webhely elérése hostnév alapján

Itt a bosszantó tünet az volt, hogy a szokásos https://intranet cím beírása után a böngésző átvitt a https://x.y.z.w IP címet tartalmazó címre, ami miatt persze nem stimmelt az SSL tanúsítvány és hitelesítésre is szükség volt.

A megoldást a Központi felügyelet > Tevékenység > Másodlagos címek leképezése oldalon találtam meg, ahol sok kattintgatás után az alábbi beállítás eredményeként az intranetünk elérhető belülről https://intranet címen, kívülről https://extranet.aut.bme.hu címen, az stsadm pedig https://maffia néven szeret hivatkozni a webhelyekre:

Másodlagos címek leképezése

3.4 Backup szkript frissítése

Ha korábban stsadm segítségével készítettünk backupot a szerverről, ne felejtsük el a backup szkriptünkben az stsadm útvonalát megváltoztatni a ../60/.. mappa helyett ../12/.. kell a WSS 3.0-hoz.

3.5 Rendszergazdai engedélyek visszaállítása

A migráció után az új verzióban a tartományi rendszergazdák nem élveztek rendszergazdai jogokat a WSS-ben, márpedig nálunk erre szükség van. Ezt legegyszerűbben úgy lehetett visszaállítani – és ez egy nagyon király funkció a WSS 3.0-ban, – hogy házirend szinten adtam jogok a helyi Domain Admins csoportnak a következő oldalon: Központi felügyelet > Alkalmazáskezelés > Webalkalmazás házirendje.

3.6 Fájl típusok engedélyezése

Már a WSS 2.0 is ismerte a Letiltott fájltípusok fogalmát és nagy zseniálisan nem engedte például .chm fájlok felmásolását SharePoint dokumentumtárakba. Mivel nekünk erre szükségünk volt, a CHM-et és még néhány kiterjesztést töröltünk a tiltólistáról, sajnos ez a beállítás szintén nem migrálódott. A következő útvonalon a 2.0 verzióban megszokott módon tudtam újra engedélyezni őket: Központi felügyelet > Tevékenység > Tiltott fájltípusok.

 

Ennyi konfigurálgatás, sok tesztelés és backup futtatása után elmondhatjuk, hogy a gép forog, az alkotó pihen. Az igaz, hogy férfi munka volt, de hogy jó mulatság, azt még egyetlen SharePointos feladattal kapcsolatban sem sikerült megélnem…

 

Technorati tags: ,