Súbor technológií známych doteraz pod názvom WinFX (Windows Presentation, Communication a Worfklow Foundation a nové Windows CardSpace (pôvodné InfoCard)) bol oficiálne premenovaný na .NET Framework 3.0. Bude dostupný pre Windows Vista, XP a 2003 Server.
Category: Software
Logovanie chýb pomocou log4net
Veľmi dôležitou vecou, ktorú musí mať každá aplikácia, je logovanie chýb. Pre .NET aplikácie existuje výborná knižnica log4net. Síce jej chýba priamo zabudovaný výstup do XML dokumentu, obsahuje generovanie XML fragmentov do textového súboru a ten je možné potom vložiť ako externú entitu do XML dokumentu.
log4net obsahuje dobrý základ pre logovanie chýb pomocou vlastných, špecializovaných, objektov. Pomocou nich je možné napr. zalogovať podrobne chyby v SQL príkaze, alebo všetky SQL príkazy, ktoré boli asociované s DataAdapter-om, v ktorom nastala chyba. Takto je možné zistiť aj v akom stave bolo spojenie s databázou.
Logovací systém log4net sa skladá z týchto základných objektov:
-
Layout – stará sa o formát, v akom budú logované záznamy uložené.
-
Appender – ukladá záznamy do logovacieho výstupu. Výstup môže byť súbor, databáza, konzola, logovací server a pod.
-
Filter – filtruje úroveň (Level) záznamov a iné vlastnosti, na základe ktorých logovaný záznam predá appenderu, alebo nepredá.
-
ILog – interface ktorý ukladá záznamy. Je vytvorený na základe konfiguračného XML súboru, alebo programovo.
Všetky logovacie metódy rozhrania ILog prijímajú ako prvý parameter object, druhý, nepovinný, je Exception. Napr.:
ILog.Error(object message, Exception exception);
Pri spracovaní logovaného objektu (väčšinou v metóde LayoutBase.Format(), v prípade XmlLayout-u vo FormatXml()) sa zavolá message.ToString(). Štandardne sa do metódy posiela string (zložitejší text sa formátuje napr. pomocou ErrorFormat(string format, params object[] args)). Nič nám však nebráni si napísať vlastný logovací objekt, ktorý bude preťažovať metódu ToString().
Prvá trieda je celkom jednoduchá: do textového logu vypisuje len chybovú správu. (Zdrojový kód SimpleLogItem)
public class SimpleLogItem
{
private string _message;
public SimpleLogItem()
: this("")
{ }
public SimpleLogItem(string message)
: this (message, null)
{ }
public SimpleLogItem(string message, params object[] args)
{
if (message != null)
_message = String.Format(message, args);
else
_message = message;
}
public string Message
{
get { return this._message == null ? "" : _message; }
}
public override string ToString()
{
return String.Concat("[Log message] ", Message);
}
}
Konštruktor SimpleLogItem priamo podporuje formátovanie textu pre väčšie pohodlie. Celkovo však táto trieda nerobí nič, čo by sa nedalo dosiahnuť „Format“ metódami v ILog. Slúži však ako veľmi jednoduchý základ pre sofistikovanejšiu triedu: SimpleSqlLogItem.
Zdrojový kód triedy SimpleSqlLogItem je celkom veľký takže na neho uvádzam len linku. Uvediem len použitie a výstup logu.
SqlCommand cmd;
SqlConnection conn;
// …
try
{
SqlDataReader reader = cmd.ExecuteReader();
// …
}
catch (SqlException ex)
{
log.Warn(new SimpleSqlLogItem(cmd, „Nepodarilo sa získať informácie o užívateľovi.“));
}
finally
{
conn.Close();
}
SimpleSqlLogItem môže naformátovať výstup napríklad takto:
[Log message] Nepodarilo sa získať informácie o užívateľovi.
[SQL Command] SELECT id, meno, email FROM uzivatelia WHERE id = @ID AND meno = @meno
[param] int @ID = 1
[param] varchar @meno = ‚Administáror‘
[Connection] DBSERVER\SQLEXPRESS:UkazkovaDB (Open)
Btw: v tomto príklade sa nepodarilo získať informácie o užívateľovi pretože dátový typ parametru @meno by mal byť nvarchar. Takéto logovanie dokáže zachytiť aj aktuálny stav pripojenia do databázy, pretože získanie stavu objektu SqlCommand.Connection sa vykoná pred uzavretím spojenia v kóde finally.
Nabudúce popíšem spôsob vytvorenia vylepšeného LogItem-u, ktorý bude používať XmlWriter na zápis údajov.
Skúška blogovania cez Microsoft Word 2007
Po rozchodení XML-RPC rozšírenia do Textpatternu, môžem teraz oveľa
pohodlnejšie blogovať. A aj s kontrolou pravopisu ![]()
Vďaka Wordu budem môcť jednoduchšie publikovať články s naformátovanými a zvýraznenými zdrojovými kódmi s ukážkami. Len aby som teraz mal inšpiráciu na nejaké features v .NETe… A spomenul si na tie, ktoré som chcel blognúť v poslednom mesiaci, ale kvôli strnulému publikovaciemu rozhraniu som sa na to nakoniec vykašlal.
PS: Word pridáva do textu aj tvrdé medzery a sú súčasťou
vypublikovaného dokument. Dobrá vecička, veľmi dobrá ![]()
PS2: Vytváranie smajlíkov je tiež jednoduchšie: vytvoril som si jedného, pravé kliknutie ? Uložiť rýchly štýl a už len ďalších smajlíkov pooznačujem a kliknem v Ribbone na štýl Smajlíci. Keby som to ešte mohol spraviť cez Auto Correct ;o)
Windows Vista Beta 2, Office System Beta 2
A je to tu, dnes vyšla pre širokú verejnosť dlhoočakávaná porcia software: Windows Vista beta 2 a Microsoft Office System 2007 beta 2.
Kto sa zaregsitroval do Beta experience programu, má možnosť vyskúšať
si tieto skvelé produkty. Už sa teším na blogovaciu
feature v Microsoft Word 2007. Konečne bude blogovanie tak easy, ako
písanie protokolov na meračky, alebo firemných reportov ![]()
Textpattern: export do RSS
Tak som polku dňa riešil, prečo mi nefunguje RSS. Okrem špecifickej chybe kvôli špeciálne nastavenému prepisovaniu URL v Apache, som zistil, že vygenerovať pomocou TXP a PHP nejaký validný XML výstup je takmer nemožné.
Problém je v tom, že na generovanie XML sa používa skladanie stringov a
potom rôzne machrovanie s utf8 konverznými funkciami… Však načo sú
špecializované XML streamy… To by ešte bolo v pohode, pri dobre
napísaných funkciách z toho vylezie kód so správnymi tagmi. Čo však
spôsobuje problém sú entity. Vôbec pomenované entity v XML predstavujú
obrovský problém, pokiaľ XML súbor nemá explicitne prilinkovaný DTD súbor
s ich definíciou. Potom XML reader nevie, čo to je za entitu a všetko je
v háji. A boh vie, čo ten druhý PHP systém používa na spracovanie
XML…
Takže som problém vyriešil systémovo: otvoril starý článok a zmenil
znaky, ktoré robili problémy… Však prečo by najrozšírenejšia serverová
technológia mala mať normálnu podporu pre niečo, ako je XmlTextWriter
a spol. ![]()
Kódujeme parametre do URL (sofistikovane)
Niekedy je potrebné zakódovať parametre do URL, ktoré budú odoslané na server (napr. cez HttpWebRequest.GetResponse()). V .NETe môžeme použiť klasickú metódu z ASP HttpServerUtility.UrlEncode() na zakódovanie jednotlivých parametrov. Existuje však oveľa lepší spôsob, ako kódovať parametre. Vďaka objektovému modelu sa nám naskytne veľmi elegantné riešenie.
Triedu UrlParameterWriter si rozšírime tak, aby sme mali prístup k jej chránenej (protected) metóde Encode(TextWriter, string, object). Táto do výstupného bufferu vloží zakódovaný názov parametru a jeho hodnotu, pričom sama podľa potreby pridáva oddeľovacie znaky ako = a &.
Naša trieda teda bude dediť
namespace izsaknet.VisualStudio.FogBugz.Tools{ public class UrlParameterEncoder : UrlParameterWriter { public UrlParameterEncoder() : base () { } public void Encode(TextWriter writer, string name, string value) { base.Encode(writer, name, value); } }}
URL parametre je dobré si uchovávať v NameValueCollection, ktorá uchováva páry kľúč/hodnota (typu string). Na celé zloženie URL použijeme objekt UriBuilder.
UriBuilder uri = new UriBuilder(„http://www.izsak.net/search“);NameValueCollection values = new NameValueCollection(2);values.Add(„search“, searchTerm);values.Add(„section“, „all“);StringBuilder query = new StringBuilder();TextWriter writer = new StringWriter(query);UrlParameterEncoder encoder = new UrlParameterEncoder();foreach (string key in values){ encoder.Encode(writer, key, values[key]);}uri.Query = query.ToString();
Kód asi nepotrebuje veľa vysvetľovania, vytvoríme nový objekt so základnou URL adresou na nejaký dokument. Potom si naplníme pole hodnotami. Za zmienku stojí vytvorenie textového bufferu a writeru. Metóda Encode() bude zapisovať parametre do TextWriteru a ten do bufferu textu. Spojené parametre zo StringBuilder-u vložíme do UriBuilder cez jeho Query vlastnosť.
Niektoré veci v .NETe si vyžadujú viacej úsilia, ako len inštancovanie
triedy a jej použitie. Treba trošku použiť hlavu a derivovať triedy
. Toto celé sa dá pekne
zaobaliť do triedy ktorá by reprezentovala webový formulár a uchovávala si
hodnoty pre GET a POST v dvoch kolekciách a používali by takúto
serializáciu parametrov. Pri POST ešte treba výsledný string skonvertovať
na pole bajtov (byte[]) napr. pomocou
Encoding.ASCII.GetBytes(string).
Windows RSS Platform
Spolu s prehliadačom Internet Explorer 7 budú mať aj užívatelia OS Windows XP a 2003 dostupnú Windows RSS Platform. Toto API poskytne jednoduchý prístup k RSS zdrojom. Všetky aplikácie budú zdieľať užívateľov zoznam RSS zdrojov, čiže odpadne synchronizácia cez OPML bez viacerými RSS čítačkami.
API poskytne 3 komponenty: zoznam RSS zdrojov, synchronizáciu a úložisko pre zdroje. Bude podporovať rôzne RSS a Atom formáty, pričom vývojári sa nebudú musieť starať o implementáciu spracovania formátov – Windows RSS Platform poskytne cez Common Feed List rovnaké rozhranie pre prácu s rôznymi formátmi.
Užívatelia Windows Vista budú môcť štandardne pristupovať k RSS zdrojom cez IE7 alebo Sidebar. WRP zaistí, že aplikácie budú synchronizované.
Via: Windows RSS Platform.
.NET 2.0: Nulové základné dátové typy
Niekedy je výhodné mať v základnom dátovom type ako int, float, double, DateTime a pod. uloženú hodnotu null. Všetko sú to hodnotové typy, čiže musia byť vždy inicializované na určitú hodnotu.
Problém nastáva pri práci s databázami, ktoré pri týchto dátových typoch umožňujú použitie hodnoty NULL, v .NETe reprezentovanej ako trieda DBNull.
Často sa teda do týchto štruktúr ukladali hodnoty, ktoré boli mimo rozsahu definovaného architektúrov programu (napr. máme tabuľku produktov, v ktorej sú produkty bez uvedenej ceny. Stĺpec je dátového typu money alebo decimal a umožňuje mať aj nulové hodnoty. Pri načítaní dát z DB treba kontrolovať, či hodnota nie je typu DBNull a ak je, vložiť do premennej hodnotu -1M, pretože zápornú cenu produkt nemôže mať.)
.NET 2.0 obsahuje novú triedu System.Nullable, ktorá umožňuje uchovať v hodnotových typoch aj hodnotu null. Je teda lepšie rozpoznateľné, či je hodnota nezadaná, alebo zadaná hodnota je z povoleného rozsahu, alebo nie. Jazyk C# obsahuje nový operátor ?? pre prácu s triedou Nullable<T> a umožňuje skrátený zápis pre nulový hodnotový typ.
Nulový hodnotový typ sa definuje napísaním ? za názov hodnotvého typu.
int? x;
Tento zápis je ekvivalentný zápisu
Nullable<int> x;
Na zistenie, či premenná obsahuje nejakú hodnotu, je možné použiť vlastnosť Nullable<T>.HasValue alebo pri priraďovaní operátor ??.
Do hodnotového typu je operátorom ?? vložená hodnota nulového hodnotového typu ak je v ňom priradená nejaká hodnota. Ak je hodnota nulová, do hodnotového typu sa vloží hodnota na pravej strane operandu ??.
Taktiež je možné zavolať metódu Nullable<T>.GetValueOrDefault().
int? x = null;
// prvá možnosť – určenie vlastnej hodnoty v prípade „null“
int j = x ?? 0;
// druhá možnosť
int k = x.GetValueOrDefault(); // k = 0
// tretia možnosť
int j = 0;
int? x = null;
if (x.HasValue)
j = x.Value;
Poznámka: DBNull trieda existuje v pamäti vždy len jedna a to jej inštancia DBNull.Value. DBNull sa nikdy nerovná žiadnemu inému dátovému typu.
PS: Dnes to bolo bohužiaľ bez praktickej ukážky.
.NET 2.0: Prázdny alebo nulový reťazec
Zistiť, či je text nulový (null) alebo prázdny (String.Empty, "") je častou zálažitosťou v programoch. Veľmi dobrá novinka v .NET 2.0 je statická metóda String.IsNullOrEmpty(string). Táto metóda je oveľa prehľadnejšia a efektívnejšia, ako text == null || text == "". Dokonca je rýchlejšia, ako častý trik text.Length == 0. Totiž porovnanie text == "" je veľmi pomalé.
Pri testoch nie je String.IsNullOrEmpty() rýchlejší, ako text.Length == 0, ale často sa zabúda na skontrolovanie, či je text nulový a po pridaní podmieny text == null je String.IsNullOrEmpty() tým najrýchlejším zistením, či je text prázdny.
Využitie nájde napr. v triedach, ktoré načítavajú konfiguráciu. Trieda má v sebe napevno nakódované defaultné hodnoty nastavení, potom načíta zmenené hodnoty z konfiguračného súboru alebo databázy a zmení ich. Ak sa nové nastavenia načítavajú do nejakého poľa, napr. HashTable alebo niečoho podobného, tak kontrola, či nastavenie v HashTable má nejakú hodnotu je pomocou String.IsNullOrEmpty veľmi efektívna.
string dataDir = „/App_Data“;
HashTable customSettings = LoadSettings();
if (!String.IsNullOrEmpty(customSettings[„dataDir“]))
dataDir = customSettings[„dataDir“].ToString();
.NET 2.0: Rýchlejšie parsovanie čísel
Veľmi častou úlohou pri programovaní je previesť text na číslo alebo dátum. Najčastejšie pri spracovaní vstupu od užívateľa, alebo spracovaní vystupných dát, ktoré nie sú „strongly typed“ (teda nenesú informácie o dátových typoch).
V .NET 1.0 a 1.1 sa používala načastejšie trieda Convert, ktorá obsahuje statické metódy pre konverziu medzi jednoduchými dátovými typmi (čísla, dátumy, logické hodnoty).
Problém nastáva v zložitom manažmente týchto konverzií. Ak sa totiž argument nedá previesť na daný dátový typ, tak vyhodia výnimku. Tzn. že celý blok kódu treba obaliť do try{} catch{}, ktoré zbytočne znižujú výkonnosť programu.
.NET 2.0 prináša nový prístup ku konverzii základných dátových
typov. Je oveľa pohodlnejší a vyžaduje menej systémových prostriedkov.
Stará koncepcia je totiž zlá – výnimky by sa mali používať naozaj vo
výnimočnom prípade. Ak však užívateľ zadáva vo WinForm
aplikácii do TextBoxu číslo a zadá ho zle, tak sa dosť časť nejde
o výnimočný prípad
.
Preto existuje v .NET 2.0 v každom základnom dátovom type metóda TryParse(). Ako názov napovedá, metóda sa pokúsi spracovať zadaný vstup. Ak sa jej to podarí, vráti true, v opačnom prípade false. Čo však s konvertovanou hodnotou? Metóda má len návrtovú hodnotu bool… Použiť na vstupný text jednu z metód z Convert v bloku if() po úspešnom spracovaní textu metódou TryParse() by bolo jedno z riešení. Je vša neefektívne, pretože dochádza k dvojnásobnému spracovaniu vstupných dát.
Metóda TryParse() má parameter výstupný (out). Ide o premennú, do ktorej bude uložená skonvertovaná hodnota, ak bude konverzia úspešná. Toľko teória a teraz jeden jasný príklad:
int vek;
string input;
Console.Write(„Zadajte Váš vek: ");
input = Console.ReadLine();
if (Int32.TryParse(input, out vek))
{
// správne zadané číslo, od dnešného datáumu odpočítame roky
DateTime rokNarodenia = DateTime.Today.AddYears(-vek);
Console.WriteLine(“Narodili ste sa v roku {0}.„,
rokNarodenia.Year
);
}
else
{
Console.WriteLine(“Prosím, zadajte číslo.");
}
Zdrojový kód programu: TryParse.cs.
Ukážku je možné vylepšiť o pridanie parametru NumberStyles.None, ktorý neumožňí spracovaniezáporného čísla. TryParse() by vyzeral takto:
Int32.TryParse(
input,
System.Globalization.NumberStyles.None,
System.Globalization.CultureInfo.CurrentCulture.NumberFormat,
out vek)
Paramater CurrentCulture.NumberFormat podľa aktuálneho
jazyka poskytne metóde informácie o kladnom, zápornom alebo desatinnom
znamienku v číslach v aktuálnom jazyku (a aj ostatné dôležité
informácie o číslach).