Jarda Jirava

Vývojář a architekt řešení postavených na technologii .net framework. Zabývám se jak vývojem webových aplikací za pomoci asp.net, tak také desktopových aplikací winform. Při návrhu řešení a samotném vývoji pak využívám dlouholetých zkušeností se zpracováním obchodní logiky a pravidel aplikací získaných z vývoje komerčních aplikací pro finanční a bankovní instituce.

Microsoft MVP

Microsoft MVP - Client App dev

Silverlight minesweeper

Get Microsoft Silverlight

Navrhi COOL design a vyhraj zkušební let po Evropě!

Poslední příspěvky

code snippet

10
X

Odhalujeme .net - Deserializace

O deserializaci je toho možné napsat velice mnoho. Jsou však situace, kdy si člověk říká, že má vše pod kontrolou a ono ejhle, poměrně triviální věc a najednou je vývojář v rozpacích. Něco takového se mi přihodilo poměrně nedávno, kdy jsem řešil poměrně zajímavý projekt na zpracování a převod datových struktur. Zjednodušeně řečeno, takové menší SSIS.

Deserializace ze stringu

V uvedeném řešení existovalo několik malých tříd, které sloužily jako konfigurace pro jednotlivé tasky a jež měl možnost uživatel přes vizuální prostředí editovat. Hodnoty z těchto tříd potom byly serializovány a uloženy do databáze k danému tasku. To je pro tento případ nepodstatné. Co je však podstatnější, že bylo nutné zpětně tyto třídy obnovit z takto uložených řetězců a předat do aplikace. Ano, to co jsem zde popsal bylo uschováno a bylo použito vzoru Memento. Ale i ten musí být nějakým způsobem implementován.

Toto je útržek kódu pro deserializaci

XmlSerializer xs = new XmlSerializer(creationType);
StringReader reader = new StringReader(setting);
object result = xs.Deserialize(reader);

který byl použit v prvotní fázy a jenž byl funkční. Jistě namítnete, že nevidíte nic neobvyklého a že tímto způsobem také provádíte deserializaci.

Nakonec je z toho hádanka pro Vás

Teď by možná mohla následovat otázka, co je na této části kódu špatně a v jaké situaci se nedočkáme očekávaného výsledku? Pominu to, že může dojít ke změně interface serializovaného objektu, což se nestalo. Úspěšně však zapracovalo interní testování.

Znáte tedy odpověď? Buďte prvním kdo se o ní podělí.

Publikováno pod: .net technology , code snippet
2
X

Odhalujeme FlowLayoutPanel a TableLayoutPanel

Tentokrát se ve svém odhalování .NETu zaměřím na dva nové panely v .NET 2.0 a to konkrétně na FlowLayoutPanel a TableLayoutPanel. V obou případech se jedná o nevizuální prvky, které slouží jako container pro umístění dalších winform kontrolů na formulář.

TableLayoutPanel

Jestliže se zabýváte vedle tvorby winform aplikací také vývojem web aplikací určitě znáte tabulkový layout. A právě pro tvorbu tabulkového layoutu je určen TableLayoutPanel, jak ostatně již vyplývá z jeho názvu. Můžete tak do panelu přidávat řádky nebo sloupečky, a jednotlivé buňky seskupovat. Každá buňka pak slouží k vložení jednoho jediného kontrolu.

I mě se tento způsob umístění prvků na formulář líbil a našel jsem pro něj uplatnění ve své aplikaci, ale malinko mě překvapil. A než jsem stačil nalézt chybu, uběhla nějaká ta hodinka. Co se vlastně stalo? Jak už to tak bývá, nejdříve jsem si s daným panelem hrál a přidával a odebíral sloupčky a řádky. Poté co jsem si řekl, že znám možnosti designera, smazal jsem všechny řádky a začal prvky vkládat v runtime. Účelem mého snažení totiž bylo vkládání jednotlivých kontrolů na základě definované a načtené konfigurace při běhu aplikace. Jaké však bylo mé překvapení, když se zobrazilo nejdříve prázdné místo a vložené kontroly se nacházely až někde hluboko pod okrajem formuláře.

Ano, přestože jsem vymazal sloupčky i řádky pomocí grafického designeru. Tyto zůstaly zachovány v inicializaci formuláře/panelu. Než mě však napadlo se podívat na počet vytvořených řádků, uvažoval jsem o úplně jiných chybách ... chjo. A tak ponaučení pro příště, překontrolovat i formular.Designer.cs soubor, ne vždy se designeru povede vše odstranit.

FlowLayoutPanel

O tomto prvku již jenom krátce. Jelikož také slouží jako kontainer pro další kontroly a to tím způsobem, že umožňuje jejich pozicování za sebe a to jedním z několika možných způsobů jejich toku. Opět je zde analogie z web aplikací a tentokráte pro beztabulkový layout.

Následující, je ale spíše pro oba dnes zmíněné panely. Je známé, že pokud umístíme na formulář nebo usercontrol některé prvky (většinou se jedná o složitější prvky jako je StripControl) nelze je v poděděných formulářích nebo usercontrolech editovat a to ani po nastavení jejich visibility na public nebo protected.

Já jsem tuto funkcionalitu však potřeboval využít a tak jsem se pokusil poodhalit opět něco z .netu a výsledek se dostavil. Vytvořil jsem si nový kontrol, který byl poděděn z FlowLayoutPanelu a přidal mu atribut, konkrétně DesignerAtribut pro Panel.

[Designer("System.Windows.Forms.Design.PanelDesigner, System.Design")]

S touto úpravou jsem pak měl zpřístupněn panel i ve zděděných formulářích a mohl tak vesele designovat dataentry formuláře. A po přečtení tohoto příspěvku to dokážete i vy.

Zamyšlení k vylepšení

Ač nejsem velkým příznivcem naklikávání aplikací, občas se rychlý návrh formuláře pro editaci záznamu hodí a k tomuto účelu má Visual Studio 2005 poměrně pěkný designer. Co bych však uvítal je možnost zvolit si, že chci takto vygenerovaný formulář umístit právě do TableLayoutPanelu. Přeci jen mi přijde, že v něm jsou prvky lépe pozicovány a celý formulář pak vypadá úhledněji.

Publikováno pod: .net technology , code snippet
22
IX

Jednoduchý web sql editor

Vytvořil jsem si jednoduchý sql editor. Záměrně zmiňuji, že se jedná o jednoduchý webový sql editor, který umí pouze to základní, co jsem požadoval. A z jakého důvodu jsem se rozhodl o něm napsat? Myslím si totiž, že podobný editor může být pro někoho stejně užitečný jako je pro mě.

SqlExpress na webhostingu

Tím hlavním důvodem je to, že pokud stejně jako já máte hosting na kterém je provozován SQL EXPRESS 2005 a používáte jej pomocí AttachDBFilename není dostupný žádný nástroj, jak se k databázi připojit. A to mě dovedlo k tomu, že jsem napsal tento velice jednoduchý web sql editor.

V rozbalovacím seznamu je možné vybraz jednu z dostupných databází nakonfigurovaných pomocí connectionStrings. Do připraveného textového pole je pak možné vkládat jakékoli sql dotazy (SELECT, UPDATE atd.) Není problémem vložit i několik SELECT dotazů za sebe a ty spustit společně. Výsledek se pak zobrazí ve formě resultsetů uspořádaných do tabulek.

Jednotlivé příkazy jsou uchovány v historii a je tak možné se k nim jednoduše dostat a provést jejich spuštění znovu.

Architektura

Architektura této aplikace je velice jednoduchá. Jelikož jsem si chtěl vyzkoušet AJAX Pro, použil jsem k přenosu dat z/na server výhod AJAX technologie. Tím se mi také podařilo částečně zmenšit objem přenášených dat, neboť se přenáší skutečně jen data a nikoli i jejich reprezentace.

Jelikož jsem potřeboval zajistit výpis dat až na klientovi (tedy v prohlížeči) jako rozumným řešením mi přišlo zvolit XSL transformaci. Ta na základě definice XSD vytvoří tabulku a vypíše data. Díky tomuto řešení jsem se tak poměrně elegantně vypořádal se zpracováním NULL hodnot, a určitě by bylo možné i lépe formátovat tabulku na základě datových typů - tato funkcionalita však implementována zatím není. Malým mínusem, který mi však nevadí je provázanost na IE a instancování msxml2.domdocument, pokud někdo ví, jak toto vytvořit univerzálně má možnost nechat řešení v komentářích.

Vzhled aplikace prodává, o tom jsem již psal, a tak jsem se rozhodl osladit i tuto aplikaci pověstnou třešničku na dortu a použít nifty corners od Alessandro Fulciniti. (Díky) Nic Vám však nebrání v tom, změnit si vzhled dle vlastních potřeb.

Zabezpečení

Určitě by bylo velice nemilé, pokud by k takovéto aplikaci měl přístup každý návštěvník. Samozřejmě by bylo možné řídit přístup pomocí oprávnění v souboru web.config, avšak to je nedostatečné v případě použití aplikace jakou je např. Community server, na níž je provozován tento blog. Proto je přístup na stránky řízen pomocí konfigurovatelného security managera. V případě, že potřebujete řídit specificky přístup k editoru, postačí implementovat rozhraní IEditorAuthorize z assembly JiravaNet.Data.SqlEditor.Authorize a napsat vlastní implementaci. V sekci authorizeManager souboru web.config poté tuto implementaci uvést a nakonfigurovat. Přístup k editoru má v mém případě pouze CS administrátor a při přístupu z localhost není autorizace prováděna vůbec.

Rozšíření

Jestliže se Vám bude zdát, že by tento jednoduchý web sql editor mohl umět více, nebojte se svoje náměty zamechat v komentářích, pokud budu mít chvilku, pokusím se je implementovat a rozšířit editor o další důležité schopnosti. Zdrojové kódy, byť na nich není nic převratného, mohu poskytnout na vyžádání.

Zdroje

Web SQL editor ke stažení.

Update

Samozřejmě je možné s tímto editorem použít i jakoukoli jinou databázi, nejen SQL EXPRESS 2005, která bude správně konfigurována.

20
IX

Uchování ViewState mimo asp.net stránku

O tom, že protokol http je bezstavový je jeho vlastnost se kterou se musí vypořádat nejeden vývojář webových aplikací. Microsoft přišel v asp.net s tím, používat pro uchování stavu požadavků mezi jednotlivými requesty klienta, ViewState. ViewState je ve výchozím nastavení webového projektu povolen a jeho uchování se děje na základě vloženého input prvku typu hidden do renderované HTML stránky.

Tento způsob uchování ViewState není jediný možný a již ve verzi asp.net 1.x byla možnost jej za pomoci přepsání dvou metod změnit. ASP.NET 2.0 však jde ještě dál a poskytuje přímo abstraktní třídu PageStatePersister, ve které stačí přepsat dvě metody pro uložení a načtení ViewState a ControlState a stav uložit dle návrhu aplikace. V tomto článečku ukáži, jak takový stav uložit do databáze.

Pro napsání tohoto příspěvku, s poměrně triviálním kódem, jsem se rozhodl z toho důvodu, že se opět rozbouřily vody kolem asp.net a jeho renderování výstupu HTML na klienta. Nejsem si jist, zda to rozpoutal Borber s uveřejněním své bakalářské práce, na kterou reagoval Jakub Vrána. Nebo to bylo až poté, co se DGX pozastavil nad výroky Marcuse, a kdy jsem se do debaty vložil také osobně?

Hnedka na úvod musím říci, že ViewState využívám, snažím se však o to, aby byl využívám účelně a jeho velikost zbytečně nebobtnala. Proto je vždy důležité zvolit správné UI kontroly a v případech kdy to jde, zakázat ViewState zcela. Jelikož píši z převážné většiny intranetové aplikace, nebráním se ViewState využívat. Avšak přišlo mi velice neefektivní jej přenášet při každém požadavku na klienta a zase zpět. Také proto jsem zvolil uchování stavu na serveru a to přímo v databázi - přeci jen v aplikacích je těch dotazů do db několik a jeden dotaz navíc je téměř zanedbatelný.

Vlastní implementace

Důležité je říci stránce, aby používala náš vlastní persister. V případě, že používáte vlastní poděděnou třídu Page jako výchozí pro všechny ostatní, což z vlastní zkušenosti doporučuji, je postačující přepsat property PageStatePersister

protected override PageStatePersister PageStatePersister {
 get {
  return new DbPagePersister(Page, "connectionStringKey");;
 }
}

Jestliže nemáte stránky navrženy výše uvedeným způsobem, nemusíte ještě zoufat. Můžete využít PageAdapter, a obdobně zde přepsat metodu GetStatePersister(), následně pomocí souboru .browser tento adaptér pro generování stránek přiřadit.

Dříve však než můžeme zaregistrovat vlastní persister, musíme si jej vytvořit. Vytvoříme tedy novou třídu a podědíme ji od abstraktní třídy PageStatePersister. Zde přepíšeme dvě metody pro uložení Save() a načtení Load() stavu. Předpokládám, že každý umí uložit data do databáze a tak tento krok přeskočím, nicméně je v přiložené ukázce implementován. Co je však důležité, jakým způsobem bude identifikována stránka, abychom mohli načíst její stav zpět. To je zajištěno pomocí registrace hidden pole a přiřazení unikátního řetězce Guid. Tento je jako jediný odeslán na výstup stránky a při zobrazení zdrojového kódu jej zde naleznete.

Pod čarou

Pokud se podíváte na výsledný zdrojový kód, možná vás překvapí, že se zde vyskytuje hidden pole nazvané __VIEWSTATE avšak je prázdné. Toto pole se mi však nepodařilo využít pro uložení jednoznačného identifikátoru, stejně tak se mi nepodařilo pole odstranit z finálního výstupu. Tím ovšem neříkám, že to ve výsledku nelze, ale o tom až příště.

Zdroje

Ukázka ke stažení.

Publikováno pod: .net technology , code snippet
28
VIII

První autonaming CSModule

Začal jsem používat windows live writer pro publikování článků na tomto blogu. Jenže každá výhoda má i svoji nevýhodu. Jak jste si sami všimli, snažím se používat na blogu hezká url, tudíž je místo číslo článku použit textový popisek. A onou zmíněnou nevýhodou je, že nedokážu z prostředí WLW nastavit jméno, které se má do url použít. Vlastně to již nevýhodou není, díky modularitě Community Serveru jsem ji téměř odstranil.

Rozšíření pomocí ICSModule

Napsal jsem své první rozšíření, které má za úkol převést název článku do url a to nikoli tak, jak se dělo doposud, tedy s převedenými (encodovanými) znaky, ale tak, aby se takové url hezky četlo a zadávalo. Zároveń je možné tento modul nakonfigurovat dle vlastního uvážení a tak může být použito téměř kdekoliv.

Byl jsem mile překvapen, jak je napsání takového modulu jednoduché a přesně tak jsem si rozšiřování dobře navržené aplikace představoval.

Autonaming CSModule

Zmíněný modul zajišťující autonaming si můžete stáhnout ze sekce souborů, kde je též stručný popis konfigurace.

Publikováno pod: code snippet , community server
22
XII

MulitColumnComboBox

Poměrně dlouhou dobu jsem přispěvatelem do konference na Builder.cz a snažím se odpovídat na zdejší dotazy. I já jsem si prošel obdobím, kdy jsem tápal a nevěděl si rady. Ale o tom jsem již psal a nemá příliš cenu se k tomu vracet.

Dotazy ať již jsou jakékoli, občas jsou inspirativní a jeden z nich, výstižně nadepsaný Datagrid a vice sloupcu v comboboxu upoutal moji pozornost o něco více. A jelikož jeho autor vyjádřil potřebu nějaké té ukázky kódu, zkusil jsem něco málo ukázat.

MultiColumnComboBox

Jedná se o jednoduchou implementaci ComboBoxu, který umožňuje zobrazit v jedné položce text z více sloupců datového zdroje. Myslím, že než popisovat zde technické aspekty bude lepší napsat potřebnou část kódu. Celý MultiColumnComboBox je pak možné si stáhnout.

Hlavní podstatou úpravy ComboBoxu je jeho přepsání metody OnDrawItem, která v mém případě vypadá následovně:

protected override void OnDrawItem(DrawItemEventArgs e)
{
	base.OnDrawItem (e);
	if ((e.Index < 0) || (e.Index >= Items.Count))
		return;
	if ((DisplayMember == null) || (DisplayMember.Length <= 0))
		return;

	string [] columns = this.DisplayMember.Split(',');
	object [] values = new object[columns.Length];
	string displayText = string.Empty;
	Brush brush = null;
	RectangleF layout = new RectangleF(e.Bounds.X, e.Bounds.Y, 
		e.Bounds.Width, e.Bounds.Height);

	for (int i=0; i

Ostatní vlastnosti jsou zde přepsány hlavně z důvodu, abych mohl zajistit vypsání hodnot z více sloupců. Formát výstupu je pak ovlivněn právě vlastností FormatString, která předstvuje známý formát zápisu formátování textu. A dále přepsanou novou vlastnost DisplayMember, která obsahuje seznam sloupců oddělených čárkou, ze kterých budou hodnoty vybrány.

Musím upozornit, že se nejedná o odzkoušený prvek a tento slouží pouze pro demonstrační účely, jak přistoupit k napsání si vlastního prvku. Jeho kód můžete jakkoli modifikovat a používat dále, budu ovšem rád, pokud mi pošlete jeho vylepšenou variantu.

Publikováno pod: builder.cz , code snippet