György's profileBalássy GyörgyPhotosBlogListsMore Tools Help

Blog


    September 17

    Időnként Access Denied a _layouts mappa fájljaira

    Meghalt a SharePointunk alatt a winchester, nem maradt más választásunk, mint backupból visszaállítani az egészet egy másik gépre. Ha már újratelepítés, akkor természetesen minden szoftverből a legújabb került a vasra: Windows Server 2008 R2, IIS 7.5, SQL Server 2008, WSS 3.0 SP2. A mentést sikerült visszaállítani, vidáman ketyegtek a csoportmunka webhelyek, időnként azonban furcsa 403 – Access Denied hibákat kaptunk.

    Még olyan is előfordult, hogy egy webhelycsoport tulajdonosaként tudtam listázni a webhely felhasználóit (/_layouts/user.aspx), de amikor újat akartam felvenni, az oldal (/_layouts/acinv.aspx) jogosultsági hibával elszállt. Az a furcsa, hogy két olyan fájlról van szó, amik virtuálisan és fizikailag is azonos mappában vannak. Az operációs rendszer eseménynaplójában semmi.

    A WSS-ben többnyire elég jól megoldották azt, hogy ha egy beállítás módosításához nincs jogom, akkor a megtekintéséhez sem és fordítva, ezért gyorsan kizártam annak a lehetőségét, hogy SharePoint konfigurációs hiba lenne. A mentésből a jogosultságokat is visszaállítottuk és szemmel láthatóan még mindig a webhelycsoport tulajdonosa voltam.

    Így aztán, amint sikerült reprodukálni a hibát, jött a szokásos access denied kalapács: Sysinternals Process Monitor. Szűrés a w3wp.exe processre és a sok SUCCESS között ordított az ACCESS DENIED sor:

    Process Monitor: Access Denied

    Látszik, hogy a WSS megszemélyesítette az AUT\balassy felhasználót és annak a nevében próbálta olvasni a webalkalmazáshoz rendelt bin könyvtárat. Adtam az érintett felhasználónak olvasási jogot erre a mappára és azóta sokkal szebb az élet.

    August 27

    Mi az a SharePoint?

    Erre a kérdésre nem egyszerű a válasz, és lássuk be, eddig a Microsoftnak sem sikerült. Elég csak megnézni a hivatalos weboldalt, ahol a kötelező bűvszavakból (effectiveness, extensibility, interoperability, processes, information sharing, enterprise stb.) áll össze a nagy büdös semmi négy hosszú sorban. Most azonban úgy tűnik, hogy rátaláltak a CommonCraft cégre, akik arra specializálódtak, hogy egyszerűen és röviden magyarázzanak el bármit. Ezt is rövidebben mondják el, mint én: “our product is explanation”.

    Ez a 3 perces videójuk többet ér, mint az összes marketing maszlag:

    SharePoint in plain English SharePoint in plain English

    Érdemes megnézni a többi videójukat is.

    Technorati-címkék: ,,
    August 24

    SharePoint Access Web Datasheet hiba

    Egy Windows SharePoint Services webhely egyik adatlap nézetben megjelenő listája a minap az alábbi hibaüzenettel üdvözölt:

    “The Access Web Datasheet is attempting to retrieve data from a different domain. You will be redirected to an error page. Contact your system administrator to resolve this error.”

    A legszebb az egészben, hogy mindez csak akkor jelent meg, amikor a listát a http://intranet címen keresztül értem el, amikor FQDN-en keresztül, akkor működött simán. Ezek után nem lepődtem meg, hogy a guglizás eredménye az lett, hogy nézzek körül az Alternate Access Mappings beállításoknál.

    A megoldás azonban lényegesen egyszerűbb volt: elfogyott a szabad hely a C: meghajtón. Kiderült, hogy a bűnös maga a WSS volt, a keresőmotor elindított egy teljes újraindexelést és közben telehányta a naplót a C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\LOGS mappában. Magasabbra vettem a naplózási küszöböt a Központi Felügyelet oldalon, kitöröltem a LOGS mappa tartalmát és azóta megint szépen forog a gép.

    Hogy ennek mi köze a fenti hibaüzenethez? Szerintem semmi. Contact your developer to fix this error message.

    May 19

    Informatika Tisztán – Megoldásbörze letöltések

    Letölthetőek az Informatika Tisztán sorozat múlt heti Megoldásbörzéjén tartott előadásaim prezentációi és videói.

    Adatokat az intranetre

    Data Source Library SharePoint DesignerbenPartnerek, ügyfelek és a saját munkatársak elérhetővé és kereshetővé tétele az intraneten

    Gyakran merül fel az igény, hogy egy vállalaton belül összegyűjtött adatbázist, például a partnereink elérhetőségeit szeretnénk a munkatársak között megosztani, webes felületen megjeleníteni, rendezhetővé és kereshetővé tenni. Az előadásban a Windows SharePoint Services webkijelző infrastruktúrájára épülve, SharePoint Designer segítségével, fejlesztés nélkül tesszük közzé a relációs adatbázisban tárolt adatainkat az intraneten.

    • Prezentáció (1694 kB)
    • A screencast a képre kattintva megtekinthető, vagy a kép alatti hivatkozás segítségével letölthető teljes vagy rövid változatban:

    Adatokat az intranetre - screencast

    Teljes változat: Adatokat_az_intranetre.wmv (37:34, 206 722 kB)

    Rövid összefoglaló: Adatokat_az_intranetre_rovid.wmv (3:46, 20 538 kB)

    Dokumentumok standardizálása

    Új dokumentum létrehozása dokumentumtárban Céges dokumentumok automatikus előállítása: árajánlatok, szerződések, teljesítésigazolások generálása

    A vállalati előírásoknak, formuláknak megfelelő dokumentumok manuális előállítása nehézkes és időigényes feladat, különösen akkor, ha a szükséges adatokat nekünk kell más dokumentumokból összevadásznunk. Az előadásban bemutatjuk, hogyan használhatjuk ki a Windows SharePoint Services dokumentumtárait és a SharePoint Designer grafikus lehetőségeit árajánlatokat, szerződéseket és teljesítésigazolásokat létrehozó munkafolyamatok készítésére.

    • Prezentáció (1152 kB)
    • A screencast a képre kattintva megtekinthető, vagy a kép alatti hivatkozás segítségével letölthető teljes vagy rövid változatban:

    A Dokumentumok standardizálása c. screencast megtekintése

    Teljes változat: Dokumentumok_standardizalasa.wmv (46:58, 259 015 kB)

    Rövid összefoglaló: Dokumentumok_standardizalasa_rovid.wmv (7:54, 42 180 kB)

    Aki ott volt a Sugárban, vagy esetleg letöltötte és megnézte ezeket a felvételeket, kérem írjon valami visszajelzést, hasznos, megérte?

    February 02

    SharePoint teljes webhelytartalom oldal nem jön be

    Ma sikerült belefutnom az alábbi kedves üzenetbe egy Windows SharePoint Services oldalon, mikor a webhelyen lévő listákat (viewlsts.aspx) akartam megnézni:

    An item with the same key has already been added.

    Ilyet egy .NET-es alkalmazásban akkor szoktunk kapni, ha egy szótár típusú változóban már létezik elem azzal a kulccsal, amivel épp egy újat akarunk hozzáadni. Weben tipikusan postbacknél szokott előfordulni, nem pedig az oldal első lekérdezésénél. (De mint tudjuk, a SharePoint szinte bármire képes, így WSS-ben ez első oldal betöltésnél is elő tudott jönni.) Hagyományosan ilyenkor ki szoktuk javítani a kódot, de mivel ez a WSS beépített oldala volt, itt ez a lehetőség szóba se jöhetett. Így jobb híján maradt az a kalapács, amivel a SharePointos hibaüzenetek 130%-át le lehet csapni:

    IISRESET

    Működött.

    July 02

    Saját activity SharePoint Designerbe

    A SharePoint Designer workflow tervezőjével sok feladatot könnyen megoldhatunk, bonyolultabb esetekben azonban hamar kifuthatunk a funkciókból. Szerencsére a lista bővíthető, be lehet varrni saját activity-t az eszközbe.

    Ehhez csak a következőket kell tennünk:

    1. Készítsük el a szokásos módon a saját activity komponensünket egy Activity Library típusú projektben.

    2. Lássuk el a szerelvényt erős névvel és telepítsük a központi szerelvénytárba (GAC).

    3. Keressük meg a 12\TEMPLATE\1033\Workflow\WSS.ACTIONS fájlt, készítünk róla másolatot akármi.ACTIONS néven (a kiterjesztés fontos) ugyanabba a mappába és egy Action elemben írjuk le az activity-nket. Például egy mappa másolását elvégző saját FolderCopyActivity így írható le:

        <?xml version="1.0" encoding="utf-8"?>
        <WorkflowInfo>
            <Actions Sequential="then" Parallel="and">
                <Action Name="Mappa másolása"
                    ClassName="MyActivityLib.FolderCopyActivity"
                    Assembly="MyActivityLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e1b2225a7cb586c4"
                    Category="Saját"
                    AppliesTo="all">
                    <RuleDesigner Sentence="A %1 mappa másolása a %2 mappába">
                        <FieldBind Field="SourceFolder" Text="forrás" DesignerType="TextArea" Id="1" />
                        <FieldBind Field="TargetFolder" Text="cél" DesignerType="TextArea" Id="2" />
                    </RuleDesigner>
                    <Parameters>
                        <Parameter Name="SourceFolder" Type="System.String, mscorlib" Direction="In" />
                        <Parameter Name="TargetFolder" Type="System.String, mscorlib" Direction="In" />
                    </Parameters>
                </Action>
            </Actions>
        </WorkflowInfo>
    

    Érdemes megfigyelni, hogy a Sentence attribútumban egy értelmes mondatot kell megadnunk, ami meg fog jelenni a felhasználói felületen. A % jellel jelölt paraméterek megjelenését a FieldBind elemekben tudjuk részletezni és a Parameters elemben tudjuk azokat az Activity osztály dependency property-jeihez kapcsolni. Célszerű odafigyelni a DesignerType attribútumra, hogy olyat válasszunk, ami később megkönnyíti a paraméter beállítását. A lehetséges értékek listája az MSDN oldalain megtekinthető, ahogy az ACTIONS fájl teljes sémája is.

    4. A webalkalmazásunkhoz tartozó web.config fájlban regisztráljuk a típust authorizedType-ként. Ez lényegében olyan, mint a SafeControl szekció, csak éppen a System.Workflow.ComponentModel.WorkflowCompiler elemben található:

        <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
        <configuration>
            <!-- ... -->
            <System.Workflow.ComponentModel.WorkflowCompiler>
                <authorizedTypes>
                    <!-- ... -->
                    <authorizedType 
                        Assembly="MyActivityLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e1b2225a7cb586c4" 
                        Namespace="MyActivityLib" 
                        TypeName="*" 
                        Authorized="True" />
                </authorizedTypes>
            </System.Workflow.ComponentModel.WorkflowCompiler>
        </configuration>

    5. Nyissunk rá a webhelyre SharePoint Designerben és frissítsük a nézetet, aminek hatására az eszköz letölti a szerverről az ACTIONS fájlt és meg fog jelenni az új activity-nk workflow tervezése közben.

    June 30

    A lényeg kiemelése

    A Word 2003-ban volt egy Autosummarize funkció, amely nevéhez hűen kiemelte a lényeget egy dokumentumból. A Word 2007-ben is elérhető ez a szolgáltatás, azonban alapértelmezés szerint nincs kint a szalagon, nekünk kell kitenni:

    Word Options: AutoSummary

    Ezek után az alábbi opciókat tudjuk beállítani és a funkció kiválóan működik angol szövegre:

    AutoSummarize beállítások

    Mivel én személy szerint jobban kedvelem a képes megoldásokat, ezért némi keresgélés után sikerült rátalálnom a Wordle weboldalra, ahol a lényeg kiemelése a tag-cloud megoldáshoz hasonlóan méret-, elrendezés- és szín variációkkal történik. Lehet tippelni, hogy Szalkáry Károly barátom miről írta a diplomamunkáját:

    Wordle: Diploma

    Ez pedig én lennék, rövid angol CV alapján, tömören:

    Wordle: Balássy György CV

    Mikor jutunk el odáig, hogy a keresőmotorok találatai nem egy csupasz listában, hanem átláthatóan rendezve jelennek meg?

    Technorati Tags:
    June 18

    Adatok bekérése SharePoint Designeres workflowban

    SharePointos workflow fejlesztéshez igen jól használható eszköz a SharePoint Designer (SPD), de tagadhatatlan, hogy néha nehéz elsőre eligazodni a felhasználói felületen. Az egyik ilyen “néha” akkor jön velünk szembe, amikor a folyamat futása során adatokat szeretnénk bekérni a felhasználóktól.

    Az adatok bekéréséhez és a felhasználókkal történő kommunikációhoz a SharePointos workflow-k a feladat listákat használják. A SharePoint Designerben az Adatgyűjtés a felhasználóról (angolul Collect Data from a User – a webhely nyelvétől függően) műveletet használhatjuk arra, hogy a feladat listába újabb elemet tegyünk:

    SharePoint Designer: Adatgyűjtés a felhasználról

    Az Adatok (angolul data) linkre kattintva egy Custom Task Wizard varázsló segítségével adhatjuk meg, hogy milyen információkat szeretnénk megtudni a felhasználótól. Az első kérdésnél egy nevet és egy leírást kell megadnunk:

    Custom Task Wizard: név és leírás

    A varázsló következő lépésében pedig a bekérendő adatokat definiálhatjuk:

    Custom Task Wizard: mezők

    Érdemes tudnunk, hogy mi történik a háttérben:

    • A SPD létrehoz egy új tartalomtípust azzal a névvel, amit itt megadunk. A tartalomtípus a Workflow Task típusból származik, tehát 0x01080100 kezdetű azonosítója lesz. Az új tartalomtípus azon a webhelyen jön létre, ahol a workflow-t készítjük.
    • A SPD hozzárendeli ezt a tartalomtípust a folyamathoz rendelt feladatlistához.
    • A SPD létrehoz egy ASP.NET alapú űrlapot a http://szervernév/webhelynév/Workflows/folyamatneve/űrlapneve.aspx címen. Ha barátságos folyamat- és űrlap neveket használunk, az URL gusztustalan lesz. (Persze esélyünk sincs barátságos URL-re, mert van pár tucat karakternyi query string a végén.) Az űrlapot hozzárendeli a tartalomtípushoz szerkesztési űrlapként (tehát csak edit módban fog megjelenni, display módban nem). Ezen az űrlapon statikus szövegként, Title és Description címen megjelenik a varázslóban megadott név és leírás:

    Feladat szerkesztő űrlap

    Miután így definiáltuk az adatokat és az azokat bekérő felületet, és még azt is megadtuk, hogy ki nyerte meg ezt a feladatot, végül egy változót kell megadnunk:

    SPD_WFD_04-Variable

    A trükk az, hogy itt egy ID típusú változót kell megadnunk, azaz a művelet eredményeként nem közvetlenül az adatokat kapjuk meg, hanem azt, hogy a SharePoint a folyamathoz kapcsolt feladat listában melyik listaelembe mentette el a felhasználó válaszait.

    Persze ilyenkor felmerül a kérdés, hogy ezt hogyan tudom visszanyerni? Például ha naplózni szeretném a Vélemény mezőt, így kell felkonfigurálni a Define Workflow Lookup ablakot:

    Define Workflow Lookup

    Kis segítség a beállítások olvasásához: ha SQL lenne, ezt írhatnánk:

    SELECT Vélemény

    FROM Feladatok

    WHERE Szám = VéleményezésiFeladatID

    Általánosabban:

    SELECT LookupDetails_Field

    FROM LookupDetails_Source

    WHERE FindTheListItem_Field = FindTheListItem_Value

    A lookup eredménye olyan típusú lesz, mint a felső Field mezőben megadott oszlop.

     

    June 17

    Származtatott tartalomtípus oszlopok nélkül

    Amikor saját SharePointos tartalomtípust készítünk, az kötelezően származik egy szülő tartalomtípusból és örökli annak oszlopait. Hogyan lehet mégis olyan tartalomtípust létrehozni, amelynek egyetlen oszlopa sincs?

    A kérdés még inkább fordítva szokott előfordulni, főleg workflow fejlesztéskor: készítünk egy saját tartalomtípust a feladatok kezelésére, származtatunk a WorkflowTask (0x010801) típusból, az öröklés rendben van, mégsem jelennek meg a szülő típus oszlopai. A jelenség oka, hogy úgy hoztuk létre a feature-ben a ContentType elemet, hogy kihagytuk belőle a FieldRefs tag-et. Ez az elem mindenképpen szükséges, még akkor is, ha üres:

    <?xml version="1.0" encoding="utf-8"?>
    <Elements Id="43c7826b-e8ed-434c-bc48-a321094caee3" xmlns="http://schemas.microsoft.com/sharepoint/">
        <ContentType ID="0x01010088d402e587cb46258a6cdbec0ad318e7"
                   Name="Szerződés"
                   Group="Saját tartalomtípusok"
                   Description="Szerződést leíró tartalomtípus."
                   Version="0">
            <FieldRefs />
        </ContentType>
    </Elements>
    Technorati Tags: ,,
    June 16

    Beépített mező és tartalomtípusok

    SharePoint programozása során gyakori feladat, hogy kódból kell hivatkoznunk egy adott mezőre vagy tartalomtípusra. Ha nyelvfüggetlen módon szeretnénk mindezt megtenni, akkor a mező vagy tartalomtípus neve helyett annak azonosítóját kell használnunk.

    Ha olvasható kódot szeretnénk gyorsan írni, akkor a GUID-ok bedrótozása helyett inkább használjuk a Microsoft.SharePoint névtérben található SPBuiltInFieldId és SPBuiltInContentTypeId osztályokat. Akkor is jól jöhetnek ezek az osztályok, ha éppen adatbázist vagy naplófájlokat kell elemeznünk, ugyanis közvetlenül megtalálható az osztály forráskódjában az összes azonosító, amely Reflectorral prímán kinyerhető. Az egyszerűség kedvéért mellékeltem is a két fájlt.

    A tartalomtípusokkal kapcsolatban előfordulhat, hogy meg kell állapítanunk, hogy egy adott típus egy másikból származik-e. Ez persze “ránézésre látszik”, ha egymás alá tesszük a két típus azonosítóját, a gyermek azonosítója ugyanis a szülő azonosítójával kezdődik. Példaként itt egy öröklési hierarchia:

    Item: 0x01

    Document: 0x0101

    BasicPage: 0x010109

    WebPartPage: 0x01010901

    Ha ezt a vizsgálatot nem akarjuk mi elvégezni, akkor használhatjuk az SPContentTypeId típust, például így:

        SPContentTypeId doc = SPBuiltInContentTypeId.Document;
        SPContentTypeId item = SPBuiltInContentTypeId.Item;
    
        Console.WriteLine( doc.IsChildOf( item ) );  // true
        Console.WriteLine( item.IsParentOf( doc ) ); // true
    
        SPContentTypeId custom = new SPContentTypeId( "0x0105" );
        Console.WriteLine( custom.IsChildOf( item ) );  // true
        Console.WriteLine( custom.IsChildOf( doc ) );   // false
    
        Console.WriteLine( custom.Parent );  // 0x01

    Az SPContentTypeId osztály belül csak egy byte tömbnyi információt tárol a tartalom típusról, azaz gyakorlatilag csak az azonosítóját. Név nincs sehol (legalábbis az SDK és a Reflector szerint), így a Parent tulajdonság kiolvasásakor nem kapunk értelmes nevet, mindössze egy azonosítót. Az SPBuiltInContentTypeId.Contains(contentTypeId) meghívásával még megtudhatjuk, hogy a kapott szülő standard-e, de a nevét nem tudja ez az osztály visszaadni, még a ToString() hívásakor is csak az azonosítót kapjuk.

     

    June 15

    Létrehozási, fordítási és hibakeresési problémák VS 2008 SharePointos projekteknél

    Hosszú listát lehet összeírni arról, hogy a SharePoint mi mindenben egyedi. Íme egy újabb tétel a listába: a Visual Studio 2008-ban található SharePointos projekt sablon létrehozás után nem fordul, még ha nem is írunk bele semmit, vagy éppen debug módban nem indítható el.

    Először is tisztázzuk, mitől lesznek SharePointos projekt sablonok a Visual Studio 2008-ban: a telepítéskor ki kell választanunk, hogy Office alkalmazásokat is szeretnénk fejleszteni. Ennek hatására két SharePointos projekt típus jelenik meg: SharePoint 2007 Sequential Workflow és SharePoint 2007 State Machine Workflow:

    SharePointos projekt típusok Visual Studio 2008-ban

    Előfordulhat, hogy hiába kattintunk bármelyikre, a Studio nem képes létrehozni a projektet:

    Could not load file or assembly 'Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' or one of its dependencies. The system cannot find the file specified.

    Ezek után még felkínálja a Studio, hogy adminként indítsuk újra, de ettől ne várjunk csodát, ugyanis a hibaüzenetnek nagyon egyszerű oka van: valószínűleg nem telepítettünk a gépünkre SharePointot. Egy újabb ok arra, hogy a SharePointos fejlesztéseinket Windows Serverre telepített SharePoint és helyi Visual Studio környezetben végezzük.

    Amikor a projekt típusok közül bármelyiket létrehozzuk és le akarjuk fordítani, az alábbi hibaüzenetekket kapjuk:

    Could not resolve this reference. Could not locate the assembly "Microsoft.Office.Workflow.Tasks". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors.

    The type or namespace name 'Office' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?)

    Ha jobban megnézzük a Solution Explorer ablakban a References ágat, azt vehetjük észre, hogy négy SharePointos szerelvényre van hivatkozás, melyek közül a Microsoft.Office.Workflow.Tasks nem található:

    Solution Explorer: References

    Ennek valószínűleg az az oka, hogy WSS-sel dolgozunk, ezt a szerelvényt viszont csak a MOSS tartalmazza. A hibaüzenet megszűntethető, ha eltávolítjuk ezt a szerelvény referenciát. A hivatkozás egyedül azért szerepel itt, mert a Workflow1.cs fájlban megtalálható az alábbi using sor, amit szintén törölhetünk:

    using Microsoft.Office.Workflow.Utility;

    A projektünk ezek után vígan fordulni fog. Amikor azonban az F5-re bökve debug módban indítanánk, jön egy újabb hibaüzenet, ezúttal nem fordítási, hanem deployment error:

    Failed to install the workflow template to Microsoft Office SharePoint Server.

    Feature '86d1ee3b-9966-40a0-a16f-c366e8a5f302' could not be installed because the loading of event receiver assembly "Microsoft.Office.Workflow.Feature, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" failed: System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Office.Workflow.Feature, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' or one of its dependencies. The system cannot find the file specified.
    File name: 'Microsoft.Office.Workflow.Feature, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c'

    Ennek az oka, hogy a feature.xml-ben található hivatkozás a Microsoft.Office.Workflow.Feature szerelvényre, amely szintén csak a MOSS-ban található meg. Bátran töröljük a ReceiverAssembly és a ReceiverClass sorokat és máris menni fog a telepítés:

        <?xml version="1.0" encoding="utf-8" ?>
        <Feature  Id="86d1ee3b-9966-40a0-a16f-c366e8a5f302"
                    Title="SharePointWorkflow1 feature"
                    Description="My SharePoint Workflow Feature"
                    Version="12.0.0.0"
                    Scope="Site"
                    ReceiverAssembly="Microsoft.Office.Workflow.Feature, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
                    ReceiverClass="Microsoft.Office.Workflow.Feature.WorkflowFeatureReceiver"
                    xmlns="http://schemas.microsoft.com/sharepoint/">
            <!-- ... -->
    

    A Visual Studio 2008 egyik újdonsága, hogy egy projekt létrehozásakor megadhatjuk a cél .NET Framework verziószámot. A szóban forgó projektek azonban csak akkor jelennek meg, ha a létrehozáskor 3.5-t választunk. Mivel tudjuk, hogy a SharePointnak a .NET 3.0 is elég, ezért a projekt létrehozása után a projekt tulajdonságai között bátran állítsuk át a Target Framework opciót .NET Framework 3.0-ra.

    Ezek után megint fordítási hibákat fogunk kapni, aminek megoldásához töröljük a LINQ-es hivatkozásokat. A References ágból töröljük a System.Data.DataSetExtensions és a System.Xml.Linq szerelvényeket, a workflow1.cs fájlból pedig a using System.Linq; sort.

     

    June 05

    Informatika Tisztán - letöltések

    Javában zajlik az Informatika Tisztán rendezvénysorozat, akit érdekel a csoportmunka, még van lehetősége megtekinteni az előadásokat valamelyik helyszínen.

    A Windows SharePoint Services v3 üzemeltetéssel kapcsolatos prezentáció letölthető innen:

    WSSv3_rendszergazda_szemmel_(Balassy_Gyorgy)_v15.ppt (23946 kB)

    Az előadáshoz kapcsolódó screencastok is elkészültek:

    1. A telepítés előkészítése (13:57) Lejátszás »
    2. Telepítés utáni első lépések (24:06) Lejátszás »
    3. Extranet publikálás (11:31) Lejátszás »
    4. Monitorozás (8:25) Lejátszás »
    5. Mentés és visszatöltés (12:03) Lejátszás »
    6. Külső gyártótól származó megoldás telepítése (9:51) Lejátszás »

    Ráadásként pedig készült egy olyan felvétel is, amely az Internet Information Services és az ASP.NET webalkalmazások üzemeltetésével kapcsolatos legfontosabb alapismereteket foglalja össze:

    ASP.NET bevezető üzemeltetőknek (32:21) Lejátszás »

    A videó fájlok közvetlenül is letölthetőek vagy a Lejátszás linkre kattintva böngészőben is megtekinthetőek egy Silverlight alapú lejátszónak köszönhetően 800x600 felbontásban.

    Sajnos nagyon kevés visszajelzést kapunk az előadásokkal kapcsolatban, aki ott volt és van véleménye, kérem írja meg, hogy tudjuk, mi volt jó és mit csináltunk rosszul. Köszönjük!

     

    May 31

    Office 2007 ribbon ikonok

    Korábban a SiteSource add-in fejlesztésekor futottam bele abba a problémába, hogy kellene egy jól mutató ikon az add-inhoz tartozó szalagra. Kedvenc ikonunkat kétféle képpen lehet megjeleníteni és a Visual Studioba beépített Ribbon Designer mindkettőre ad is lehetőséget:

    Visual Studio Ribbon Designer

    1. Ha valamilyen saját képet szeretnénk használni, adjuk meg azt az Image tulajdonságban.
    2. Ha szeretnénk igazodni az Office 2007 dizájnjához, akkor pedig használhatjuk az OfficeImageId tulajdonságot.

    Mivel a legminimálisabb dizájner vér sem csörgedezik az ereimben, ezért úgy döntöttem, hogy az Office beépített ikonjai közül fogok választani. Adott tehát a feladat, ki kell választani egy ikont és megadni annak az azonosítóját az OfficeImageId tulajdonságban.

    A képek közötti válogatásban sokat segíthet a 2007 Office System Add-In: Icons Gallery, ami letölthető a Microsoft oldaláról. A neve teljesen félrevezető, miután letöltöttük és kicsomagoltuk, kapunk egy Office2007IconsGallery.xlsm fájlt, ami ahogy a neve is mutatja egy makrót tartalmazó Excel dokumentum. Ennek használatához először is az Excel Options ablakban kapcsoljuk be a Show Developer tab in the Ribbon opciót:

    Excel: Show DeveloperTab

    Majd nyissuk meg a letöltött fájlt és engedélyezzük a makrók futását, ami után a Developer tabon új ikonokat fogunk látni:

    Ribbon Image Gallery

    A kilenc galéria bármelyikét kinyitva rengeteg ikon közül válogathatunk, a nevüket pedig úgy tudhatjuk meg, ha föléjük visszük az egeret, vagy rájuk kattintunk:

    Ribbon Image Gallery: HappyFace

    A kicsomagolt Excel fájl közvetlenül letölthető innen is.

     

    Technorati Tags: ,,,
    May 13

    SharePoint szerszámosláda - 2. rész

    Január végén összegyűjtöttem egy listát a SharePointos fejlesztésekhez jól használható eszközökről, azóta azonban ismét sok mindenbe futottam bele, így ideje kiegészíteni a korábbi sort:

    VSeWSS doksik és példák (Microsoft)

    Az előző listában már szerepelt a Windows SharePoint Services 3.0 Tools: Visual Studio 2005 Extensions, aminek továbbra is csak a VS 2005-t támogató 1.1 verziója érhető el. (Nyárra ígérik az 1.2 verziót, ami már a VS 2008-at is ismerni fogja.) Most viszont megjelent hozzá egy Guide, amiben leírások és példák segítenek eligazodni a VSeWSS használatában.

    Letöltés | Áttekintő cikk

    STSADM poszterek (Kirk Stark, Microsoft)

    Bár az STSADM neve szerint rendszergazdai eszköz, fejlesztők számára is nélkülözhetetlen. Kirk Stark készített néhány áttekintő posztert, ami segíthet eligazodni a parancssori paraméterek között.

    Letöltés

    STSADM Custom Extensions (Gary LaPointe)

    Talán nem közismert, de az STSADM-hez készíthetőek kiterjesztések. Gary LaPointe SharePoint MVP ebbe vetette bele magát, és már 103 újabb parancsnál jár. Aki szeret automatizálni, annak mindenképp érdemes megnéznie legalább a parancsok listáját.

    Honlap | Parancsok listája | Letöltés (WSP és forrás)

    BPA for WSSv3 (Microsoft)

    Szintén inkább üzemeltetői eszköz a Best Practices Analyzer for WSS 3.0, amit parancssorból indítva segíthet a szerver nem optimális beállításainak megkeresésében.

    Letöltés

    BDC Meta Man (LightningTools)

    A Business Data Catalog hasznos funkció, de elég rémisztő megszerkeszteni az adatokat leíró definíciós fájlokat. A LightningTools cég készített egy BDC Meta Man nevű eszközt, ami ebben sokat segíthet, a Developer verzió ingyenesen tölthető le.

    Honlap

    CodePlex projektek

    Érdemes néha körülnézni a CodePlexen, mert a nagy zaj ellenére lehet hasznos projekteket találni. Íme néhány SharePointtal kapcsolatos:

    SharePoint 2007 Features (Scot Hillier)

    23 feature-be csomagolt újdonság a SharePointhoz fejlesztőknek, rendszergazdáknak és végfelhasználóknak egyaránt. Számomra leghasznosabbnak a Unique column policy, a Minimal- és Placeholder master, Content type hierarchy, Print list, Log viewer, Toolbar manager és Debug config bizonyultak.

    Letöltés | Projekt honlap

    SharePoint Toolbox

    Még kicsit kezdetleges, de ígéretesnek tűnő projekt, egymástól független eszközökkel. Űrlap alapú hitelesítés használatánál a Profile Import Tool hasznos lehet.

    Letöltés | Projekt honlap

    SmartPart for SharePoint (Jan Tielens)

    Jan Tielens méltán népszerű SmartPartja is átköltözött a GotDotNetről a CodePlexre, itt még screencastot is találunk a használatáról.

    Letöltés | Projekt honlap

    SmartTools for SharePoint (Jan Tielens)

    Jan másik projektje a SmartParttól függetlenül folyamatosan bővül, egyelőre három WSS bővítményt tartalmaz: What's New Webpart, Autocomplete Text Field és Enhanced Site Actions. Érdemes figyelni, mert fokozatosan gyarapodik.

    Letöltés | Projekt honlap

    WSPBuilder (Carsten Keutmann)

    Úgy látszik nem én vagyok az egyetlen, ami nagyon nem szeret a WSS solution fájlokhoz manifest és DDF fájlokat készíteni, majd MakeCabot futtatni. Ez az eszköz segít ezeknek a fájloknak az előállításában, sőt már VS projekt sablon is létezik hozzá (ld. a kapcsolódó blog bejegyzést).

    Letöltés | Projekt honlap

    SharePoint Manager 2007 (Carsten Keutmann)

    Carsten másik projektje nagyon hasonlít az Ontolica SharePoint Exploreréhez, de támogatja a tulajdonságok módosítását is.

    Letöltés | Projekt honlap

    SharePoint Solution Installer

    Ez az eszköz a WSP fájlok telepítését hivatott megkönnyíteni. Nagy előnye, hogy nem csak grafikus felületet biztosít a telepítéshez, hanem telepítés előtt képes bizonyos beállítások ellenőrzésére is.

    Letöltés | Projekt honlap

    Useful Sharepoint Designer Custom Workflow Activities (Paul Kotlyar)

    A SharePoint Designer egészen jól használható támogatást nyújt workflow projektek fejlesztéséhez, de sajnos elég kevés activity-t biztosít a folyamatok megépítéséhez. Erről a projekt webhelyről további activity-ket tölthetünk le.

    Letöltés | Projekt honlap

    SharePoint Tips Utility Pack (Ishai Sagi)

    Szintén MVP projekt, amely eredetileg ismétlődő feladatokat ellátó kódok összefogására készült, például segítségével rekurzívan törölhetünk webhelyeket, több helyen egyszerre módosíthatunk listákat, több webhelyre egyszerre tehetünk ki kijelzőket stb. Részletesen nem próbáltam, de bekerült a szerszámosládámba.

    Letöltés | Projekt honlap

    Word 2007 Content Control Toolkit (Matt Scott)

    A Word 2007-ben bevezetett tartalom vezérlők adatkötésének konfigurálását segítő alkalmazás, melyet a Word dokumentum generálását bemutató cikksorozatban is használtunk.

    Letöltés | Projekt honlap

     

    May 05

    Word dokumentum generálása adatkötéssel - 6. rész: Végjáték

    Az előző részekben megszerzett tudásunkat felhasználhatjuk arra, hogy kibővítsük a SharePoint lista elemekkel kapcsolatos szolgáltatásait. A WSS listák beépített funkciói közé tartozik, hogy kiválóan integrálódnak Excellel, Outlookkal és Access-szel, de a Word kimaradt a sorból. Pedig milyen szép is lenne, ha egy névjegyalbum valamelyik eleméből egy kattintással megcímzett levelet generálhatnánk! Nem is olyan nehéz...

    Mivel a névjegyalbum típusú lista mezői ismertek, valamint azt is tudjuk, hogy hogyan néz ki nálunk egy levél címzése, ezért gyárthatunk egy Word sablont, meg némi extra kódot, ami a Word sablonba beírja a mezők értékeit. A kód egy ASPX oldalban fog futni, amit a _layouts mappába fogunk tenni és a felhasználó a névjegyalbum listában az egyes elemek helyi menüjéből tudja elérni.

    Először tehát a korábbiak alapján készítsük el a Word dokumentumot, legyen benne minden olyan mező, amit egy levél címzésénél használni szoktunk: vezetéknév, keresztnév, város, irányítószám, utca és házszám, sőt még egy cég nevet is beletehetünk, mert olyan mező is van a névjegyalbumban. Akár így:

    Sablon dokumentum

    Második lépésként használjuk a korábban megismert Word 2007 Content Control Toolkitet, hogy hozzákapcsoljuk a tartalomvezérlőinket például az alábbi szerkezetű XML fájlhoz, ami a DOCX fájlon belül lesz elérhető:

        <?xml version="1.0" encoding="utf-8"?>
        <Contact xmlns="http://www.msdnkk.hu/samples/Contact">
            <FirstName>György</FirstName>
            <LastName>Balássy</LastName>
            <Company>MSDN Kompetencia Központ</Company>
            <City>Budapest</City>
            <Zip>1117</Zip>
            <Address>Magyar Tudósok krt. 2.</Address>
        </Contact>

    Következő lépésben készítsünk egy ASPX oldalt, ahova a felhasználó el fog navigálni, amikor egy névjegyalbum listaelem szerkesztő menüjére kattint. Mivel az oldal a _layouts mappában fog lakni és application page lesz, származtassuk a LayoutsPageBase ősosztályból. Az oldal query string paraméterként meg fogja kapni a lista és a lista elem azonosítóját, amiből ki kell bogarászni egy SPListItem típusú objektumot, valahogy így (persze hibakezeléssel):

        private SPListItem GetListItem()
        {
            string listparam = this.Request.QueryString[ "listid" ];
            string itemparam = this.Request.QueryString[ "itemid" ];
    
            Guid listGuid = new Guid( listparam );
            int itemId = Int32.Parse( itemparam );
            SPList list = this.Web.Lists[ listGuid ];
            SPListItem item = list.Items.GetItemById( itemId );
    
            return item;
        }

    Ebből az SPListItem példányból elő kell állítani a fenti XML-t, amihez én egy saját Contact osztályt használtam, ami a SharePointos típusból tudja inicializálni magát és kisorosítva épp a kívánt XML-t adja.

    Meg kell írnunk azt a kódot, ami beteszi a sablonba az XML-t és visszaküldi a felhasználónak. Azt már korábban láttuk, hogyan tudunk egy XML partot betenni egy DOCX package-be. Itt most csak arra kell figyelnünk, hogy a sablon dokumentumunkból készítsünk egy munka másolatot, hiszen webes környezetben előfordulhat, hogy több felhasználó hívja meg ugyanezt az oldalt egyidőben. Ehhez feltételeztem, hogy a Word sablon dokumentumot egy WordExport nevű feature-ben fogom telepíteni. Így készül az ideiglenes munkafájl az SPUtility.GetGenericSetupPath metódus és a System.IO.Path osztály segítségével:

        string featureFolder = SPUtility.GetGenericSetupPath( @"TEMPLATE\FEATURES\WordExport" );
        string originalTemplatePath = Path.Combine( featureFolder, "Sablon.docx" );
        string currentTemplatePath = Path.GetTempFileName();
        File.Copy( originalTemplatePath, currentTemplatePath, true );
    

    Miután beírtuk a tartalmat a munkafájlba, vissza kell küldenünk azt a felhasználónak, például így:

        this.Response.ClearContent();
        this.Response.ClearHeaders();
        this.Response.AddHeader( "content-disposition", "attachment; filename=export.docx" );
        this.Response.ContentEncoding = Encoding.UTF8;
        this.Response.TransmitFile( currentTemplatePath );
        this.Response.Flush();
        this.Response.Close();

    És persze nem szabad elfeledkeznünk az ideiglenes állomány törléséről sem:

        File.Delete( currentTemplatePath );

    Ezzel tehát megvan a kód, már csak telepítenünk kell, amihez természetesen előbb egy feature-t készítünk belőle! Ehhez először is egy feature.xml leíró fájlra lesz szükségünk:

        <?xml version="1.0" encoding="utf-8"?>
        <Feature xmlns="http://schemas.microsoft.com/sharepoint/" 
            Id="{63b1e30f-b4e9-4caa-b8ed-3552103f06c5}" 
            Title="Word export"
            Description="Lehetővé teszi névjegy lista elemeinek exportálását Word dokumentumba."
            Version="1.0.0.1"
            Scope="Web"
            Hidden="false"
            >
            <ElementManifests>
                <ElementManifest Location="WordExportPage.xml"/>
            </ElementManifests>
        </Feature>
    

    A lényeg persze a WordExportPage.xml fájlba került, itt található ugyanis az exportálás menüpont hozzárendelése a névjegy lista (RegistrationId=105) elemeinek helyi menüjéhez (Location=EditControlBlock) és nézet oldali eszközsávjához (Location=DisplayFormToolbar):

        <?xml version="1.0" encoding="utf-8"?>
        <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
            <CustomAction 
                Id="MyDetailsLink"
                Title="Exportálás Wordbe"
                Description="Erre a linkre kattintva a lista elemet Word dokumentumba exportálhatja."
                RegistrationType="List"
                RegistrationId="105"
                Location="EditControlBlock"
                ImageUrl="/_layouts/images/doc16.gif"
                >
                <UrlAction Url="/_layouts/WordExport.aspx?listid={ListId}&amp;itemid={ItemId}" />
            </CustomAction>
    
            <CustomAction 
                Id="MyWordExportButton" 
                Title="Exportálás Wordbe" 
                Description="Erre a gombra kattintva a lista elemet Word dokumentumba exportálhatja."
                RegistrationType="List" 
                RegistrationId="105"     
                Location="DisplayFormToolbar"
                ImageUrl="/_layouts/images/doc16.gif"        
                >
                <UrlAction Url="/_layouts/WordExport.aspx?listid={ListId}&amp;itemid={ItemId}" />
            </CustomAction>
        </Elements>
    

    Érdemes megfigyelni, hogy az UrlAction Url attribútumában a {ListId} és az {ItemId} tokenek segítségével tudjuk átadni az oldalunk számára szükséges paramétereket.

    Ezt a feature-t aktiválva megjelenik a felhasználónak a névjegy lista elemein egy Exportálás Wordbe opció, melyre kattintva elnavigálhat az általunk készített WordExport.aspx oldalra, amely query string paraméterben megkapja, hogy a felhasználó melyik lista melyik elemére kattintott. Az oldal ezek alapján kibogarássza az eredeti lista elemet, majd fogja a sablon DOCX fájlt, készít róla egy másolatot a Temp mappába, beleírja a lista elem adatait, ezután visszaküldi a fájlt a felhasználónak, végül pedig letörni az ideiglenes állományt.

    Mindezt szerver oldalon anélkül, hogy Office lenne telepítve a szerverre, vagy ismernünk kellene az Office objektum modelljét!

    (Vége)

     

    April 30

    VB és VBA

    A magyar műszaki felsőoktatás egyik fellegvárában egy kiváló tanszék (félreértések elkerülése végett: nem a miénk) kitalálta, hogy tárgyat akar indítani "VB/VBA" témában. A levelezésből kiderült, hogy valóban Visual Basic 6-ra és Visual Basic for Applicationsre gondoltak. Igen, mindezt most, 2008-ban! Mi sem lehet hasznosabb annál, mint ha 10 éves technológiát kezdünk el tanítani egy olyan generációnak, amelyik 1-3 év múlva végez. Erre mondaná néhány kollégám: ez itt kérem abszurdisztán.

    A tárgy mögött álló szakmai indok szerint ennek azért van létjogosultsága, mert a Vista, a Windows Server 2008 és az Office következő verziója is támogatni fogja a VB-t és a VBA-t. Továbbá az is kiderült a levelekből, hogy következetesen keveredik a VB és a VBA neve, szerepe és célja. Mikor erre rájöttem, nem tudtam, hogy sírjak vagy nevessek. Különösen összevetve mindezt a stratégiai jellegű minőségfejlesztéssel.

    Néhány dolgot mindenesetre érdemesnek látok tisztázni:

    Ne keverjük össze az almát a körtével! Adott két nagyban hasonlító, de teljesen más célú környezet, a VB és a VBA. Ezen kívül adott két szempont, az egyik, hogy egy adott technológiára érdemes-e még fejleszteni, meg hogy az adott technológiával készült alkalmazások használhatóak-e még.

    Nyelvek: 1. VB

    A Visual Basic 6 nyelvet már 2002-ben (!) felváltotta a Visual Basic .NET a Visual Studio .NET-tel, aztán jött a VS 2003, majd a VS 2005 és most a Visual Basic 9-ről (!) beszélünk a VS 2008-ban! A két nyelv között ég és föld a különbség. Az a VB6 programozó, aki ma erőlködés nélkül megért egy LINQ-kel és generikus típusokkal, osztályokkal és kivételkezeléssel teletűzdelt Visual Basic 9 kódot, az előtt emelem a kalapom. Ennyit fejlődött a nyelv, nem beszélve a két runtime közötti óriási különbségről.

    Nyelvek: 2. VBA

    A Visual Basic for Applications a VB6 Office-ban, Corel-ban és tetszőleges egyéb környezetben történő felhasználása annak érdekében, hogy az alkalmazást kívülről egyszerűen programozhatóvá tegyék. A gyökerei VB6-ba nyúlnak vissza és azóta nem fejlődött, tehát kb. 10 éves technológiáról van szó. Nyilvánvalóan még sokáig supportált lesz, de új megoldások fejlesztése igencsak megkérdőjelezhető, mert

    "As of July 1, 2007, Microsoft will no longer offer VBA distribution licenses to new customers."

    Nyelvek: 3. Visual Studio for Applications (VSTA)

    A VSTA a VBA utódja abból a szempontból, hogy saját alkalmazásunkba programozói környezet építhető. Ez is .NET alapú:

    "Enables ISVs and enterprises to embed a streamlined IDE into their applications, accelerating customization development by end users, resellers, system integrators, and internal teams.  Includes support for Visual Basic and Visual C# along with other tools for application customization."

    Nyelvek 4. Visual Studio Tools for Office (VSTO)

    A VSTO az Office programozás jövője, azaz ebből a szempontból a VBA felváltója, méghozzá egyértelműen, már 2003-től kezdve. Már alapból a VS 2008 része és természetesen .NET alapú fejlesztést támogat. Kár is részletezni, hogy sokkal hatékonyabb, mint a VBA és ezé a jövő.

    Support lifecycle:

    Természetesen a VB6 és a VBA támogatott még jó sokáig, de ennek az az EGYETLEN oka, hogy tele van a világ ilyen kódokkal. Nem pedig az, hogy az MS arra buzdítana bárkit, hogy ezt használja.

    A VBA oldalon ez áll:

    "Microsoft does not expect to make significant enhancements to VBA."

    "As of July 1, 2007, Microsoft will no longer offer VBA distribution licenses to new customers."

    Ugyanitt ez javasolt helyette:

    "Microsoft is investing its application programmability resources in Microsoft® Visual Studio® Tools for Applications (VSTA) and its companion set of tools, Microsoft® Visual Studio® Tools for Office (VSTO). We encourage you to consider VSTA for new applications that require application programmability technology."

    Már 2003-ban óriási különbség volt a VSTO javára (lásd Comparing Microsoft Visual Basic for Applications 6.0 and Microsoft Visual Studio Tools for the Microsoft Office System - Office 2003!) és ez a szakadék az azóta eltelt években tovább növekedett. Már 2005-ben sem volt nehéz felsorolni 9 ütős érvet a VSTO mellett. És azóta eltelt újabb 3 év.

     

    April 28

    Informatika Tisztán - Csoportmunka modul

    Holnap kerül megrendezésre első alkalommal a tavalyi nagy sikerű Informatika Tisztán sorozat második, csoportmunkával foglalkozó szakmai napja a Sugár mozijában, amit további alkalmak fognak követni Budapesten és vidéken egyaránt. Múlt héten volt szerencsém végighallgatni az előadásokat és bátran állíthatom, hogy érdemes eljönni a rendezvényre.

    Ha valaki úgy dönt, hogy a nap utolsó előadásán is marad, őt lesz szerencsém megbombázni egy nagy adag Windows SharePoint Services üzemeltetési információval. Az előadás annyiban formabontó, hogy a rendszergazdák számára legfontosabb felügyeleti funkciók bemutatása közben nulláról építünk fel és üzemelünk be egy WSS-t. Ebből talán már érezhető, hogy elég demó intenzív lesz az előadás.

    Tudomásom szerint nem lesz nyomtatott handout, aki esetleg mégis szeretne jegyzetelni, annak azt javaslom, hogy töltse le az előadás fóliáit innen, nyomtassa ki a számára szimpatikus formátumban és hozza el magával. A PPT fájlban ugyanis számos olyan rejtett dia, többnyire képernyőkép van, amit holnap nem fogok bemutatni, de a demók során látni fogunk.

    Akit érdekel az Exchange, SharePoint és az Office üzemeltetői szemmel, tartson velünk!

     

    April 20

    Word dokumentum generálása adatkötéssel - 5. rész: A kód neve

    Az előző részben láttuk, hogyan kapcsolódik a DOCX állományban lévő customXml part kétirányú adatkötéssel a content control vezérlőkhöz. Ha ezzel a módszerrel akarunk programozottan dokumentumot előállítani, akkor már csak egyetlen lépés van hátra: olyan kódot kell írnunk, amely belenyúl az Open XML állományba és felülírja a korábban már odatett XML partot, aminek tartalma azután az adatkötéseken keresztül automatikusan megjelenik a felhasználó számára.

    A feladat megoldásában a System.IO.Packaging névtér nagy segítségünkre lesz. A Package osztály segítségével meg tudjuk nyitni a DOCX fájlt ZIP tudomány nélkül, csak az elérési útját kell ismernünk:

        // A sablon dokumentum megnyitása.
    Package package = Package.Open( path, FileMode.Open, FileAccess.ReadWrite );

    A következő lépés az XML part megkeresése. Az egyes part-okra a csomagon belüli URI-jük segítségével hivatkozhatunk. A Word 2007 Content Control Toolkit által generált Item1.xml itt található:

        // Az XML part útvonala a sablon dokumentumban.
        Uri partUri = new Uri( "/customXml/Item1.xml", UriKind.Relative );

    Lekérdezhetjük, hogy egyáltalán létezik-e ilyen part a dokumentumban:

        // Ellenőrizzük, hogy a sablonban van-e XML part.
        if( package.PartExists( partUri ) )
        {
            // itt folytatjuk...

    Ha létezik, akkor el is kérhetjük, mégpedig egy PackagePart formájában:

        // Az XML part elkérése.
        PackagePart xmlPart = package.GetPart( partUri );

    Az XML part tartalmát streamként tudjuk elérni. Ha például egy content nevű változóban megtalálható a beírandó XML UTF-16 formátumban, akkor annak beírására használhatjuk például az alábbi kódot:

        // Az XML part tartalmát kezelő stream elkérése.
        using( Stream xmlStream = xmlPart.GetStream() )
        {
            // A stream hosszának beállítása, hogy rövidebb szöveg esetén a régi tartalom levágódjon.
            xmlStream.SetLength( content.Length );
    
            // Az új tartalom beírása a streambe. Unicode kell, mert az XML stringben utf-16 szerepel.
            using( StreamWriter writer = new StreamWriter( xmlStream, Encoding.Unicode ) )
            {
                writer.Write( content );
                writer.Flush();
                // writer.Close(); automatikus a Dispose miatt.
            }
    
            // Az XML part mentése.
            // xmlStream.Close(); automatikus a Dispose miatt.
        }

    Nincs is más hátra, mint a dokumentum módosításait elmenteni a diszkre:

        // A dokumentum változásainak mentése.
        package.Flush();
        package.Close();
    

    Miért vacakoltam az UTF-16 kódolással? Azért, mert a beírandó XML előállítására szerintem az a legegyszerűbb megoldás, ha készítünk például egy Contact osztályt, annak beállítjuk úgy a tulajdonságait, ahogy azokat a Word dokumentumban látni szeretnénk, majd egyszerűen XmlSerializer segítségével kisorosítjuk:

        XmlSerializer serializer = new XmlSerializer( typeof( Contact ) );
    
        using( StringWriter writer = new StringWriter( CultureInfo.InvariantCulture ) )
        {
            serializer.Serialize( writer, this );
            result = writer.ToString();
            // writer.Close(); automatikus a Dispose miatt.
        }

    Mivel itt StringWritert használok, az eredmény a .NET Framework sztringjeinek alapértelmezett kódolása, azaz "utf-16" lesz, amivel tapasztalataim szerint a Word nem birkózik meg. Persze biztosan lehet egyszerűbben is...

    Egyetlen dologra hívnám fel a figyelmet - azon kívül természetesen, hogy a fenti kód a probléma megoldásának igen egyszerű módja: kódból módosítunk egy Word dokumentumot, de mindezt úgy tesszük, hogy nem használjuk hozzá a Word objektum modelljét. Sőt, nem használjuk a Word egyik komponensét sem, azaz a fenti kód működik akkor is, ha nincs Word a gépen! Ez igen fontos fegyvertény az Open XML mellett, hiszen aki próbált már szerver oldalon Office dokumentumot előállítani az biztosan belefutott abba a problémába, hogy az Office-t nem kiszolgáló oldali automatizálásra tervezték. Ez még a 2007-es verzióra is igaz, de nem az Open XML-re!

    Ezt a tudásunkat felhasználva akár a SharePointot is kiegészíthetjük, készíthetünk például egy olyan új funkciót a Névjegyalbum listákba, amely lehetővé teszi a névjegy lista elemek alapján megcímzett, fejléces levelek egy kattintással történő előállítását. Ehhez nem kell mást tennünk, mint...

    (folytatjuk)

    April 19

    Word dokumentum generálása adatkötéssel - 4. rész: Kapcsolat

    Ahogy az előző részben láttuk, a content control-ok vagy más néven a structured document tags szolgáltatás az Office dokumentumokban lehetővé teszi a formázás és az adatok elkülönítését. Két korlátozó körülményt azonban mindenképpen meg kell említenünk:

    1. Ez a szolgáltatás egyelőre csak a Word 2007-ben érhető el, az Office család más termékeiben nincs ilyen lehetőség.
    2. Elég fájó, de sajnos nincs táblázat vezérlő, sőt az ismétlődéseket (pl. felsorolásokban) sem tudja kezelni ez a funkció. Mivel ez sokaknak fáj, ezért várhatóan az Office 14-ben vagy talán már egy javítócsomagban megkapjuk ezt is.

    Nem beszéltünk még arról, hogy hol tárolódnak az adatok és hogyan kapcsoljuk azokat a vezérlőkhöz. Az adatok a DOCX állományon belül egy önálló XML fájlban tárolódnak, alapértelmezés szerint a \customXml mappában.Itt nyers XML-t kell elképzelni, semmi Open XML specifikus elem nincs benne, az viszont praktikus, ha van egy önálló, egyedi névtere. Ha például a dokumentumunk egy levél, amelyben a címzett és a feladó adatait programozottan akarjuk kitölteni, akkor a szükséges adatokat betehetjük a \customXml\item1.xml fájlba az alábbi formában:

        <?xml version="1.0" encoding="utf-16"?>
        <Contact xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                         xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
                         xmlns="http://www.msdnkk.hu/samples/Contact">
            <FirstName>György</FirstName>
            <LastName>Balássy</LastName>
            <Company>MSDN Kompetencia Központ</Company>
            <City>Budapest</City>
            <Zip>1117</Zip>
            <Address>Magyar Tudósok krt. 2.</Address>
            <Sender>Feladó Ferenc</Sender>
        </Contact>

    Ennek az XML fájlnak az írása és olvasása megoldható a korábban már említetett Packaging API segítségével, hiszen ez is egy Open XML document part.

    Hogyan kapcsoljuk ezt a fájlt a csomag többi részéhez? A \word\_rels\document.xml.rels fájlt kell kiegészítenünk az alábbiakkal:

        <?xml version="1.0" encoding="utf-8"?>
        <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
            <!-- Sok Relationship elem van itt már... -->
            <Relationship 
                Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml" 
                Target="../customXml/item1.xml" 
                Id="R0fbcbf7dffdc49b6" />
        </Relationships>

    A [Content_Types].xml fájlhoz nem kell nyúlnunk, mert abban már szerepel egy definíció, amely magában foglal minden XML kiterjesztésű állományt. Kiegészíthetjük viszont egy XML properties résszel:

        <?xml version="1.0" encoding="utf-8" ?>
        <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
            <Default Extension="xml" ContentType="application/xml" />
            <!-- A dokumentum többi része itt Override elemekben -->
            <Override 
                PartName="/customXml/itemProps1.xml" 
                ContentType="application/vnd.openxmlformats-officedocument.customXmlProperties+xml" />
        </Types>

    Az XML properties fájlban további tulajdonságokat adhatunk meg, például egy ún. data store ID-t:

        <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
        <ds:datastoreItem 
            ds:itemID="{70372b4c-0b6e-4f5d-9fa2-39118fe7a889}" 
            xmlns:ds="http://schemas.openxmlformats.org/officeDocument/2006/customXml" />

    Ha több customXml partunk is van, akkor még egy ds:schemaRefs elem segítségével összekapcsolhatjuk a data store-t egy adott XML sémával. Ennek akkor van jelentősége, ha egyébként a dokumentumban több azonos sémájú XML part is van, mert így meg tudjuk adni, hogy pontosan melyikhez kívánunk kapcsolódni.

    A tárolást tehát megoldottuk, következő probléma, hogy az egyes vezérlőket hogyan kapcsoljuk az XML fájlban lévő elemek valamelyikéhez. A megoldás a cikksorozat címében oly sokszor említett adatkötés. Nem is akármilyen, hanem kétirányú! Tehát akár kódból módosítjuk az XML állományt, akár a felhasználó ad Wordben új értéket valamelyik vezérlőnek, a másik automatikusan frissül, ezzel semmilyen további munkánk nincsen!

    Az adatkötés megadása a word\document.xml fájlban történik az egyes w:sdtPr elemekbe ágyazott w:dataBinding elemekkel. Itt két dolgot kell megadnunk:

    1. Egy névtér aliast a w:prefixMappings attribútumban.
    2. A névtér aliast használó és az XML dokumentumban egy elemet azonosító XPath kifejezést a w:xpath attribútumban.
    3. Ha több azonos névterű XML partunk is van, akkor még egy data store ID-t, ami alapján a Word megtalálja majd az XML partot. Ezt a w:storeItemID attribútumban lehet megadni.

    Végül például egy Keresztnév  értéket bekérő vezérlő, amely a fent bemutatott XML dokumentum FistName mezőjéhez van kötve így festhet:

        <w:sdt>
            <w:sdtPr>
                <w:dataBinding 
                    w:prefixMappings="xmlns:ns0='http://www.msdnkk.hu/samples/Contact'" 
                    w:xpath="/ns0:Contact[1]/ns0:FirstName[1]" 
                    w:storeItemID="{70372b4c-0b6e-4f5d-9fa2-39118fe7a889}" />
                <w:rPr>
                    <w:i />
                </w:rPr>
                <w:alias w:val="Keresztnév" />
                <w:tag w:val="Keresztnev" />
                <w:id w:val="370331103" />
                <w:placeholder>
                    <w:docPart w:val="DefaultPlaceholder_22675703" />
                </w:placeholder>
                <w:text />
            </w:sdtPr>
            <w:sdtContent>
                <w:r w:rsidR="00136851" w:rsidRPr="00136851">
                    <w:rPr>
                        <w:i />
                    </w:rPr>
                    <w:t>Keresztnév</w:t>
                </w:r>
            </w:sdtContent>
        </w:sdt>

    A jó hír az, hogy mindezt nem kell kézzel odaheggesztenünk minden egyes vezérlőhöz. Bár sem a Wordben, sem pedig a Visual Studioban nincs erre eszköz, szerencsére a CodePlexről letölthetjük a Word 2007 Content Control Toolkitet, ami sokat segíthet a munkában. Egyetlen képernyős alkalmazásról van szó és mivel Windows Formsban készült, kiválóan olvasható Reflectorral (megjegyzem tanulni is lehet belőle, például nagyon érdekes, hogyan vezérli ez a külső alkalmazás a Word kurzorát):

    Content Control Toolkit

    Az alkalmazás használata nagyon egyszerű:

    1. Készítsük el Wordben a sablon dokumentumot és tegyük bele a vezérlőket a Developer fülről.
    2. Töltsük be a Word dokumentumot a Content Control Toolkit (CCT) eszközbe, ami után bal oldalon megjelennek a vezérlők.
    3. A jobb alsó Create a new Custom XML Part linkre kattintva adjunk új XML partot a dokumentumhoz.
    4. Készítsük el azt az XML dokumentumot például Visual Studioban, amit egyszerűen elő tudunk állítani később kódból, és amilyen formátumú fájlt majd a DOCX állományba szeretnénk helyezni.
    5. Másoljuk be az XML tartalmát az Edit View fülön lévő mezőbe.
    6. Váltsunk vissza Bind View nézetre, ahol megjelenik az XML hierarchia.
    7. Jelöljük ki a bal oldali listában valamelyik vezérlőnket (ez kell), majd a jobb oldali hierarchiában fogjuk meg a hozzá illő XML elemet és dobjuk rá a vezérlőre. Ekkor elkészül az adatkötés. Ha inkább kézzel szerkesztenénk a paramétereken, akkor kattintsunk duplán bármelyik vezérlő sorára és a felbukkanó ablakban adjuk meg az adatokat.
    8. Végül ne felejtsük el menteni a dokumentumot.

    Ezzel még csak az adatkötés paraméterezése készült el, illetve az eszköz megoldja azt is, hogy a DOCX állományban létrejöjjön egy XML part. Ami még hátra van, az a DOCX állományban lévő XML tartalmának módosítása kódból. De ezt majd legközelebb, addig is ezt érdemes kipróbálni!

    (folytatjuk)

    April 17

    Informatika Tisztán - Csoportmunka

    Aki tavaly figyelemmel kísérte az Informatika Tisztán sorozatot biztosan emlékszik, hogy érdemes volt ellátogatni a Sugárba vagy valamelyik vidéki helyszínre. A tavalyi Rendszerfelügyelet téma mellé áprilistól új téma kerül terítékre, mégpedig a csoportmunka. A Csoportmunka és Kommunikáció modul az Office 2007, az Exchange Server 2007 és a Windows SharePoint Services 3.0 területeire fókuszál, elsősorban üzemeltetői szemmel.

    A SharePoint témakörhöz van egy kis közöm, így bátran tudom ajánlani azoknak, akik még egyáltalán nem használják és nem tudják, hogy mire lehet képes, és azoknak is, akik már elhatározták, hogy szeretnék használni, csak még nem tudják, hogyan tegyék meg a kezdő lépéseket. A nap utolsó előadásában nulláról építünk fel egy Windows SharePoint Services portált, így lépésről lépésre tudunk végigmenni azokon a beállításokon, amelyekkel a rendszergazdák biztosan találkozni fognak. A felhasznált operációs rendszer Windows Server 2003 lesz, tehát bárki ki tudja próbálni az elhangzottakat, ha rendelkezik ilyen licenccel. Ha valakit mégis a Windows Server 2008-ra történő WSS telepítés érdekel, annak szintén érdemes eljönni az előadásra, mert a WSS beállításai azonosak, az operációs rendszer előkészítésével kapcsolatban pedig már korábban készült magyar nyelvű screencast.

    A Csoportmunka előadás összesen 7 alkalommal lesz megtekinthető, ebből kettő budapesti és az első alkalom 2008. április 29., kedd. Várunk mindenkit!

    Bővebb információk az Informatika Tisztán eseménysorozat honlapján találhatóak.