Jozef Izso

Informačný portál

June 28th, 2006

Moja iniciatívna maličkosť navrhla, aby v robote nasadili nejaký portál na správu dokumentov. Mám skúsenosti s pár inštaláciami SharePoint Services, tak sme sa rozhodli pre ne. Požiadavka na portál bola, aby vedel pracovať aj s dokumentami na zdiľaných priečinkoch a s mailami v Exchange. Čiže sme potrebovali nasadiť SharePoint Portal Server 2003.

Rozchodiť SPS Portál už nie je taká sranda, ako rozchodiť len WSS. Trápili sme sa s kolegom, trápili, celý deň. Úspech v rozchodení Portálu spočíva v tom, že konto, pod ktorým beží Application Pool portálu na IIS, má prístup do SQL Server-u a je owner konfiguračnej databázi Portálu.

SharePoint Portal má úžasnú vec, ktorou je crawler. Tento indexovací robot prechdáza stránkami portálu a indexuje ich. Týmto spôsobom dokáže naindexovať Portál, Sites, Exchange alebo zdieľané priečinky. Verejné priečinky Exchange, ktoré sa majú zdieľať, treba vystaviť cez Exchange HTTP Virtual Server s použitím Windows integrated authentication a bez formulárového prihlasovania. Potom stačí crawleru povoliť adresu http://exchange/public/verejný_priečinok a spustiť indexáciu.

Vyhľadávanie je jedna z najlepších vecí na Portále. Z jediného vyhľadávacieho políčka máte možnosť vyhľadať vo full textovo indexovanom obsahu (kategorizovanom na základe metadát v dokumentoch) , ktorý nepozostáva len z obsahu dokumentov v knižniciach na SharePoint-e, ale aj zo súborov na zdieľaných priečinkoch, v Exchang-i a na mnohých iných miestach. Všeobecne sa dá povedať, že čokoľvek, čo sa dá reprezentovať URI adresou, sa cez portál dá nájsť.

Ukladanie dokumentov do knižníc na SharePoint Services je geniálne jednoduché. Stačí otvoriť Word, napísať svoj dokument a uložiť ho na adresu http://sharepoint/sites/project/documen­ts. Word, Excel a PowerPoint dokážu prechádzať štruktúrou SharePoint-u ako priečinkami na disku, ?root? však nie je Tento počítač, ale SharePoint Server.

Pre správne fungovanie balíka Office so SharePointom treba mať doinštalovanú súčasť SharePoint Services Components, bez ktorej Office nevie takto pracovať so SharePointom.

Windows Sidebar Gadgets

June 25th, 2006

Windows Vista a portál Live.com umožňujú spúšťanie tzv. Gadgetov, čo sú mini aplikácie využívajúce DHTML alebo Web 2.0. Najnovšie informácie pre vývojárov o gadgetoch sú na MicrosoftGadget­s.com. Sú tu dva tutoriály o vytváraní gadgetov pre Live.com a Windows Sidebar. Jediný rozdiel pre Gadgety medzi týmito dvoma prostrediami je XML manifest, ktorý popisuje Gadget.

Live.com používa rozšírený RSS formát. Windows Sidebar používa vlastný XML formát, ktorý popisuje Gadget v podstate rovnakým spôsobom, ako RSS formát, len tagy majú iné názvy.

Na vývoj Gadgetov vám stačí Visual Studio Express (Web Edition pre Live.com Gadgety) a prípadne Windows Vista, ak by ste chceli testovať Gadgety vo Windows Sidebar-e. Potrebujete mať znalosť HTML, CSS a JavaScript-u a potom už stačí si prejsť SDK.

Nastavenie vývojového prostredia pre Live.com gadgety je pracnejšie, poskytuje však aj ladenie JavaScriptov z prostredia Visual Studia (podpora pre breakpointy, step in/out… klasické debugovanie).

Portál Live.com nepoužívam, tak som začal pracovať na Gadgete do Windows Sidebar. Podľa tutoriálu som vytvoril šablónu pre Visual Studio, ktorá vytvorí nový C# projekt so základnou štruktúrou, predpripravenou prvou stránkou a stránku s nastaveniami Gadgetu a nejakú tú aplikačnú logiku na pozadí. C# projekt po zbuildovaní nakopíruje súbory do správneho priečinku, aby ho Windows Sidebar videl. V tomto type projektu však nebude možné ladiť JS, pretože Windows Sidebar nepracuje so zdrojákmi, ktoré má Visual Studio, ale s ich kópiou a neexistuje žiaden PDB súbor, ktorý by umožnil ladenie.

Šablónu Windows Sidebar Gadget treba nakopírovať do priečinku My Document\Visual Studio 2005\Templates.

.NET Framework 3.0

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

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

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)

Textpattern: export do RSS

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)

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

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

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.