2008. március havi bejegyzések

Árvíztűrő sütik

ASP.NET-ben nagyon egyszerűen tudunk sütiket, azaz cookie-kat kezelni, gyakorlatilag kulcs-érték párokról van szó. Egyetlen sorral elmenthetünk oda valamit:

    this.Response.Cookies[ "akarmi" ].Value = this.txtOriginal.Text;

és egyetlen másik sorral vissza is olvashatjuk:

    this.txtLoaded.Text = this.Request.Cookies[ "akarmi" ].Value;

Akkor van csak igazán gond, ha a felhasználó telepakolja a fenti txtOriginal nevű TextBoxot magyar ékezetes karakterekkel – legyen az a kedvenc árvíztűrő tükörfúrógép teszt szövegünk -, még a böngésző is eldobja magát, méghozzá ritka durván:

Cookie encoding: ez lesz a böngészőben

Persze ki hisz manapság egy modern böngészőnek, megnéztem, hogy Nikhil Web Development Helpere mit lát ebből.Íme a szerver által küldött válasz, amiben a süti lejön a kliensre:

Cookie encoding - Response

Azután pedig a böngésző ezt küldi vissza a szervernek:

Cookie encoding - Request

Örülhetünk, hogy a két sztring azonos, de sajnos ez nem segít a szerveren.

Két lehetséges megoldást találtam az ékezetek lecsapkodására, úgy látom működik mindkettő.

1. Base64 encoding használata

Ekkor így módosul a kód:

    this.Response.Cookies[ "akarmi" ].Value = Convert.ToBase64String( Encoding.UTF8.GetBytes( this.txtOriginal.Text ) );
    ...
this.txtLoaded.Text = Encoding.UTF8.GetString( Convert.FromBase64String( this.Request.Cookies[ "akarmi" ].Value ) );

És ez megy át a madzagon, összesen 44 karakter:

w6FydsOtenTFsXLFkSB0w7xrw7ZyZsO6csOzZ8OpcA==

2. UrlEncoding használata

Ez webfejlesztőknek ismerősebb kód lehet:

    this.Response.Cookies[ "akarmi" ].Value = this.Server.UrlEncode( this.txtOriginal.Text );
    ...
this.txtLoaded.Text = this.Server.UrlDecode( this.Request.Cookies[ "akarmi" ].Value );

De sokkal terjengősebb az eredmény, 67 karakter:

%c3%a1rv%c3%adzt%c5%b1r%c5%91+t%c3%bck%c3%b6rf%c3%bar%c3%b3g%c3%a9p

Ezt az ASP még megcsinálta automatikusan, az ASP.NET azonban nem, tehát erre külön oda kell figyelni különösen akkor, ha ASP és ASP.NET alkalmazások között cserélgetünk sütiket (lásd KB313282).

 

Technorati Tags: ,,

OBA “state of the art”: addin, ribbon, task pane – Site Source

Múlt héten egy barátom jóvoltából (ezúton is köszönet érte) kezembe akadt a 6 Microsoft® Office Business Applications for Office SharePoint® Server 2007 című MS Press könyv. Bevallom elsőre vegyes érzelmeim voltak a könyvvel kapcsolatban, mert bár a SharePoint programozás érdekel, az "OBA" hallatán feláll a szőr a hátamon.

Először is: Gondolt már valaki arra, micsoda nyelvi környezetszennyezést okoz az, ha egy ilyen mondat kerül a címlapra: "Practical OBAs for working developers"?

Másodszor pedig: Az Office szerencsére már nagyon régóta programozható platform mind szerver, mind pedig kliens oldalon és az én meglátásom szerint az OBA-hullám nem más, mint ennek egy új marketinges megközelítése, ahol minden "super-easy". Ettől még számomra továbbra is kliens és szerver oldali, részben burkolt COM és felügyelt interfészek összekalapálásáról van szó. Úgy látszik a könyv borító tervezője egyetérthet velem, mert szögeket rajzolt a címlapra 🙂

Azt belátom, hogy most már kezd az Office eljutni oda, hogy a felügyelt interfészeknek és a Visual Studio támogatásnak köszönhetően valóban lehet alkalmazás hosztként is használni, ez igaz. Legalábbis ezt mondják és a könyvbe beleolvasva én is hinni kezdtem a dologban…

Lassan másfél éve, hogy utoljára Office kliens programozással bajlódtam, akkor még keményen ott volt benne a COM és az ActiveX, nem volt viszont designer támogatás, helyette lehetett XML-t írni IntelliSense nélkül. A könyvet olvasva elhatároztam, hogy kipróbálom, milyen érzés mostanában egy Word addint írni.

Feladatként a következőt tűztem ki: írok egy olyan Word 2007 addint, ami kiegészíti a ribbont, ahol egy saját gombra kattintva megjelenik egy saját task pane. Ebben a saját task pane-ben el lehet navigálni egy SharePoint listára, a Wordben megjelennek a lista elemei, ahol az egyes mezők értékeit egyszerűen be lehet szúrni a dokumentumba. Mindezt azért, hogy ne kelljen annyit SharePoint listából Word doksikba copy paste-elnem és ALT-TAB-oznom, amitől jojózik a szemem egy idő után. Ha ehhez COM-ot vagy XML-t kell matatnom, megint másfél évre jegelem az Office programozást.

Fogtam tehát egy Visual Studio 2008-at és létrehoztam benne egy Word 2007 addin típusú projektet és elneveztem Site Source-nak. Plusz pont a VS teamnek, hogy már nincs külön VSTO, mindent megkapunk egy teljes Visual Studio 2008 telepítéssel:

New Project dialógusablak

A következő kellemes meglepetés akkor ért, amikor megláttam, hogy milyen tiszta kódvázat generál a Studio. Egyetlen osztály mindössze ennyi kóddal:

    namespace SiteSourceAddIn
    {
        public partial class ThisAddIn
        {
            private void ThisAddIn_Startup( object sender, System.EventArgs e )
            {
            }

            private void ThisAddIn_Shutdown( object sender, System.EventArgs e )
            {
            }

            #region VSTO generated code

            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InternalStartup()
            {
                this.Startup += new System.EventHandler( ThisAddIn_Startup );
                this.Shutdown += new System.EventHandler( ThisAddIn_Shutdown );
            }

            #endregion
        }
    }

Ennek fele se tréfa, dolgoztak a fiúk Redmondban. Nosza, alkossunk ribbont, tehát Solution Explorerben Add New Item és láss csodát, lehet ribbont létrehozni nemcsak XML-ben, hanem designer segítségével is:

New item templates

 

Be is húztam egy ToggleButton nevű vezérlőt a Toolboxról, ez fogja majd megjeleníteni a saját task pane-t és a szokásos módon generáltam hozzá eseménykezelőt:

Ribbon Designer

Az eredmény a Forms világban jól megszokott osztály, ahogy annak lennie kell. Kiegészítettem a ThisAddIn osztályomat, hogy meg is jelenjen:

        protected override Office.IRibbonExtensibility CreateRibbonExtensibilityObject()
        {
            return new Ribbon.RibbonManager( new Ribbon.OfficeRibbon[] { new SiteSourceRibbon() } );
        }

Hozzáadtam a projekthez egy user controlt, ebből lesz a task pane. User controlhoz már régóta van designer támogatás, így nem okozott gondot felparaméterezni a vezérlőket és bekonfigurálni az adatkötést:

User Control

Újabb egy sor a ThisAddIn osztályba az addin betöltődésekor és még egy internal változó, hogy tudjak rá hivatkozni:

        internal OfficeTools.CustomTaskPane taskPane;

        private void ThisAddIn_Startup( object sender, System.EventArgs e )
        {
            this.taskPane = this.CustomTaskPanes.Add( new SiteSourceTaskPane(), "Site Source Tasks" );
        }

Ezek után már megírhattam a ribbon eseménykezelőjét, ami megjeleníti vagy elrejti ezt a task pane-t:

        private void tbtnDisplay_Click( object sender, RibbonControlEventArgs e )
        {
            Globals.ThisAddIn.taskPane.Visible = !Globals.ThisAddIn.taskPane.Visible;
        }

A task pane SharePoint webszolgáltatások segítségével kéri le a listák tartalmát és LINQ to XML segítségével dolgozza fel. Ha valakit érdekel írjon és megmutatom azt is. Az Office programozással kapcsolatban ami érdekes, hogy végül az eredményt hogyan lehet beszúrni a dokumentumba. Így:

    Globals.ThisAddIn.Application.Selection.Text = value;

Mindenkinek ajánlom figyelmébe a Globals.ThisAddIn.Application objektumot, sok okosság érhető el rajta keresztül, ráadásul bárhonnan. Íme az eredmény, ahogy Wordben látszik:

Site Source Wordben

Összességében nagyon pozitív kép alakult ki bennem ezekről az alap programozói feladatokról Office 2007 és Visual Studio 2008 környezetben. Persze ez még csak a kezdet egy komolyabb projekt esetén.

Miután így belejöttem, belepakoltam még a SharePoint webszolgáltatás híváshoz szükséges felhasználó nevek és jelszavak kezelését a Windows Credential Manager segítségével. Az a kódom már megvolt korábban, csak most átírtam .NET 3.5-re. Az új szintaktikának köszönhetően 600-ról 390-re ment le a kódsorok száma és persze olvashatóbb is lett a kód.

Érdekel valakit az addin vagy a forráskód, közzétegyem?

Kiegészítés (2008.03.24.): A teljes forráskód megtalálható az MSDN Code Gallery SiteSource projektjében ezen a címen: http://code.msdn.microsoft.com/SiteSource
Minden visszajelzést szívesen veszek!

 

Melyik SharePointot válasszam?

Amikor SharePoint funkciókról beszélünk, sajnos általában elég pontatlanul fogalmazunk (én is és a Microsoft is), nem derül ki, hogy egy adott szolgáltatás a WSS vagy a MOSS része, az utóbbiból pedig a standard vagy az enterprise csomagban kapjuk-e meg? Akkor jön a fejfájás, amikor a fejlesztői gépről át kellene költözni az éles szerverre és a fejlesztőktől kérdezik a megrendelő oldalon az üzemeltetők, hogy mit telepítsenek.

Létezik erről hivatalos, mindenre kiterjedő, igen alaposnak mondható Excel fájl (SharePointProductsComparison.xlsx vagy xls), amit nagyon tudok ajánlani. Megtekinthető és letölthető az Office Online-ról, illetve mirroroztam is. A neten kering egy PDF is, annak ne tessék bedőlni, csak 1 oldalas, míg az XLS 8, valakinek nem sikerült a PDF export.

A februári Office DevCon óta több helyen futottam bele a neten ebben az ábrába, ami szintén nem rossz megközelítése a problémának (rákattintva megtekinthető nagyobb méretben):

SharePoint Standard vs. Enterprise

Mivel volt már szerencsém jópár hasonló kérdésben konzultálni, nálam az alábbi "ökölszabályok" alakultak ki:

  1. Próbáld meg a problémát WSS-sel megoldani. Tisztább, szárazabb, kellemesebb érzés, ráadásul ingyen van, kevesebbet kér enni és emiatt gyakran gyorsabb is.  Néhány egyedi webkijelző fejlesztése sokszor egyszerűbb és gyorsabb, mint megtanulni a nagy testvér működését. Mutasson valaki egy fejlesztőt vagy egy üzemeltetőt, aki képes átlátni a teljes MOSS-t! Sokkal többet tud a WSS alapban, mint ahogy azt a legtöbben gondolják.
  2. Ha kell content management vagy enterprise search funkció, válts MOSS Standardre. Ez a gyakorlatban azt jelenti, hogy ha nem csak dokumentumokat, hanem tartalom oldalakat is kell kezelni, esetleg egyetlen belső vállalati webhelyet kell létrehozni, ahonnan minden elérhető és kereshető, akkor már feljebb kell lépni, szükséges a MOSS.
  3. MOSS Enterprise-t akkor érdemes venni, ha kell BI (Business Data Catalog, Report Center, Key Performance Indicators), Excel Services, Forms Services. Bár ez nem funkcionális megkötés, tudomásom szerint a publikus internetes webhelyek megvalósításához is Enterprise CAL kell.

Ez persze csak az én megközelítésem, vásárlás előtt tessék átfutni az Excel táblát és nem árt egy licenc szakértővel is konzultálni.

 

MOSS 2007 és least privilege

A least privilege azon elvek közé tartozik, melyek követése nem egyszerű, különösen eleinte okoz némi fáradtságot, de hosszú távon biztosan megéri. Aki esetleg nem ismerné, annak röviden: ne légy admin, csak baj lehet belőle! Tökéletesen lehet levelezni, netezni, fejleszteni, debuggolni, doksit írni, olvasni, telefont szinkronizálni, CD-t írni – szinte mindent, mezei felhasználóként. Igaz, telepítéshez, üzemeltetéshez, driver debuggolásához néha elengedhetetlen, na de ki az, aki mást sem csinál, csak drivert ír és telepítget a gépén?

Úgy emlékszem a Windows 2000 idején hallottam először erről és akkor még elég sok alkalmazást kellett Run As-zel indítani ahhoz, hogy jól működjön. Mára ez megváltozott, könnyen lehet boldogulni normál jogosultságú felhasználóként. Ez mutatja, hogy változik a világ, az igényes fejlesztők igyekeznek úgy megírni az alkalmazásaikat, hogy minimális jogosultságokkal tudjanak működni. Mondom, az igényesek.

Mi a helyzet az üzemeltetőkkel?

Az igényes rendszergazdák már régóta követik ezt az elvet, elég nekik részletes doksit adni és boldogan beállítanak mindent korrektül. (Megint, az igényesek.) Ami a SharePointot illeti, bizony nem vagyunk alaposan ellátva információval arról, hogy az egyes felhasználói fiókoknak milyen jogosultságok szükségesek, ráadásul jó sok van belőlük. Hetek óta olvasgatok a neten ezekről és számos egymásnak ellentmondó információt találtam. Arra nem vállalkoztam, hogy kiderítsem mi igaz, arra viszont igen, hogy mindet összeszedjem egyetlen táblázatba és kiegészítsem a saját tapasztalataimmal. A végeredmény letölthető innen:

Office SharePoint Server Security Account Requirements

Egy jótanács a SharePoint fejlesztőknek: ne domain admint állítsunk be minden felhasználói fióknak, amire a SharePoint telepítő rákérdez. Igen, először szokatlan, sőt szokatlanul nagy fáradságnak is tűnik, de így legalább biztosan nem telepítés után fog kiderülni, ha a kódunk jogosultsági problémák miatt nem működik.

 

(P.S. Mióta magam sem rendszergazdai jogokkal dolgozom és látom, hogy működik, próbálok másokat is meggyőzni ennek az elvnek a követéséről. Biztosan bennem van a hiba, de eddig még egyetlen fejlesztőt sem sikerült. Mindenki atyaúristen akar lenni a gépén folyamatosan a nap minden percében. Mondja már meg valaki mi ez, valami kompenzáció, mint a feleslegesen nagy és feltűnően drága autók?)

 

IIS7 konfigurálása WSS-hez

Korábban már közzétettem egy screencastot arról, hogyan telepíthetjük és üzemeltethetjük a Windows SharePoint Services v3-t Windows Server 2008-on. Bár szerepel a felvételen, hogy mely szerepköröket, képességeket és IIS7 komponenseket kell telepíteni, kigyűjtöttem ide őket külön is:

  • Web Server (IIS) role:
    • Common HTTP Features
      • Static Content
      • Default Document
      • Directory Browsing
      • HTTP Errors
    • Application Development
      • ASP.NET
      • .NET Extensibility
      • ISAPI Extensions
      • ISAPI Filters
    • Health and Diagnostics
      • HTTP Logging
      • Logging Tools
      • Request Monitor
      • Tracing
    • Security
      • Basic Authentication
      • Windows Authentication
      • Digest Authentication
      • Request Filtering
    • Performance
      • Static Content Compression
      • Dynamic Content Compression
    • Management Tools
      • IIS Management Console
      • IIS 6 Management Compatibility
        • IIS 6 Metabase Compatibility
  • Features:
    • .NET Framework 3.0 Features
      • .NET Framework 3.0
    • Network Load Balancing (ha kell)
    • Remote Server Administration Tools (ha kell)
      • Role Administration Tools
        • Web Server (IIS) Tools
    • SMTP Server (ha nincs másik)

IISRESET fürgén

Aki foglalkozott már valaha SharePoint programozással, valószínűleg maga is levonta azt a következtetést, hogy a SharePointos problémák 130%-a megoldható egy IISRESET-tel. Az addig rendben is van, hogy újra kell indítanunk a webalkalmazást (ez bármelyik szoftver esetén előfordulhat), de miért éppen így? Leginkább azért, mert ez összesen 8 karakter, villámgyorsan be lehet gépelni. Valljuk be magunknak őszintén, ezért szeretjük használni. Nyolc karaktert még a kattintgatásfüggő fejlesztő is hajlandó begépelni.

Ráadásként azonban ezzel "sikerül" nem csak a kívánt SharePointos webalkalmazást, hanem az egész webszervert újraindítanunk, tehát az összes webalkalmazás, application pool minden vicik-vacak újraindul. El is tart jóóóó sokáig, elég csak visszagondolni arra, hányszor olvastuk már életünkben, hogy "Attempting stop…", aztán meg "Attempting start…".

Pedig tudjuk, hogy az IIS-ben lévő alkalmazásokhoz hozzátartozik egy application pool, aminek az újraindítása magával hozza az alkalmazás újraindulását is. Ráadásul ez sokkal barátságosabb, nem véletlenül lett az angol terminológiában Recycle és nem Restart. Amit viszont nem mindenki tud, hogy ezt is lehet parancssorból. A Central Admin újradindítása például ennyi:

cscript C:WindowsSystem32iisapp.vbs /a "SharePoint Central Administration v3" /r

Aki ezt most látja először, annak feltétlenül javaslom, hogy próbálja ki, előbb jelenik meg itt a Done, mint az IISRESET-nél az Attempting.

A fenti példáról persze ordít, hogy hosszabb, mint 8 karakter. Szerencsére Spence Harbar még nyolc karaktert sem szeret gépelni, hanem inkább megalkotta az Application Pool Recycle Utility-t. Ez a kis eszköz az IIS WMI adapterén keresztül felderíti, hogy milyen application poolok léteznek, majd a tálca jobb szélén ücsörögve várja, hogy rákattintva előrántson egy helyi menüt, amiből közvetlenül újraindíthatjuk őket:

Application Pool Recycle Utility

Sőt! Az Options ablakban beállíthatjuk, hogy az alkalmazáskészlet újraindítása után a háttérben lekérje az általunk megadott URL-en található oldalakat, ezzel mintegy bemelegítve a webalkalmazást. Így mikor először nézzük meg az oldalt böngészőben már nem fogjuk érezni az ASP.NET szokásos késleltetését.

 

Circular reference

Könnyű belefutni az alábbi XML sorosítási hibaüzenetbe, ha webszolgáltatásokat használunk:

System.InvalidOperationException: There was an error generating the XML document. —> System.InvalidOperationException: A circular reference was detected while serializing an object of type Result.

Például előjöhet akkor, ha LINQ to SQL designer segítségével összerakjuk az alábbi modellt:

LINQ to SQL modell kapcsolatokkal

Majd utána megírjuk például az alábbi webszolgáltatást:

    [WebMethod]
    public List<Result> GetTopResults( int count, int songId, int difficulty )
    {
        HeroDataContext dc = new HeroDataContext();
        return dc.Results
.Where( r => r.SongID == songId && r.Difficulty == difficulty )
.OrderByDescending( r => r.Score )
.Take( count )
.ToList(); }

Már a LINQ kifejezés miatt is érdekes a fenti kód, de sajnos az előbb említett hibaüzenetet fogjuk kapni, aminek nyilván az asszociációk az okai. Konkrétan egy LINQ-es asszociáció kétirányú kapcsolatot biztosít például az ábrán látható Song és Result osztályok között. A Result osztálynak lesz SongID és Song tulajdonsága, a Song osztálynak pedig Results gyűjteménye. Ettől persze nagyon kényelmes a használatuk csak éppen a körkörös referenciák a sorosításnál bajt okoznak.

Íme a megoldás: állítsuk az asszociáció gyermek tulajdonságának láthatóságát Internalra:

Asszociáció tulajdonságai 

Ne felejtsük el ezt megtenni minden érintett kapcsolatra és remélhetőleg megoldódik a probléma!

 

Technorati Tags: ,,