\


 Sunday, 26 September 2004
Logování událostí v mediátoru

V mediátoru, kterého jsem popisoval v jednom dřívějším spotu, potřebujeme při testování logovat všechny příchozí události, které jsou předdefinovaným a bezpečným způsobem distribuovány dalším objektům. Nejméně náročnou cestou na napsání, volenou většinou vývojáři, kteří se pravděpodobně do IT rekrutují z rekvalifikovaných potomků nejzarytějších stachanovců;), je logování každé události zvláštní metodou. Po registaci nových událostí do mediátora je vždy i změněna komponenta pro logování, takže o údržbě takového kódu si můžete nechat zdát jen mrazivé sny o opětovném plíživém nahrazování kvality kvantitou.*

Na údržbu nenáročné a univerzální řešení spočívá ve vytvoření preprocesoru (viz spot o mediátoru), který je vyvolán před distribucí událostí ostatním objektům a který parametry události vypíše přes objekt Trace z jmenného prostoru System.Diagnostics.

Základní myšlenky v preprocesoru.

1) Většina (ne li každý) objekt v business vrstvě má unikátní identifikátor s názvem Id. Preprocesor události vypíše typ objektu, který událost vyvolal a jeho unikátní Id, takže je snadné dohledat zdroj problematických událostí.

2) Objekty nesoucí parametry událostí dědí vždy z třídy EventArgs. Přes reflection vypíšeme rekurzívně hodnoty vlastností do úrovně nastavené ve vlastnosti EndDumpLevel.

using System;
using System.Diagnostics;
using System.Reflection;
namespace RStein.Utilities
{
    /// <summary>
    ///  Třída EventsLog pro logování událostí
    /// </summary>
    public class EventsLog
    {
       
        #region private constants
        private const int BEGIN_DUMP_LEVEL = 1;
        private const int DEFAULT_END_DUMP_LEVEL = 2;
        #endregion private constants
        #region private variables
        private int m_endLevel;
        #endregion private variables
        #region Constructors
        /// <summary>
        /// Konstruktor
        /// </summary>
        public EventsLog() : base()
        {
            m_endLevel = DEFAULT_END_DUMP_LEVEL;
        }
        #endregion Constructors
        #region Public properties
        /// <summary>
        /// Koncová úroveň rekurzivního výpisu vlastností objeudálosti
        /// </summary>
        public int EndDumpLevel
        {
            get
            {
                return m_endLevel;
               
            }
            set
            {
                if (value < 1)
                    throw new ArgumentOutOfRangeException("Value must be greater than 1");
                
                m_endLevel = value;   
            }
           
        }
        #endregion Public properties
        #region Public methods
       
        /// <summary>
        /// Metoda pro výpis informace o událostech
        /// </summary>
        /// <param name="sender">Zdroj události</param>
        /// <param name="e">Parametry události</param>
        public void ProcessEvent(object sender, EventArgs e)
        {   
            Debug.Assert((sender != null) && (e != null), "EventsLog - Invalid event data");
           
            if ((sender == null)||
                (e == null))
            {
                    return;
            }
               
           
                Trace.WriteLine(new string('-',25));
                dumpId(sender);
                dumpEventProperties(e);
           
        }
        #endregion Public methods
        #region Private methods
       
        //Zapsání Id a názvu objektu
        private void dumpId (object sender)
        {
           
            Type senderType = sender.GetType();
            PropertyInfo idInfo = senderType.GetProperty("Id");
            string id = String.Empty;
           
            if (idInfo != null)
                id = idInfo.GetValue(sender, null).ToString();
            Trace.WriteLine(String.Format("Přijata událost od objektu {0}, Id = {1}", senderType.ToString(), id));
        }
        //Vypsani vlastností objektu s parametry události
        private void dumpEventProperties(EventArgs e)
        {
           
            Type eventType = e.GetType();
            Trace.WriteLine(String.Format("Objekt události -  {0}", eventType.ToString()));
            PropertyInfo[] eventInfo = eventType.GetProperties();
            Trace.WriteLine("Výpis hodnot událostí");
            writeEventValues(eventInfo, BEGIN_DUMP_LEVEL, e);
        }
        //Metoda pro rekurzivní výpis hodnot vlatností
        private void writeEventValues(PropertyInfo[] eventInfo, int level, object o)
        {
            foreach (PropertyInfo info in eventInfo)
            {
               
               
                //Nezpracovávat indexované vlastnosti
                if (info.GetIndexParameters().Length != 0)
                    continue;
               
                object propValue = info.GetValue(o, null);
               
               
                if (propValue == null)
                    continue;
               
                Trace.Write(new String('\t', level));
                Trace.WriteLine(String.Format("Jméno - {0}, Hodnota = {1}", info.Name, propValue.ToString()));
               
                if (level < EndDumpLevel)
                    writeEventValues(propValue.GetType().GetProperties(), level + 1, propValue);
            }
        }
       
        #endregion Private methods
    }
}
 
 
*Pozorný čtenář z tohoto spotu dokáže vyčíst i mou politickou orientaci a nechuť k určitému druhu myšlení;)



Sunday, 26 September 2004 17:02:00 (Central Europe Standard Time, UTC+01:00)       
Comments [0]  .NET Framework | Návrhové vzory


 Thursday, 23 September 2004
Druhá malá programátorská hádanka na tento týden

Dokážete (bez spuštění programu) poznat, v čem bude provádění tohoto kódu z hlediska "selského programátorského rozumu" podivné a proč?

using

System;

namespace

ConsoleApplication24

{

public class Class1

{

public static void Calculate( int number)

{

}

}

public class Class2: Class1

{

public static void Calculate( long number)

{

}

}

class Test

{

[STAThread]

static void Main( string []args)

{

Class2.Calculate(

int .MinValue);

}

}

}



Thursday, 23 September 2004 15:30:00 (Central Europe Standard Time, UTC+01:00)       
Comments [13]  Programátorské hádanky


 Wednesday, 22 September 2004
All-In-One zařízení nebo jednoúčelové vyšperkované přístroje?

Dneska se Patrik Zandl zamyslel nad užitečností All-In-One zařízení, tedy přístrojů, které v jednom kabátku nabídnou funkce více specializovaných elektronických “hraček". Spot byl zaměřen hlavně na mobily, do kterých je dneska integrován fotoaparát, rádio, MP3 přehrávač a další více či méně užitečné funkce. Vyznění spotu bylo jednoznačné - kombinovaná zařízení jsou hezká věc, ale brzy nás omrzí a používáme jen jejich primární funkce a na vše ostatní zakoupíme dražší, ale technicky dokonalejší přístroje, které mají lepší ovládání přizpůsobené svému základnímu a jedinému účelu. Z telefonu pořád hlavně voláme nebo posíláme  SMS, ale dle průzkumů nás třeba fotoaparát omrzí po prvním měsící hraní, z čehož nemají radost hlavně operátoři, kteří by asi nejradeji viděli, jak si s voyerským úsměvem vyměňujeme každý s každým fotografie banálního soukromí, které svou (ne)kvalitou danou nízkým rozlišením dávají prostor fanatazii, protože si každý může (spíš musí) z rozpitých skvrn domýšlet, jestli fotografie zachycuje poslední výstřelek kubistické estetiky nebo fotříka rozvaleného s pivem v křesle;)

Zpět k All-In-One zařízením.

Jirka Macich se ve svém spotu All-In-One zařízení zastal a vyzdvihl hlavně výhodnou cenu kombinovaného zařízení. Také jsem zastáncem kombinovaných zařízení, i když vím, že jsou zatím kompromisem. Ale velmi dobrým kompromisem. MDA II jsem si koupil, protože mě nebaví nosit s sebou PDA, mobil, přenosný MP3 přehrávač, rádio, čtečku knih. Fotoaparát nezmiňuji, protože se bez něj s radostí obejdu. Nerad se fotím a nerad koukám na strnulé statické snímky čehokoli a souhlasím s Mílanem Kunderou, že fotky jsou jen jednou ze sofistikovaných forem zapomnění.;)

Po 9 měsících intenzivního používání musím říct, že jsem spokojený a že většinu mých nároků plní MDA II na výbornou:

  1. MDA II je špičkové PDA, které i dnes předčí některá samostatně prodávaná PDA.
  2. K přehrávání MP3 na cestách nemusím mít žádné extra specializované zařízení s jednoduchým ovládáním jako je Ipod. Stačí mi, že si mohu vytvořit playlist a spustit sekvenční nebo náhodné přehrávání písniček. To vše jakýkoli přehrávač pro Windows Mobile 2003 samozřejmě zvládá.
  3. Když mě omrzí MP3, mohu poslouchat internetová rádia. Kvalita není nic moc, ale když mi nebude stačit, mohu si koupit SD kartu s rádiem.\
  4. Pro Windows Mobile existuje nepřeberné množství různě kvalitních programů pro čtení elektronických knih. Všechny materiály, odborné knihy, které mám právě teď rozečteny, mám stále u sebe, aniž bych s sebou tahal navíc nějaké místo zabírající jednoúčelové zařízení.
  5. Když bych zatoužil po GPS, není nic snazšího než zakoupení SD karty nebo samostatného a přes bluetooth komunikujícího GPS modulu.

Paradoxně jediné co se dá vytknout MDA II je horší software pro ovládání telefonní části. Verze "Phone Edition" operačního systému Windows Mobile není ještě tolik vyzrálá, ale třeba konkurenční Symbian má již dnes telefonní část plně srovnatelnou s běžnými “jednoúčelovými" mobily bez operačního systému.

Kvalita All-In-One zařízení se bude podle mě bude stále zvyšovat, takže k nákupu specializovaných zařízení najdeme stále méně důvodů. Nebo si myslíte něco jiného a používáte tak propracované zařízení, že vám ho žádný All-In-One přístroj nedokáže nahradit?



Wednesday, 22 September 2004 19:47:00 (Central Europe Standard Time, UTC+01:00)       
Comments [0]  Mobilitky


 Tuesday, 21 September 2004
Malá programátorská hádanka

Máte následující kód:

class

Test :  BaseTest

{

private string m_rene;

public Test() : base ()

{

m_rene = "Rene";

}

public override void WriteName()

{

Console.WriteLine(m_rene);

Console.Read();

}

}

Metoda WriteName vypíše za určitých podmínek jen prázdný řetězec - víte kdy? ;)

Update: A víte, jak se bude chovat stejný kód po přepsání do C++?



Tuesday, 21 September 2004 15:32:00 (Central Europe Standard Time, UTC+01:00)       
Comments [25]  Programátorské hádanky


 Monday, 20 September 2004
Česká .Net Developer Group nabírá dech

Jak už psal Michal, dneska se uskutečnilo první setkání české .Net Developer Group. K jeho postřehům bych jen dodal, že mě jakožto skeptika, co se týče úspěšnosti pořádání kolektivních akcí pod egidou velkých společností jako je Microsoft, příjemně překvapil počet účastníků, a hlavně to, že většina z nich nebyla všemu pasivně přitakávající zasmušilou většinou, která vévodí většině oficiálních seminářů a přednášek, ale že se se (skoro) všichni podíleli na vytváření programu dalších setkání.

Jestliže tedy nechcete potkávat své kolegy jen ve virtuálním prostoru internetu a nejste naprostí asociálové opevňující se s hysterickými vzlyky ve svém domě i při zmínce o návštěvě blízkého příbuzného, tak přijďte na další setkání, které se bude konat přibližně za měsíc a jehož tématem je bezpečnost v .Net Frameworku. O bezpečnosti bude přednášet Honza Šeda.

Honzovi Šedovi také patří pořádný dík za to, že si .Net Developer Group vymyslel, prosadil a celé první setkání v Microsoftu zorganizoval.



Monday, 20 September 2004 21:52:00 (Central Europe Standard Time, UTC+01:00)       
Comments [2]  .NET Framework | Ostatní


ADSL versus CDMA

Uvažuji, že své pomalé GPRS připojení vyměním za něco lepšího, protože mám konečně v dosahu ADSL i CDMA.

Po srovnání obou technologií a hlavně jejich perspektivy se mi víc zamlouvá ADSL, ale ta má jednu velkou nevýhodu - je poskytována Českým Telecomem, jehož rozhodnutí o rozvoji broadband internetu mají jedinou logiku - logiku maximalizace zisku za každou cenu v co nejkratším časovém období a na úkor rozvoje celé služby. Kvůli laxnosti Telecomu při instalaci DSlamů, kdy jsem byl neustále krmen jen velkohubými PR zprávami o lepšící se infratruktuře Telecomu, jsem v únoru už dlouho předtím nepoužívanou pevnou linku odhlásil. A teď bych si jí měl zase zřídit, jak já nesnáším monopol :(

Vím, že s Eurotelem Telecomu neuteču, ale ke kompletnímu manažerskému ovládnutí Eurotelu Telecomem a k telekomunizaci celé cenové politiky a firemní strategie Eurotelu snad zatím nedojde a po prodeji Telecomu se, alespoň doufám, obě společnosti opět rozdělí. (spekulace vychází z modelového scénáře, že Eurotel koupí Orange, který se chce Telecomu ihned zbavit).

Takže bych vás chtěl poprosit, abyste mi v komentářích napsali své zkušenosti s oběma technologiemi i vaším doporučením, abych měl rozhodování lehčí. Díky ;)



Monday, 20 September 2004 08:03:00 (Central Europe Standard Time, UTC+01:00)       
Comments [10]  Ostatní


 Sunday, 19 September 2004
Rychlá instalace všech aplikací na MDA II (XDA II) po tvrdém restartu

Nevím jak vy, ale já na svém Pocket PC nesnáším stav po tvrdém resetu, kdy musím znovu a znovu instalovat desítky programů, které používám. Windows Mobile 2003 jsou sice navzdory pochybovačným křiklounům stabilní a kvalitní operační systém a kvaziargumenty křiklounů jen je samotné usvědčují z toho, že za perfektní PDA považují jakoukoli programovatelnou kalkulačku, hlavně když je bez démonického systému Microsoftu, a do extatického křepčení kolem zlatého telete je dostane pouze fakt, že jde navíc o kalkulačku osedlanou Linuxem, ale experimentování s málo zdokumentovaným RIL protokolem dokáže i moje MDA II spolehlivě složit. U MDA II naštěstí nemusíte s otráveným obličejem instalovat všechny programy, ani nemusíte dbát na pravidelné a zdlouhavé zálohování celého zařízení, protože instalaci programů lze po tvrdém resetu spustit z Extended ROM.

Extended ROM je neveřejná část vestavěné flash paměti, která je vyhrazena pro mobilní operátory. Mobilní operátoři do této paměti umisťují programy (u TMO jde například o GPRS monitor), českou lokalizaci nebo témata na Today obrazovku se svým logem. Extended ROM je uzamčena pro zápis a v seznamu složek na PDA není vidět. Druhou část flash paměti, kterou asi používáte, je takzvaná Storage. Storage je volně přístupná uživateli a je určena k zálohování dat, o něž nechceme přijít po tvrdém resetu. Do Storage i do Extended ROM můžeme také nakopírovat CAB soubory, které budou nainstalovány po tvrdém restartu zařízení. Aby byly programy nainstalovány, neobejdeme se bez zásahu do Extended ROM a hlavně do "magického" souboru config.txt.

Upozornění: I když jde o zcela nesmyslné opatření servisu, zásahem do Extended ROM přicházíte o záruku. Proto si nejdříve obsah originální Extended ROM zazálohujte na počítači a před zanesením zařízení do servisu obnovte zálohu, zamkněte a skryjte Extended ROM - v servisu pak žádné provedené úpravy nepoznají a vaše oprava bude provedena v rámci záruky. Úpravu Extended ROM provádíte na vlastní odpovědnost a já neodpovídám za žádná případná poškození zařízení. (ale to jste určitě ode mě ani nečekali;) )

1) Stáhnete si a nainstalujte na MDA II Extended ROM Unlocker. Extended ROM Unlocker je nástroj, který zpřístupní a odmkne Extended ROM. Po instalaci najdete zástupce programu s výmluvnými názvy Hide, Unhide, Lock, Unlock v menu Programy pod složkou Extended ROM Tools. Zveřejněte (Unhide) a odemkněte (Unlock) Extended ROM. Resetujte (měkký reset) zařízení, abyste viděli složku Extended ROM.

2) V Extended ROM jsou hlavně CAB soubory operátorů, ale nás bude zajímat soubor config.txt. Config.txt je obyčejný textový soubor, který obsahuje příkazy vykonávané jednoduchým interpreterem autorun.exe po tvrdém resetu MDA II. Modifikací souboru config.txt můžeme instalovat další programy, které jsou umístěny v Extended ROM, ve Storage nebo na paměťové SD kartě (Storage Card) a odstraněním instrukcí operátora nebo výrobce se zase zbavíme automatické instalace programů, které stejně ihned po restartu odebíráme.

Instalaci CAB souboru si vynutíme zadáním prefixu CAB:, za který doplníme cestu k CAB souboru.

Instalace CABu umístěného v Extended ROM:
CAB: \EXTENDED_ROM\tcmdpocket.exe

Instalace CABu umístěného v Storage
CAB: \STORAGE\tcmdpocket.exe

Kromě instalace CAB souborů, můžete potvrdém restartu automaticky kopírovat soubory. Takže je snadné přidat třeba nového zástupce do Startup složky.

Za prefixem CPY1: zadáme cestu ke kopírovanému (zdrojovému souvoru)
Za prefixem CPY2: zadáme cestu k cílovému souboru

CPY1:\STORAGE\totalcmd.lnk
CPY2:\Windows\StartUp\totalcmd.lnk

Příkazem RST: Reset v config.txt si vynutíme měkký reset.

Nyní můžete bez obav provést tvrdý reset zařízení a všechny programy (bez dat!) budete mít za chvíli nainstalovány.

Tip na závěr: Z config.txt odstraňte volání nepovedených programů TPEnable.exe a TPDisable.exe. Jejich úkolem je po dobu instalace programů nepovolit vstupy uživateli - bohužel tyto prográmky jsou občas příčinou "zamrznutí" zařízení a také se nehodí, když CAB soubor vyžaduje potvrzení některých instalačních kroků.



Sunday, 19 September 2004 16:38:00 (Central Europe Standard Time, UTC+01:00)       
Comments [0]  Mobilitky


 Thursday, 16 September 2004
Vytvářejte se mnou aureolu dobrého weblogu

Můj blog rozmnožuje informační entropii již několik měsíců, a protože souhlasím s Radkem Hulánem, že dobrý weblog je navštěvovaný weblog, chci dát v tomto spotu prostor vám, čtenářům, abyste mi pomohli dotvářet jeho podobu, která bude více zajímavá pro vás i pro mě.

Za těch pár měsíců, co se spolu potkáváme na weblogu, jste mohli už částečně poznat, co mě zajímá, z čeho jsem nadšený i jaké animozity v sobě živím. Weblog jako žánr vyžaduje, aby v něm autor nabídl svoje osobité vidění problematiky, a to i problematiky odborné, a ne aby byl vzdálenou dvouřádkovou ozvěnou novinek právě rezonujících všemi informačními kanály na internetu nebo ochraptělou a omezenou hlásnou troubou jedné minoritní komunity. Od počátku se snažím i podtitulkem naznačit, že weblog je pro mě hlavně střet - nejen veřejný verbální střet mezi mnoha soupeřícími podobami mého ega (myšleno psychologicky, ne pejorativně ;) ) ve spotech , ale také střet mezi mými a vašimi názory, střet s jinými bloggery nebo autory. Nechci být jedním z mnoha bloggerů na doméně Vyvojar.cz, ale chci a snažím se, abyste po otevření směsice spotů na blog.vyvojar.cz poznali, který příspěvek jsem napsal já. Je to neskromné? Asi ano, ale kdybych o to neusiloval, tak nemusím psát weblog - nezaměnitelná aureola dobrého weblogu je podle mě konstituována jen a pouze originálními příspěvky jeho autora.

Proto bych chtěl slyšet váš názor na můj blog.

Zajímalo by mě, proč právě vy chodíte na můj weblog a jaké rysy vás na něm přitahují, co vás nudí nebo dokonce odpuzuje a co by vás nejvíce z témat, o nichž víte, že mě baví, zajímalo. Vaše reakce mi usnadní rozhodnutí, co by se s blogem mělo dít dál. V poslední době čím dál častějí přemýšlím o přesunu svych aktivit na vlastní doménu, i když by těsná spolupráce s Vývojářem v jiné podobě trvala určitě dále.

Co mě k rozhodnutí založit si vlastní doménu vede?

  1. Můj blog se netýká jen .NETu a i když Michalovi tématicky odlišné příspěvky nevadí, tak si nejsem jist, zda neodrazují jiné návštěvníky serveru Vyvojar.
  2. Na blogovacím systému .Text se mi nelíbí, že do RSS exportuje celé spoty.
  3. Na vývojáři není funkční stránka pro zasílání emailu přes odkaz Contact.
  4. Nové příspěvky pod spoty nejsou zasílány emailem. Nejen kvůli těmto nevýhodám uvažuji, že jako blogovací systém nepoužiji .Text v jeho "čisté" podobě.
  5. Na blogu nemám jednoduše dostupné úložiště pro obrázky a zdrojové kódy. Michal na požádání sice ochotně všechny artefakty na server umístí, ale přeci jen vlastní a vždy dostupné úložiště by bylo lepší.
  6. Na mých stránkách nechci mít jen blog, ale také stránky s regulérními články, poradnu pro zajímavé dotazy a když bude z vaší strany zájem, tak i třeba komerční sekci s e-booky na aktuální vývojářská témata.

Takže neváhejte a pořádně me zkritizujte, abych věděl, co musím se svým blogem udělat ;)



Thursday, 16 September 2004 21:15:00 (Central Europe Standard Time, UTC+01:00)       
Comments [23]  Ostatní


 Wednesday, 15 September 2004
Živě učí staré psy staré kousky

Živě zahájilo s obrozeneckým nadšením seriál o VB.NET. Nadšení serveru pro nové jazyky a polopatické vzdělávání svých čtenářů se ale ve své aktuální podobě stávají pro seriál sudičkami se smrtícími kletbami ve své bezzubé hubě.

Autor seriálu Milan Petřík se rozhodl, že postaví na hlavu všechna didaktická pravidla, která říkají, že vysvětlování nového tématu s odlišným viděním problému by nemělo být budováno na předchozích zastaralých znalostech, a raději nám předkládá svoji vizi "jednoduchého" VB jako chameleona proplouvajícího napříč technologiemi již léta skoro beze změny. To, že VB.NET je jen marketingový název Microsoftu pro jazyk budovaný na zcela jiných principech nez VB6 a nižší verze, který se svými zastaralými předchůdci sdílí některé méně významné syntaktické konstrukce, a že jen pro nepoučitelné nostalgiky je vytvořen jmenný prostor Microsoft.VisualBasic, s jehož pomocí je způsob kódování ve VB.NET degradován na hybridní VB6/.NET styl, nemusím návštěvníkům mého blogu asi připomínat.

Autor veškeré připomínky ke svému seriálu odmítá alibistickým poukazem na to, že prvních 10 dílů seriálu je určeno úplným začátečníkům, a proto nevysvětluje hned některé pokročilé, ale zásadní koncepty (třeba třídy, jmenné prostory), které přesahují ohraničený svět VB.NET. Alibistické je to proto, že se sice dle svých slov vyhýbá teoretickému vysvětlování některých pojmů, ale to mu nebrání, aby nás hned ve druhém dílu seriálu nepoučil o o logickém členění programu do modulů (Proč Microsoft před programátory skrývá své sladké tajemství, že modul ve VB.NET je jen třída se statickými metodami a syntaxe modulu je rozvinuta do třídy teprve kompilátorem?) a procedur a v zatím posledním díle se zase rozhodne, že jeho čtenáři jsou již dostatečně vyspělí, aby pochopili konstrukci Try - Catch (a to vše ještě před řídícími konstrukcemi jazyka!), ale aby jejich chápavé obvody v mozku nepřetížil, tak jim taktně zamlčí existenci klíčového slova Finally.

Dalšími lapsy jsou neustálé vypisování celé hierarchie jmenných prostorů nebo utvrzování začátečníka, že používání "magických" čísel místo konstant je v pořádku. Seriál je rozvleklý, těžkopádný a skáče bez jakékoli logické souvislosti z tématu na téma.

Shrnu-li to. Za seriálem není znát žádná myšlenková osnova a působí na mě dojmem, že si někdo v Živě řekl "No ten .Net už je docela rozšířenej, jeden děsnej seriál pro začátečníky o PHP už máme, a protože jsme server pro masového čtenáře, tak vytvoříme i podobný seriál ve VB.NET (jako bumerang se zde Microsoftu vrací, že VB má pověst lidového jazyka :), pozn. aut. ) a seženeme někoho, kdo dokáže žoviálně podat, jakej je ten VB.NET pohodovej jazyk fakt pro každou lamu".

Komu je seriál určen, opravdu netuším. Napadli mě jen ortodoxní příznivci programování v Basicu na nezastarávajícím stroji Didaktik Gamma, kteří se pod tlakem doby rozhodli migrovat na na PC a .NET. Ale že by tvořili tak početnou skupinu, aby se pro ně vyplatilo vytvářet seriál? :)



Wednesday, 15 September 2004 07:55:00 (Central Europe Standard Time, UTC+01:00)       
Comments [16]  .NET Framework | Ostatní


 Monday, 13 September 2004
Http modul pro změnu URL adresy ve WSDL webové služby

Webové služby v ASP.NET generují dynamické WSDL, ve kterém je adresa služby (obsah elementu soap:address) dynamicky určena podle url původního požadavku. Například při použití reverzní proxy by se hodilo určit adresu ve wsdl dokumentu staticky a přitom stále ponechat na ASP.NET generování většiny elementů ve wsdl dokumentu.

K tomuto účelu jsem napsal http modul pro změnu adresy. V kódu se předpokládá, že nové url webové služby je zadáno ve web.config v sekci appSettings pod klíčem newUrl a že k službě je přistupováno pouze přes protokol SOAP.

using System;
using System.Web;
using System.IO;
using System.Xml;
using System.Diagnostics;
namespace RSTEIN.HttpModules
{
    /// 
    /// Modul pro změnu
    /// 
    public class ChangeUrlModule : IHttpModule
    {
        
        #region private constants                
        private const string WSDL_REQUEST = "wsdl";
        private const string SOAP_NAMESPACE = "http://schemas.xmlsoap.org/wsdl/soap/";
        private const string SOAP_PREFIX = "soap";
        private const string LOCATION_NAME = "location";
        private const string ADDRESS_NAME = "address";
        #endregion private constants                
        #region private variables
        private readonly string m_newServiceUrl;
        #endregion private variables
        #region Constructors
        /// 
        /// Konstruktor
        /// 
        public ChangeUrlModule()
        {
            m_newServiceUrl = System.Configuration.ConfigurationSettings.AppSettings["newUrl"];
        }
    #endregion Constructors
    
    #region IHttpModule Members
        /// 
        /// Inicializace modulu - Součást rozhraní 
        /// 
        /// 
        public void Init(HttpApplication context)
        {
            if (m_newServiceUrl != String.Empty)
            {
                context.BeginRequest +=new EventHandler(context_BeginRequest);
                context.EndRequest +=new EventHandler(context_EndRequest);
            }
        }
        /// 
        /// Součást rozhraní 
        /// 
        public void Dispose()
        {
        }
        #endregion
        
        #region private methods
        //Zapsání jiného URL
        private void context_EndRequest(object sender, EventArgs e)
        {
            string path = HttpContext.Current.Request.RawUrl.ToLower();
            if (isWSDLRequest())
                changeUrl();
        }
        
        //Změna Url www služby
        private void changeUrl()
        {
            HttpResponse response = HttpContext.Current.Response;
            XmlDocument doc = new XmlDocument();
            MemoryStream originalStream = ((FilterStream)response.Filter).InnerStream;
            originalStream .Position = 0;
            try
            {
                
                XmlTextReader reader = new XmlTextReader(originalStream);
                doc.Load(reader);
            }
            catch (Exception e)
            {
                Trace.WriteLine("Invalid response");
                return;
            }
            
            XmlNamespaceManager namManager = new XmlNamespaceManager(doc.NameTable);
            namManager.AddNamespace(SOAP_PREFIX, SOAP_NAMESPACE);
            XmlNode locationNode = getLocationAttribute(doc);
            locationNode.Value = m_newServiceUrl;
            response.Clear();
            doc.Save(response.Output);
            
        }
        //Vyhledání atributu location elementu soap:address
        private XmlNode getLocationAttribute(XmlDocument doc)
        {
            XmlNode addressNode = doc.GetElementsByTagName(ADDRESS_NAME, SOAP_NAMESPACE)[0];
            return addressNode.Attributes["location"];
        }
        #endregion private methods
        //přiřazení filtru na objekt Response
        private void context_BeginRequest(object sender, EventArgs e)
        {
            if (isWSDLRequest())
                HttpContext.Current.Response.Filter = new FilterStream(HttpContext.Current.Response.Filter);
        }
        //Kontrola, zda se jedná o WSDL požadavek
        private bool isWSDLRequest()
        {
            string path = HttpContext.Current.Request.RawUrl.ToLower();
            if (path.EndsWith(WSDL_REQUEST))
                return true;
            return false;
        }
    }
}


O významu http modulů a jejich registraci ve web.config se více dočtete v mém starším článku na Interval.cz.



Monday, 13 September 2004 15:12:00 (Central Europe Standard Time, UTC+01:00)       
Comments [0]  Web Services