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

.net technology

24
I

ApplicationContext ještě jednou a lépe

Udělat chybu je celkem lidské, že to však dopadne takto jsem tedy vůbec nepředpokládal. Když jsem nedávno psal o splash screenu a jak jej zobrazit za pomoci třídy ApplicationContext vůbec jsem netušil, jaký to bude mít dopad a že něco není v pořádku.

Chyba není na vašem přijímači

To jediné mě malinko uklidňuje, že chyba není ani na vašem a kupodivu ani na mém přijímači. Tedy samozřejmě v přeneseném slova smyslu (je třeba si za tím představit napsaný kód). A o jakou vlastně chybu se jedná? Při použití SaveFileDialogu a pokusu o přepsání již existujícího souboru by se měl objevit dialog zda chceme soubor přepsat. Místo toho však aplikace vyvolá vyjímku Cannot access a disposed object named "FormSplash". S výpisem tohoto Stack trace:

-----[Core exception]--------------------
at System.Windows.Forms.Control.CreateHandle()
at System.Windows.Forms.Form.CreateHandle()
at System.Windows.Forms.Control.get_Handle()
at System.Windows.Forms.ThreadWindows.Callback(IntPtr hWnd, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.EnumThreadWindows(Int32 dwThreadId, EnumThreadWindowsCallback lpfn, HandleRef lParam)
at System.Windows.Forms.ThreadWindows..ctor(Control parent, Boolean onlyWinForms)
at System.Windows.Forms.ThreadContext.DisableWindowsForModalLoop(Boolean onlyWinForms)
at System.Windows.Forms.ThreadContext.BeginModalMessageLoop()
at System.Windows.Forms.Application.BeginModalMessageLoop()
at System.Windows.Forms.MessageBox.ShowCore(IWin32Window owner, String text, String caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, MessageBoxOptions options)
at System.Windows.Forms.MessageBox.Show(String text, String caption, MessageBoxButtons buttons, MessageBoxIcon icon)
at System.Windows.Forms.FileDialog.MessageBoxWithFocusRestore(String message, String caption, MessageBoxButtons buttons, MessageBoxIcon icon)
at System.Windows.Forms.SaveFileDialog.PromptFileOverwrite(String fileName)
at System.Windows.Forms.SaveFileDialog.PromptUserIfAppropriate(String fileName)

To je, zjednodušeně řečeno, způsobené tím, že smyčka zpráv se vytvořila nad formulářem FormSplash a přestože došlo následně k přiřazení hlavního formuláře do property MainForm ve třídě ApplicationContext v přepsané metodě OnMainFormClosed, smyčka zpráv se nepředala a zůstala nad již zavřeným formulářem.

Finální řešení

Mohli bychom samozřejmě provádět ještě šílenější obezličky než za chvíli zmíněné řešení, ale proč. Určitě je možné zobrazovat Splash screen v obsluze události Load hlavního formuláře, nebo vymyslet ještě obskurnější řešení, většinou však tato řešení budou poměrně hodně svázána s konkrétním hlavním formulářem a nebude tak možné mít jednu obecnou třídu pro zobrazení Splash screenu.

Navržené řešení je triviální, leč ne úplně čisté a děkovat za něj mohu dobrému pomocníkovi Reflectoru. Je totiž nutné přenastavit interní proměnnou currentForm ve třídě ThreadContext, která je interní třídou v ApplicationContext.

Část kódu, který je tedy přítomen v metodě OnMainFormClosed vypadá následovně a prosím všechny ty, kteří použili mnou navržené řešení, o opravu v jejich kódu:

_main = new FormMain();
Type application = typeof(Application);
Type threadContext = application.GetNestedType("ThreadContext", BindingFlags.NonPublic);
object current = threadContext.InvokeMember("FromCurrent", BindingFlags.Static | BindingFlags. NonPublic | BindingFlags.InvokeMethod, null, null, new object[0]);
FieldInfo currentForm = threadContext.GetField("currentForm", BindingFlags.NonPublic | BindingFlags.Instance);
currentForm.SetValue(current, _main);
this.MainForm = _main;
this.MainForm.Show();

Proč považuji toto řešení za ne úplně čisté je celkem jasné, je využívána reflection, což by samo o sobě vadit nemělo, avšak je nutné uvést textově odkazy na získání interních proměnných, jejichž název se může v příští verzi změnit.

Po provedení této úpravy by se aplikace měla chovat tak jak očekáváme a tak jak jsme ji napsali.

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

Vlastní parametr pro Data Source

Novinkou v asp.net 2.0 jsou prvky pro přístup k datům, souhrnně pojmenované jako Data Source controls. Tyto prvky umožňují deklarativním způsobem definovat základní operace práce s daty a umožnit tak rychlý vývoj jednoduchých webových aplikací.

Dotazy s parametry

Tyto datově orientované prvky používají ke zpřesnění dotazu, případně k předání informací, parametry. Což je v případě databázového přístupu doporučovaný postup, který chrání proti sql injection. Ale samozřejmě se nejedná jen o databázový přístup a tímto způsobem lze předávat parametry i pro ObjectDataSource.

Zdrojů pro parametr je několik, především se jedná o možnost získání hodnoty z Control, Form, Cookie, Profile, QueryString nebo Session. Pokud však potřebujeme získat parametr jinou cestou, musíme si vytvořit vlastní parametr.

Tvorba vlastního parametru

Na co se tedy připravit, když budeme chtít vytvořit třídu, která nám zprostředkuje vlastní hodnotu pro parametr? Potřebujeme pouze podědit od třídy System.Web.UI.WebControls.Parameter. V naší nové třídě potom přepíšeme metodu Evaluate(HttpContext context, Control control) a do jejího těla vložíme kód pro získání vlastní hodnoty.

Jednoduchá třída vlastního parametru tak může vypadat následovně:

public class DateParameter: Parameter { 
  protected override object Evaluate(HttpContext context, Control control) {
    return DateTime.Now;
  }
}

Použití parametru

Vytvořený vlastní parametr budeme určitě chtít využít v deklarativním zápisu na stránce naší aplikace. První věc, kterou musíme udělat je registrace naší assembly a zaregistrování prefixu, to je stejné, jako bychom chtěli registrovat vlastní User/WebControl a to pomocí direktivy Register na stránce. (Případně můžeme využít web.config.)

Poté už nám nic nebrání použít takový parametr


 

a to nejen v Select parametrech, jak je uvedeno výše, ale i v Update, Insert, Delete parametrech příslušného DataSourceControlu.

Publikováno pod: .net technology
11
I

Proč využít externí soubor ke konfiguraci?

V minulém příspěvku jsem se zmínil o možnosti umístění konfigurace aplikace, a to ať už asp.net nebo winform, do externího souboru. Uvedl jsem i jeden z možných způsobů využití, tím ovšem nebylo řečeno vše a rád bych se k tomu ještě jednou vrátil.

Externí konfigurace totiž přináší ještě další výhody. Někteří je již využívají, pro některé mohou být následující tipy nasměrováním. V dalším pojednání se budu věnovat konfiguraci connection stringů, byť je samozřejmě možné toto aplikovat a využít na kteroukoliv sekci v konfiguračním souboru.

Zůstaňme ve firmě

Pro začátek můžeme zůstat ve vývojářské firmě, kde se právě vytváří naše nová aplikace postavená na .net frameworku 2.0.

Nikoliv prvním, ale také ne posledním, kdo aplikaci tvoří je vývojář, který implementuje funkce. Takový vývojář se připojuje k vývojové databázi, která je většinou v tu dobu již v poměrně stabilním stavu. Píše kód proti této databázi a má tak svůj připojovací řetězec. Tento vývojář by klidně mohl mít konfiguraci uloženou přímo ve web/app.config souboru, má to však své ale.

V případě, že jste solidní softwarová firma a svůj software testujete, měl by být dalším článkem v řetězci i tester aplikací. Takový tester však bude mít vytvořenu svoji databázi, oproti které bude aplikaci testovat a tak v případě, že by dostal konfigurační soubor s aplikací od vývojáře by si jej musel editovat. Tím, že oba pracovníci budou mít svůj externí konfigurační soubor jsou tohoto kroku ušetření.

Shodně pak dopadneme, pokud používáme automatizované unit testy (i když ty ve většině případů nepracují s databází). Zde opět můžeme mít separátní konfigurační soubor.

A co naši klienti

S tím se již jistě setkal každý. Ať už považujeme za klienta náš ostrý aplikační server, nebo skutečně klienta, který je na míle vzdálen. Používá naši aplikaci spokojeně avšak má vlastní databázový server pod přísnou bezpečnostní politikou. Jeho zaměstnanci však vyžadují co nejjednodušší instalaci i administraci aplikace a tak je nemožné, aby otevírali konfigurační, byť xml, soubor a prováděli v něm zásahy. A zde je otázkou, jak provést přidání nového parametru nebo jenom jeho změnu. Samozřejmě, máme možnost vytvořit pro editaci konfiguračního souboru skvělé administrační rozhraní, ale není přeci jen snazší nakopírovat soubor?

Při použití externího konfiguračního souboru, ve kterém jsou uloženy specifické údaje pro konkrétní stroj, je pouhé překopírování možné. Nic přitom nebrání tomu, aby data v takovém externím souboru byla zakryptována a tak chráněna proti zneužití.

Určitě toto nejsou všechny možnosti, které nám přinese umístění konfigurace do externího, a přitom na hlavní konfiguraci, závislého souboru. Máte ještě jiné využití, podělte se o něj v komentářích!

Publikováno pod: .net technology
8
I

Konfigurace v externím souboru pro .net 2.0

V úterý mi přišel zápis z kulatého stolu DPE, který byl pořádán na základě Michalova článku a mě to připomělo jednu věc o kterou bych se s vámi chtěl podělit.

Je totiž spoustu začínajících vývojářů s asp.net, kteří vyvíjí své stránky a následně je chtějí umístit na jeden z volně dostupných hostingových serverů. Takové aplikace, jak už je u asp.net poměrně zvykem, využívají pro úložiště dat databázi.

A právě zde dochází k poměrně častým problémům, takový začínající vývojář je schopný navrhnout databázi, vytvořit pomocí asp.net 2.0 velice rychle aplikaci splňující všechny požadavky. Nastává však očekávaná chvíle a to přesun takové aplikace na hosting a takový vývojář většinou nezapíše správně connection string pro připojení k databázi. S otázkou, jak správně nakonfigurovat připojení, je možné se setkat snad na všech fórech a nejen u free hostingových programů.

Přitom řešení by mohlo být velice elegantní. Stačí, aby provozovatelé vytvořili vzorový web.config soubor a dali jej ke stažení. V takovém souboru pak v sekci pro ukládání připojovacích řetězců k databázi místo fiktivních údajů vložili odkaz na externí soubor a v tomto provedli vygenerování fungujícího řetězce.

Referencování externího soubor

Jakým způsobem tedy takové nareferencování externího souboru provést? Je to velice jednoduché, stačí přidat jeden atribut do příslušné sekce a vše je hotovo. Tímto magickým atributem je configSource. Konfigurační sekce tak tedy může vypadat následovně:

Tímto způsobem je samozřejmě možné použít externí konfigurační soubor pro jakoukoli sekci v hlavním konfiguračním souboru aplikace.

Pokud by se tímto přístupem inspirovali webhosteři, určitě by to potěšilo nejednoho začínajícího .netového programátora. A samozřejmě jsou zde i další možnosti, které je pomocí tohoto přístupu dostupné.

Publikováno pod: .net technology
7
I

Deploy report modelu na server

Byl jsem postaven před otázku nasazení vytvořeného report modelu na SQL Server 2005, na který jsem neměl fyzický ani vzdálený přístup.

Report model jsem vytvářel pomocí Visual Studia a jeho extenze z balíčku pro Business inteligence, který obsahuje právě i možnost vytváření report modelů. Nasazení modelu na server z tohoto prostředí je velice jednoduché, stačí zvolit nad projektem Deploy a po provedení Buildu se provede nahrání modelu do zvoleného Report serveru. Tato informace se nachází v properties dialogu daného projektu.

Nahrání modelu do Report serveru

Jenže jak se tento proces provede, pokud nemáme možnost se dostat k Report serveru (umístěného na SQL Serveru 2005) z prostředí Visual studia? Moje první cesta vedla k tomu, že by mělo být dostačující poslat .smdl soubor, ve kterém je report model definován. Import tohoto souboru také nabízí SQL Server Management Studio, pokud se připojíme k report serveru. Jenže ouha, pokud se o toto pokusíme, obdržíme hlášení, že schází definice Data Source View. Prohlédnutím si možností Management studia však rychle zjistíme, že není žádná možnost jak Data Source View na server nahrát.

Cesta druhá - úspěšná

Druhou cestou tak bylo již vytvořený a nasazený model uložit zpět na disk a ten se pokusit znovu nasadit. Po zvolení možnosti editace modelu se tento nabídne k uložení. Provedením tohoto kroku na mě čekalo menší překvapení, ač se uložil report model (.smdl soubor) již podle velikosti neobsahoval stejné údaje jako jeho původní zdroj. Po otevření jako xml souboru jsem zjistil proč, součástí takto uloženého modelu je i Data Source View, nejen samotný Report model.

Toto chování se mi zdá poněkud nešťastné a do jisté míry i obtěžující. Proto, abych mohl nasadit report model na vzdálený server jej musím nejdříve nahrát na dostupný Report server, odsud uložit a až poté mohu takto vygenerovaný soubor poslat k importu a nasazení. Přitom by určitě nebyl tak velký problém mít již tento soubor ve Visual Studiu spojený a pouze v projektu jej zobrazovat jako dvě položky.

Vzdálený server - krok za krokem

Prošli jsme tedy prvotními zjištěními a máme dostupný soubor s report modelem (.smdl), který je možné importovat. Jaké jsou tedy nutné kroky na vzdáleném serveru, aby došlo k úspěšnému nasazení modelu? Zde jsou i s připojením k report serveru.

  1. Otevřete SQL Server Management Studio
  2. V dialogu nadepsaném Connect to Server vyberte Server type: Reporting Services
  3. Do políčka (combo box) s nápisem Server name napiště adresu report serveru. Ta je ve formátu http://jmenoserveru/reportserver V případě, že používáte pojmenovanou instanci, pak za slovo reportserver doplňte ještě $jmenoinstance. Samozřejmě je nutné za jmenoserveru a jmenoinstance doplnit skutečná jména
  4. Pak je ještě nutné vyplnit authentikační informace a připojit se
  5. V Object exploreru uvidíte složku Home a pod ní složku Data Sources
  6. Klikněte pravým tlačítkem na složce Data Sources a vyberte New Data Source ...
  7. V dialogovém okně napiště jméno datového zdroje - toto jméno musí být shodné, jaké jste uvedli při vytváření report modelu
  8. Na záložce Connection potom vyplňte přihlašovací informace ke zdrojové databázi
  9. Vraťte se do složky Models a kliknutím pravým tlačítkem na této složce vyberte volbu Import file ...
  10. Vyplňte jméno modelu a zvolte soubor pro nahrání, jedná se o .smdl soubor vygenerovaný a uložený, jak bylo uvedeno výše

Po stisku tlačítka OK máme vše hotovo a můžeme začít používat náš report model.

Publikováno pod: .net technology , reporting services
27
XII

MCP, MCAD, MCPD

Pro někoho to mohou být jen písmenka poskládaná za sebe bez většího významu. Osobně to však vnímám jako ověření teoretických znalostí získaných praxí.

Právě dnes jsem udělal poslední krůček k získání MCPD certifikace. Přesný název je Microsoft Certified Professional Developer: Windows Developer. A musím říct, že to byla konečně zkouška, jejíž náročnost mě oproti předchozím testům příjemně překvapila. Možná moje vnímání bylo ovlivněno také tím, že to byla moje první zkouška, na kterou jsem šel skutečně pouze s praktickou přípravou a neměl nastudovánu doporučenou literaturu. Samotný formát testu se také změnil, přibilo více praktických i teoretických otázek a zároveň ubylo času na jejich zodpovězení. Což jenom vítám, protože tím by mohlo dojít ke zvýšení úrovně a celkového vnímání certifikace, jako skutečného prověření znalostí vývojářů.

A co dál?

Tak to se v tuto chvíli také, sám sebe, ptám. A odpověď? Může to být MCSD, MVP - ten vlastně ne, to je přeci jen trošku jiné ocenění, nebo pokračovat dále v nastoupené linii a pokusit se o získání certifikátu jako Microsoft Certified Architect. Ale to ukáže až čas a já navíc nechci být považován za toho, kdo se dere jen za získáváním certifikátu, raději mám znalosti podložené praxí a složení zkoušky je pouze pro vnitřní pocit. Pravda, je velice hřejivý a potěší.

Tak ať se také Vám něco podobného v příštím roce povede.

Publikováno pod: .net technology , personal