More servicesWindows Live
HomeHotmailSpacesOneCare
 
MSN
Sign in
 
 
Spaces home  Balássy GyörgyProfileFriendsBlogMore Tools Explore the Spaces community
View space
Bátyai Krisztián
View space
Nacsa Sándor
View space
Markó Krisztián
View space
tamas_gal
View space
Bátorfi Zsolt

Balássy György

RD blog
August 12

.NET 3.5 SP1 = Adatkezelés vNext

Tegnap elkészült az SQL Server 2008 és hozzá a .NET Framework 3.5 és a Visual Studio 2008 első javítócsomagja. Azonban nem csak egy egyszerű javításról van szó, hanem számos olyan technológia válik ezáltal elérhetővé, amely jelentősen kibővíti a lehetőségeinket az adatkezelés terén.

Már hosszú ideje teljesen nyilvánvalóvá vált, hogy az adatkezelés terén drasztikus újításokra van szükség, hogy az ORM jellegű favágómunkát egyszerűsítsük. Bár már a korábbi Visual Studio verziókban is számos varázsló segítette ezt a munkát, az igazi változást a .NET Framework 3.5 verziójában megjelent LINQ to SQL hozta el, amely a Visual Studio 2008 RTM változatban dizájner támogatást is kapott. A lekérdezések nyelvbe integrálásával Anders Hejlsberg megint nagyot alakított, azonban ennek a megközelítésnek van egy jellegzetessége: szorosan kapcsolja össze az adatbázist a forráskód osztályaival és objektumaival. Ez egyesek szerint a technológia gyenge pontja, mások szerint kevésbé; a lényeg, hogy néha praktikus, néha zavaró.

Nem véletlenül nézett a fejlesztői társadalom nagy várakozással a LINQ to SQL-re épülő ADO.NET Entity Framework elé, amely nagyobb rugalmasságot ad a fejlesztők kezébe: segítségével definiálható a jól ismert egyed-kapcsolat modellen alapuló Entity Data Model (EDM), sőt le is kérdezhető a hozzá fejlesztett Entity SQL nyelv segítségével. Mindez lehetővé teszi, hogy az adatbázis-szerkezet pontos ismerete nélkül kezeljünk adatokat, pusztán a logikai szinten mozogva.

Sokak szerint ez a Microsoft első igazi ORM megoldása (szerintem a LINQ to SQL is már az), amely megpróbál minden adatkezelési problémára megoldást adni. Lévén az adatkezelési problémák tere óriási, így a technológia sem lett egyszerű: új XML leírások, modellek, dizájnerek és lekérdező nyelv rögös útjain kell haladnia a fejlesztőnek. Nem véletlen, hogy az Entity Framework nem készült el korábban, hanem csak most, az SP1-ben teszi a Microsoft elérhetővé – bár sokak szerint a technológia még nem teljesen életképes. Lássuk be, valahol mindent el kell kezdeni, ez az 1.0 változat.

A LINQ to SQL és az Entity Framework két kiváló technológia, mindkettő remekül programozható .NET-ből. De mi van akkor, ha a kliensnek fogalma sincs a .NET Frameworkről? Akkor megtehetjük, hogy kipublikálhatjuk az adatokat például egy webszolgáltatáson keresztül, hiszen az ráadásul (elvileg) platform független is. Bár mi a Visual Studio dizájner támogatásának köszönhetően nagyon könnyen írunk és hívunk webszolgáltatásokat, ez nem minden környezetben ilyen egyszerű. (Aki próbált már például JavaScriptből SOAP protokollon kommunikálni, tudja, hogy miről beszélek.) Ráadásul nem is mindig szükséges, sokszor tényleg csak alapműveletekre, leggyakrabban szűrt lekérdezésekre van szükség, amihez a webszolgáltatás csak felesleges overhead. Van a SOAP-nál egyszerűbb módszer, ami tökéletesen működik az interneten, úgy hívják Representational State Transfer, azaz REST. Sokat lehetne arról vitatkozni, hogy pontosan mitől lesz egy szolgáltatás RESTful, abban azonban minden szerző egyetért, hogy a kérések lényege az URL-ben van: nem bohóckodunk a metódushívás és a paraméterek csomagolásával, mindet beleírjuk az URL-be, lehetőleg query string paraméterek nélkül. Egy URL-re HTTP kérést küldeni és a választ feldolgozni pedig a mai világban minden nyelvből lehet. Képzeljünk el egy egyszerű webkijelzőt vagy sidebar gadgetet, ami mögött nem ülhet DLL, vagy egy böngészőbe ültetett Flash vagy Silverlight plugint, amely az interneten keresztül szerezné be a szükséges adatokat. De persze a REST használható vastag kliens környezetben is, tipikusan akkor, ha egyszerű interfészt kell adni vagy hívni a platformfüggetlenség érdekében. Ezekben az esetekben segíthet a .NET Framework 3.5 SP1-ben megjelent ADO.NET Data Services, gyerekkori nevén az “Astoria”.

Ha már web és adatkezelés: a Microsoft szerint annyira gyakori az adatkezeléssel kapcsolatos programozási feladat webes környezetben, hogy itt is lehetne fordítani az eddigi hagyományokon: ahelyett, hogy a korábbiakhoz hasonlóan nulláról építenénk fel egy adatbázison alapuló weboldalt, hagyjuk, hogy az ASP.NET Dynamic Data keretrendszer automatikusan felépítse azt nekünk és mi csak testreszabjuk azt az igényeinknek megfelelően. Ezt hívják data scaffoldingnek. Természetesen a háttérben LINQ to SQL vagy Entity Framework alapú adatmodell dolgozik, a testreszabást pedig az ASP.NET alapjai, mesterlapok és új vezérlők biztosítják. Ez a technológia korábban BLinq néven futott, akkor próbaként megcsinálták vele a www.asp.net oldal prototípusát, majd dolgoztak rajta közel 2 további évet. Természetesen ez is 1.0 technológia, de bízunk az ASP.NET csapatban, amely Scott Guthrie vezetésével már sokat tett le az asztalra.

Mindezek csak a .NET Framework 3.5 SP1 újdonságai, de itt van még az SQL Server 2008 is. Meg sem próbálom leírni azt a rengeteg újítást, amit 3 év alatt beépítettek, csak kiemelek két dolgot. Letölthető a Microsoft Sync Framework v1, amely elsősorban az ún. occasionally connected alkalmazások fejlesztéséhez nyújt segítséget, amelyek néha a hálózaton el tudják érni a működésükhöz szükséges adatbázis szervert és webszolgáltatásokat, máskor nem. A Sync Framework provider alapú, a Microsoft ADO.NET, fájl rendszer és RSS-ATOM feedek szinkronizálásához szükséges providereket szállít. Mindezek egyébként nem csak kliens-szerver, hanem peer-to-peer modellben, akár WCF felett is használhatóak, sőt van támogatás mobil eszközre és SQL Server Compact Editionre is. Ha SQL Server 2008-cal kombináljuk a Sync Services for ADO.NET v2-t, akkor még az SQL Server 2008 change tracking szolgáltatását is kihasználhatjuk. (Most készült el a Sync Services for ADO.NET v2, amely az új Sync Framework v1-re épül, annak részeként érhető el. A v1 még önálló volt.)

A másik SQL Server 2008-cal kapcsolatos technológia, amit ki kell emelnem, az SQL Server Data Services (nem összekeverendő az ADO.NET Data Services-zel). Az SSDS lényegében egy hosztolt adatközpont szolgáltatás, amelyhez a Microsoft adja a hardvert, a szoftvert, az üzemeltetést, megbízhatóságot, rendelkezésre állást, mindent. Bár a háttérben SQL Serverek ketyegnek, nem egyszerű relációs adatbázis szolgáltatásról van szó: attribútum-érték párokat tárolhatunk a rendszerben, amely így “minőségileg többre képes szupererőforrás” szolgáltatássá válik. A szolgáltatás egyelőre béta változatban érhető el.

Mindez csak néhány újítás azok közül, amikkel találkozhatunk, ha beleássuk magunkat a .NET Framework 3.5 SP1-be. Számos új funkció és természetesen javítás is található még a csomagban az ASP.NET, WinForms és WPF fejlesztők vagy éppen a TFS-t használó fejlesztőcsoportok számára. A hangsúly azonban az adatkezelésen van.

Kezdhetünk tanulni.

 

Linkek és letöltések:

 

July 24

Számok a felhőről

Nacsa Sándor blogjában olvastam az SQL Server Data Servicesről, ami lényegében egy a “felhőben” elérhető adatközpont szolgáltatás. Az alapja természetesen SQL Server és úgy valósították meg, hogy világszerte garantálja a szükséges megbízhatóságot és rendelkezésre állást. Ilyenkor persze felmerül az emberben, hogy milyen infrastruktúra is van a háttérben?

Találtam néhány korábbi adatot:

A Microsoft 300.000 szerverből álló konténer farmot épít Chicagoban. A tervek szerint ez a szám havonta 20.000 (!) szerverrel fog nőni. Próbáljuk belőni a nagyságrendet! A Facebook most 10.000 szerverrel üzemel. Tehát havonta 2 Facebook pluszban. A Google becslések szerint 450.000 szervert üzemeltetett 2006-ban világszerte.

Mindebből tisztán látszik, hogy olyan jövőben gondolkodnak, amelynek az alapjait a felhőben biztosított szolgáltatások jelentik. A Live Search, az MSN és a Windows Live még csak az első lépések, íme néhány szám ezekről (forrás: Bink):

MS online services stats

Érdekes feladat lehet ekkora számokra tervezni.

July 23

Autópálya információk SMS-ben

Biztos sokak által ismert, hogy az autópályákkal kapcsolatos aktuális információk SMS-ben is lekérdezhetőek. Én nem vagyok SMS rajongó, főként vezetés közben nem, ezért inkább készítettem egy Windows Mobile alkalmazást.

A protokoll nagyon egyszerű, SMS-t kell küldeni a +36 70 7774636 számra M0, M1, M3 vagy M7 tartalommal és általában 2 SMS-ben jön a válasz (valamikor később). Windows Mobile 5-től kezdve .NET Compact Framework segítségével könnyen megy az SMS küldés: a Microsoft.WindowsMobile.PocketOutlook névtérben lévő SmsMessage osztályt jól kitalálták:

    SmsMessage message = new SmsMessage();
    message.To.Add( new Recipient( this.txtPhoneNumber.Text ) );
    message.Body = speedwayName;
    message.RequestDeliveryReport = this.chkReceipt.Checked;
    message.Send();        
A felhasználói felület megalkotása mindig kényes egy mobil alkalmazás esetén, így elgondolkodtam azon, hogy hogyan akarom a válasz SMS-eket megjeleníteni. A Microsoft.WindowsMobile.PocketOutlook.MessageInterceptor osztály lehetőséget ad arra, hogy az alkalmazásom értesítést kapjon, ha beérkezik egy üzenet, de így az olvasást biztosító felhasználói felület megvalósítása az én feladatom maradna. Az alapértelmezett buborékos megjelenítéshez használt rendszerfont mérete szerencsére elég nagy ahhoz, hogy még vezetés közben is el tudjam olvasni. Ráadásul így bezárhatom az alkalmazást, visszatérhetek a GPS-hez, ami praktikus, hiszen a válaszok sokszor percekkel később jönnek.

A másik felhasználói felülettel kapcsolatos kérdés az volt, hogy hogyan akarom a kérést elküldeni. Egy desktop alkalmazásnál nem probléma, combo boxból kiválasztom, hogy melyik autópálya érdekel és egy gombra kattintva indul is az SMS. Vezetés közben viszont kizárt, hogy ezt meg tudjam tenni, így a bazi nagy gombos megvalósítást követtem, így nem kell stylus, elég az ujjam, bármilyen nagy is. Némi Mio-szerű fekete dizájnnal megspékelve ilyen lett a főablak:

SpeedwayInfo Main ablak

Mivel a telefonszám nem sűrűn változik, ezért a gyors megoldást választottam, bedrótoztam az alkalmazásba.

Probléma volt, hogy a sikeres vagy sikertelen SMS küldésről hogyan adok visszajelzést a felhasználónak (magamnak). Úgy döntöttem, hogy a hang a legkézenfekvőbb megoldás, mert ez vonja el legkevésbé a figyelmemet a vezetésről. Kerestem két WAV fájlt és erőforrásként beágyaztam a szerelvénybe, a tartalmukat pedig a Assembly.GetExecutingAssembly().GetManifestResourceStream( "SpeedwayInfo.Sounds.Ok.wav" ) metódus meghívásával kérdezem le. A stream lejátszásához nem találtam felügyelt osztályt, így kellett egy kis P/Invoke:

    [DllImport( "CoreDll.DLL", EntryPoint = "PlaySound", SetLastError = true )]
    private extern static int WCE_PlaySound( string szSound, IntPtr hMod, int flags );

    [DllImport( "CoreDll.DLL", EntryPoint = "PlaySound", SetLastError = true )]
    private extern static int WCE_PlaySoundBytes( byte[] szSound, IntPtr hMod, int flags );

Miután sikerült a streamet byte tömbbé alakítani, a lejátszás már csak egy sor:

    Sound.WCE_PlaySoundBytes( this._soundBytes, IntPtr.Zero, (int) ( Flags.SND_ASYNC | Flags.SND_MEMORY ) );

Íme néhány tanulság:

  • Mobil alkalmazás esetén a felhasználói felület kialakítása mindig kritikus. Desktop alkalmazásnál is, de itt még inkább.
  • A felhasználói felület kitalálása és megfelelő kialakítása gyakran több időt visz el, mint a kódolás.
  • Nem csak egér van a világon :)
  • A PocketOutlook névtér nagyon jól használható.
  • Compact Frameworkön is van P/Invoke, nem kell megijedni tőle.

Ha valakit érdekel, az alkalmazás letölthető, legalább Windows Mobile 5.0 és Compact Framework 3.5 kell neki.

July 14

Zermatt

Zermatt egy kisváros Svájc déli részén, mindössze tíz kilométerre az olasz határtól. A kb. 5500 fős település zsákfalu, 1620 méteres tengerszint feletti magasságban egy völgy végében, egy gleccser közelében fekszik. Érdekesség, hogy a tiszta levegő megóvása érdekében belső égésű motorokkal hajtott autók nem hajthatnak be a városba. Síparadicsom, csendes kisváros gyönyörű környezetben. Mi vezette a Microsoft fejlesztőit arra, hogy épp ezt a várost válasszák egy fejlesztői keretrendszer kódnevévé?

Talán mert mint minden határközeli svájci város, ez is a környező nemzetek, hagyományok olvasztótégelye. A “Zermatt” pedig egy új, Microsoft fejlesztésű developer identity framework kódneve.

A világban egyre inkább előtérbe kerül a hagyományos felhasználónév-jelszó pároson alapuló hitelesítési mechanizmusok leváltásának szükségessége. Az egyik lehetséges megoldás az ún. claims-based hitelesítés, amikor az alkalmazás tetszőleges információkat (claim) kérhet a felhasználótól és azok alapján határozza meg, hogy a felhasználónak mihez van joga és mihez nincs. (Na, ezt durván leegyszerűsítettem.) Ilyen hitelesítési mód például az MSDN Kompetencia Központ oldalán általunk is használt Windows CardSpace alapú bejelentkezés, amit egységesen ez az ikon jelez minden weblapon a világhálón:

CardSpace logo

Amikor ezt én annak idején megvalósítottam, gyakorlatilag semmilyen támogatás nem volt hozzá, minden vezérlőt, JavaScriptet egyedileg kellett megírnom. A tapasztalatokból itt cikksorozat is született (1, 2, 3, 4, 5), és nem én voltam egyedül a világon, aki nagyon várta, hogy a Microsoft keretrendszer szintű támogatást adjon a CardSpace alapú bejelentkezéshez ASP.NET alkalmazások esetére: vezérlőket és objektum modellt, ami végül egy standard IPrincipal objektumot ad eredményül anélkül, hogy mindenféle részlettel, például token összeállítással és titkosítással kellene közvetlenül foglalkoznunk.

Most mindez megtörtént, ez a keretrendszer a “Zermatt”, ráadásul nem csak ASP.NET alkalmazásokat támogat, hanem tetszőleges .NET-es alkalmazásban, például WCF környezetben is használható. Jelen pillanatban a keretrendszer nyilvános béta változata érhető el a Connect oldalon. További információkat Vittorio Bertocci blogbejegyzéséből tudhatunk meg, vagy aki a fejlesztői részletek iránt érdeklődik, annak Keith Brown whitepaperjét tudom ajánlani.

 

July 10

ASP.NET AJAX jövőkép

Korábban már írtam néhány olyan komponensről vagy szolgáltatásról, melyek a tervek szerint az ASP.NET AJAX részei lesznek. Nos, a jelek szerint mégsem :(

Tavaly elkezdtem boncolgatni a Microsoft AJAX Library azon részeit, amik még nem a támogatott csomag részei, hanem csak az ASP.NET Futures csomagban érhetőek el. Ezek közül számomra két terület különösen kedves, a kliens oldali vezérlők és a kliens oldali deklaratív adatkötés. Akik esetleg nem látták az erről szóló előadást a tavalyi Web Konferencián:

  • A kliens oldali vezérlők JavaScriptben implementált osztályok, amik a szerver oldali vezérlőkhöz nagyon hasonlóan viselkednek. Létezik például Sys.Preview.UI.TextBox osztály, aminek van Text tulajdonsága, amit a get_Text és set_Text metódusokkal lehet kiolvasni. Elfedi az egész HTML DOM-ot és a böngészőfüggő részleteket, ráadásul a modell teljesen ismerős a .NET világból, csak a szintakszis JavaScriptes.
  • A kliens oldali adatkötés lehetővé teszi, hogy kliens oldali vezérlőket kapcsoljunk egymáshoz, vagy éppen adatokhoz, sőt mindezt deklaratívan XML-Script formátumban megtehetjük.

Legalábbis úgy volt, hogy majd egyszer megtehetjük. A konferencia idején még nagyon kezdetleges változatban volt mindez elérhető, alap funkciók működtek és az út világos volt, hogy merre haladunk. Mivel azonban sok hír nem látott nyilvánosságot ezeknek a funkcióknak a jövőjéről, bedobtam egy levelet a Microsoft Regional Director levlistára és hamarosan meg is jött Scott Guthrie válasza, majd pár nappal később az információk publikusan is megjelentek a CodePlexen. Érdemes elolvasni az ott közzétett ASP.NET AJAX Roadmap doksit, számos változást terveznek:

  • Ami szimpatikus, hogy a sokféle közzétételi formát egy kicsit gatyába rázzák, jobban követhető lesz, hogy mi minek a részeként érhető el és honnan, mi támogatott és mi nem. Ez jó.
  • Nagy hangsúlyt fordítanak a kliens oldali adatkezelésre, így a template alapú adatkötésre is. Ez is jó.
  • Sajnos nem vagyok kibékülve azzal a szintakszissal, amit majd el kell viselnünk. Íme egy példa, a feladat megérteni, hogy mit csinál (ennél van “szebb” is :)):

<div id=”repeater1”></div>

<div id=”template1” class=”sys-template”>
  <h2><a href=”{{ ‘products/’ + id }}”>{{name}}</a></h2>
  <p>{{description}}</p>
</div>

<script type=”text/javascript”>
  Sys.Application.add_initialize(function() {
  $create(Sys.UI.DataView, {
    template: $get(“template1”),
    data: myData
  }, {}, {}, $get(“repeater1”));
}
</script>

  • Sajnos számomra még mindig nem egyértelmű, hogy mindebből mikorra lesz valami és ez szomorít el legjobban :(

A friss információk alapján úgy látom, hogy még jó darabig nem célszerű olyan projektet tervezni, amik ezekre a Futures funkciókra épülnek, ez most óriási változás. Az XML-Script támogatás a jelek szerint nem fog megszületni, bár ezt így nem láttam leírva (csak azt, hogy bonyolult és lassú). Persze ez még csak roadmap, aki szereti a bétázást, próbálja majd ki és írja meg a véleményét a fejlesztőknek!

 

July 07

Workflow Foundation – miért kellene, hogy érdekeljen?

Egyre gyakrabban találkozom azzal a kérdéssel, hogy mikor érdemes bevetni egy alkalmazás megvalósításához a Windows Workflow Foundationt és egyáltalán mi lesz jobb attól, ha egy aránylag komplex komponenssel bővítjük a rendszerünket?

Első ránézésre a WF bizony egy összetett, vízfejű szörnyetegnek tűnik, foglalkozni kell vele, mire az ember megérti, hogy melyik része mire jó. Egyszerű problémák megoldásához nagy overheadként látja az ember és nehéz átlátni, hogy egy konkrét esetben nyerünk-e vele vagy épp kockára tesszük a projekt sikerét azáltal, hogy egy újabb technológiát próbálunk összereszelni a többivel.

Tavaly volt szerencsém részt venni a barcelonai TechEd Developers konferencián, ahol az egyik szünetben ezekről a kérdésekről beszélgettem Matt Winklerrel, a WF csapat egyik szakértőjével. Mivel ezek a kérdések újra és újra előkerülnek, úgy döntöttem, hogy megosztom a videót:

Matt Winkler interjú

A videó első fele a Workflow Foundationről szól, a beszélgetés második felében pedig a .NET Framework 3.5 verziójában megjelent újdonságokról, elsősorban a WF és a Windows Communication Foundation integrációjáról kérdeztem Mattet. (Ez utóbbiról egyébként már volt ezen a blogon egy részletesebb cikk.)

A beszélgetés mindössze 10 perc, aki most kezd a témával foglalkozni, annak bevezetőként tudom ajánlani.

 

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:

Run ablak Windows Mobile-on

Nem éppen gyakori kérdés, de azért újra és újra belefut az ember, hogy hogyan lehet Windows Mobile-on egy parancssort, vagy legalább egy Run ablakot előhúzni. Íme egy trükk: tartsuk nyomva az Action gombot és közben tappintsunk sokáig a címsorban az óra helyére. Az Analog/Digital menü helyett ez jelenik meg:

Run parancs

A Run-ra tappintva pedig előjön a desktopról már ismert ablak:

Run dialógus ablak Windows Mobile-on

Mindezt emulátorban is elő lehet húzni, csak tudni kell, hogy az Action gombnak megfelel a billentyűzeten a Ctrl, azt kell sokáig nyomva tartanunk. Továbi gyorsítóbillentyűk megtekinthetők itt.

Ha ez nem elég, akkor még jól jöhet a Windows Mobile Developer Power Toysban található PPC Command Shell, illetve a Google számos freeware-t is kidobott.

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ü