Archive for the ‘Software’ Category

.NET Framework 3.0

Saturday, June 10th, 2006

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.

Logovanie chýb pomocou log4net

Sunday, May 28th, 2006

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(ob­ject message, Exception exception);

Pri spracovaní logovaného objektu (väčšinou v metóde LayoutBase.For­mat(), v prípade XmlLayout-u vo FormatXml()) sa zavolá message.ToStrin­g(). Š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(mes­sage, 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.ExecuteRe­ader();
// …
}
catch
(SqlException ex)
{
log.Warn(new SimpleSqlLogI­tem(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\SQLEX­PRESS: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.Con­nection 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

Wednesday, May 24th, 2006

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

Wednesday, May 24th, 2006

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

Tuesday, April 4th, 2006

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)

Monday, April 3rd, 2006

Niekedy je potrebné zakódovať parametre do URL, ktoré budú odoslané na server (napr. cez HttpWebReques­t.GetResponse()). V .NETe môžeme použiť klasickú metódu z ASP HttpServerUti­lity.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 UrlParameterWri­ter 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.Visu­alStudio.FogBug­z.Tools{    pu­blic class UrlParameterEn­coder : UrlParameterWri­ter    {        ­public UrlParameterEn­coder()            : base ()        { }        public void Encode(TextWriter writer, string name, string value)        {            ­base.Encode(wri­ter, name, value);        }    ­}} 

URL parametre je dobré si uchovávať v NameValueCo­llection, 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/se­arch“);NameVa­lueCollection values = new NameValueCollec­tion(2);values­.Add(„search“, searchTerm);va­lues.Add(„sec­tion“, „all“);StringBu­ilder query = new StringBuilder();Tex­tWriter writer = new StringWriter(qu­ery);UrlParame­terEncoder encoder = new UrlParameterEn­coder();foreach (string key in values){    encoder.Encode(wri­ter, key, values[key]);}u­ri.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.ASCI­I.GetBytes(strin­g).

Windows RSS Platform

Wednesday, February 1st, 2006

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

Sunday, January 22nd, 2006

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>.Has­Value 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>.Get­ValueOrDefault().

int? x = null;

// prvá možnosť – určenie vlastnej hodnoty v prípade „null“
int j = x ?? 0;
// druhá možnosť
int k = x.GetValueOrDe­fault(); // 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

Friday, January 20th, 2006

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.IsNullO­rEmpty(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.IsNullO­rEmpty() 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.IsNullO­rEmpty() 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.IsNullO­rEmpty veľmi efektívna.

string dataDir = „/App_Data“;

HashTable customSettings = LoadSettings();

if (!String.IsNu­llOrEmpty(cus­tomSettings[„da­taDir“]))
   dataDir = customSettings[„da­taDir“].ToStrin­g();

.NET 2.0: Rýchlejšie parsovanie čísel

Thursday, January 5th, 2006

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(„Za­dajte Váš vek: ");

input = Console.ReadLine();

if (Int32.TryPar­se(input, out vek))
{
// správne zadané číslo, od dnešného datáumu odpočítame roky
DateTime rokNarodenia = DateTime.Toda­y.AddYears(-vek);

Console.Write­Line(“Narodili ste sa v roku {0}.„,
rokNarodenia.Year
);
}
else
{
Console.Write­Line(“Prosím, zadajte číslo.");
 }

Zdrojový kód programu: TryParse.cs.

Ukážku je možné vylepšiť o pridanie parametru NumberStyles.No­ne, ktorý neumožňí spracovaniezá­porného čísla. TryParse() by vyzeral takto:

Int32.TryParse(
    input,
    System.Globali­zation.Number­Styles.None,
    System.Globali­zation.Culture­Info.CurrentCul­ture.NumberFor­mat,
    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).