<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msforge.net/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Tales from under the Mountain</title><subtitle type="html" /><id>http://msforge.net/blogs/blackdwarf/atom.aspx</id><link rel="alternate" type="text/html" href="http://msforge.net/blogs/blackdwarf/default.aspx" /><link rel="self" type="application/atom+xml" href="http://msforge.net/blogs/blackdwarf/atom.aspx" /><generator uri="http://communityserver.org" version="4.0.30417.1769">Community Server</generator><updated>2009-12-14T15:06:28Z</updated><entry><title>Sa VSS-a na TFS</title><link rel="alternate" type="text/html" href="/blogs/blackdwarf/archive/2011/02/01/sa-vss-a-na-tfs.aspx" /><id>/blogs/blackdwarf/archive/2011/02/01/sa-vss-a-na-tfs.aspx</id><published>2011-02-01T07:03:19Z</published><updated>2011-02-01T07:03:19Z</updated><content type="html">&lt;p&gt;Ako neko još uvek nije uradio ovu migraciju, a pita se zašto bi to uradio, šta će mu nešto drugo, ili šta su razlike (pošto sam dosta pitanja dobijao na ovu temu kada se TFS pojavio), Brajan Heri (Brian Harry) je nedavno napisao jedan članak na tu temu, koji možete da pregledate &lt;a href="http://click.email.microsoftemail.com/?qs=1f9e475f726c96792def38cc4b2fa236a65bfc526619f0aaf7d868309ed18c6dc90265955c9d72de"&gt;na Microsoft sajtu&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Out.&lt;/p&gt;  &lt;p&gt;B.D.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msforge.net/aggbug.aspx?PostID=4436" width="1" height="1"&gt;</content><author><name>blackdwarf</name><uri>http://msforge.net/members/blackdwarf/default.aspx</uri></author><category term="vs2010" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/vs2010/default.aspx" /><category term="dotnetgeneral" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/dotnetgeneral/default.aspx" /></entry><entry><title>FTS, FILESTREAM u “Denali”</title><link rel="alternate" type="text/html" href="/blogs/blackdwarf/archive/2010/12/27/fts-filestream-u-denali.aspx" /><id>/blogs/blackdwarf/archive/2010/12/27/fts-filestream-u-denali.aspx</id><published>2010-12-26T23:52:08Z</published><updated>2010-12-26T23:52:08Z</updated><content type="html">&lt;p&gt;Kao poslednji u nizu blog postova oov Full Text Search-u i FILESTREAM podršci, želeo bih da predstavim nove stvari koje dolaze sa SQL Server-om “Denali”, sledećem izdanju SQL Servera. Kao što verovatno znate, isti je trenutno u CTP1 fazi; CTP je pušten u opticaj na PASS konferenciji u Sijetlu, početkom novembra prošle godine. Uskoro će izaći i CTP3 (ne smem da kažem kada tačno, naravno), tako da je ovaj post već odavno trebalo da se desi; mnogu samo da okrivim puno posla koji je ceo SQL tim u MDCS-u imao oko dodataka u dotični CTP3 za “Denali”.&lt;/p&gt;  &lt;h2&gt;FTS – šta je novo?&lt;/h2&gt;  &lt;p&gt;Kao i mnoge druge stvari u SQL Server-u, FTS je doživeo neka poboljšanja.&lt;/p&gt;  &lt;h3&gt;FTS Property Lists&lt;/h3&gt;  &lt;p&gt;“Denali” je dodao jednu prilično lepu stvar kada govorimo o FTS-u. Međutim, pre nego što dođemo do zanimljivih detalja, moram da pokrijem još malo teorije o tome kako rade filteri koje FTS koristi.&lt;/p&gt;  &lt;p&gt;Sigurno ste do sada primetili kada ste radili sa bilo kojim Office dokumentom, da postoji određen broj meta-podataka koji se skladište zajedno sa fajlom, kao što su autor, ključne reči, apstrakt i slično. Neki filteri koji rade pretragu ovih fajlova, umeju da “izvuku” te meta-podatke i da dozvole pretragu i po njima. Integrisana pretraga u Vistu i novije Windows sisteme je jedan primer; ako me sećanje dobro služi, i stariji Windows Search kao i desktop izdanje Google Search-a su to isto mogli.&lt;/p&gt;  &lt;p&gt;Pošto znamo da se dotični filteri koriste i kod FTS-a da bi se indeksirali binarni fajlovi, jedno od pitanja je do sada bilo “kako pretraživati te meta-podatke?” U verzijama pre “Denalija”, to jednostavno nije bilo moguće na jednostavan način, ako I uopšte. Od “Denali”-ja naovamo, tačnije od CTP-a 1 naovamo, ta mogućnost postojo tako što se za svaki indeks može konfigurisati da li se liste čuvaju ili ne. Naravno, zavisno od Filtera koji se koristi; neki Filteri tokom obrađivanja fajlova za pretragu ne ekstrakuju ove meta-podatke.&lt;/p&gt;  &lt;p&gt;Pretraga se vrši konfigurisanjem tzv. &amp;quot;&lt;em&gt;”search property”&lt;/em&gt; listi. Svaka lista se sastoji od onih meta-podataka koje želite da pretražujete. T-SQL komanda koja se koristi uz ove svrhe je &lt;a href="http://msdn.microsoft.com/en-us/library/ee677625(v=SQL.110).aspx"&gt;CREATE SEARCH PROPERTY LIST&lt;/a&gt;, i ona zahteva nekoliko podataka iz samog meta-podatka. Više o ovome svemu možete saznati na &lt;a href="http://msdn.microsoft.com/en-us/library/ee677637(v=SQL.110).aspx"&gt;uvodnoj strani&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Posle uspešnog kreiranja liste meta-podataka, potrebno je &lt;a href="http://msdn.microsoft.com/en-us/library/ee677630(v=SQL.110).aspx"&gt;asocirati full-text indeks sa listom&lt;/a&gt;, i pustiti repopulaciju. Repopulacija indeksa je jedina stvar koja mi se lično ovde ne dopada, mada efekti zavise uglavnom od scenarija korišćenja; ako je indeks poveći, repopulacija može trajati duže vremena. O istom trošku da napomenem, uključivanje meta-podataka u indeks dovodi i do povećanja veličine indeksa. Koliko povećanje, zavisi od filtera i količine meta-podataka.&lt;/p&gt;  &lt;p&gt;Sama pretraga se vrši uz pomoć nove opcije unutar &lt;a href="http://msdn.microsoft.com/en-us/library/ms187787.aspx"&gt;CONTAINS&lt;/a&gt; predikata, koja se zove, očekivano PROPERTY:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; Document &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; Production.Document&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt;   &lt;span style="color:#0000ff;"&gt;WHERE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;CONTAINS&lt;/span&gt;(PROPERTY(Document,&lt;span style="color:#006080;"&gt;&amp;#39;Title&amp;#39;&lt;/span&gt;), &lt;span style="color:#006080;"&gt;&amp;#39;Maintenance OR Repair&amp;#39;&lt;/span&gt;);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h2&gt;FILESTREAM (nestruktuirani podaci)&lt;/h2&gt;

&lt;p&gt;Sam FILESTREAM je ostao nepromenjem u “Denali-ju”, ali je unapređen dodatkom FILETABLE pobošljanja.&lt;/p&gt;

&lt;h3&gt;FILETABLE – dvosmerna komunikacija sa fajl sistemom&lt;/h3&gt;

&lt;p&gt;FILETABLE je logično ishodište FILESTREAM podrške. Kao što smo napomenuli u prošlim serijama, a I kao što trenutno stoji u BOL na MSDN-u, FILESTREAM omogućava samo jednosmernu komunikaciju između fajla I baze podataka, od baze ka fajlu; ukoliko izmenite fajl na hard disku, baza podataka neće moći jednosatvno da se oporavi I SQL Server će je smatrati dovoljno oštećenom da je stavi u &lt;em&gt;corrupted&lt;/em&gt; stanje.&lt;/p&gt;

&lt;p&gt;FileTable koristi FILESTREAM da bi obezbedila aplikacijama ne-transakcioni pristup jednoj tabeli u kojoj se nalaze nestruktuirani podaci. Ovim načinom, obezbedilo se i funkcionalnost koja je već postojala sa FILESTREAM-om, dakle da se koriste mehanizmi oji su ugrađeni u SQL Server za upravljanje tim podacima, kao i da se obezbedi da aplikacije mogu da koriste standardne (kako za koju platformu/jezik) načine pristupa tim fajlovima kao “običnim” fajlovima na fajl sistemu.&lt;/p&gt;

&lt;p&gt;FileTable se sastoji od sledećih kolona:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Kolona sa FILESTREAM atributom koja skladišti sam fajl.&lt;/li&gt;

  &lt;li&gt;stream_id kolona koja je GUID za jedinstveno označavanje FILESTREAM-a.&lt;/li&gt;

  &lt;li&gt;Radi podrške FTS-u (jer sam već pokazao koliko su ove dve osobine SQL Servera zajedno dobra kombinacija) postoje dve kolone, &lt;em&gt;Language &lt;/em&gt;i &lt;em&gt;Type.&lt;/em&gt;&lt;/li&gt;

  &lt;li&gt;Dve kolone tipa &lt;strong&gt;hiearchyid&lt;/strong&gt;, &lt;em&gt;path_locator&lt;/em&gt; i &lt;em&gt;parent_path_locator&lt;/em&gt; koje omogućavaju da se dobije tačna hijerarhija lokacije fajla.&lt;/li&gt;

  &lt;li&gt;Još tačno 10 kolona koje pokazuju razne atribute fajlova.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sve ovo se da videti na strani sa &lt;a href="http://msdn.microsoft.com/en-us/library/ff929068(v=SQL.110).aspx"&gt;osnovnim opisom FileTable-a&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ff929082(v=SQL.110).aspx"&gt;Kreiranje ovakve tabele&lt;/a&gt; se radi preko CREATE TABLE T-SQL komande, sa dodatnom klauzulom “AS FileTable”. Primera radi:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;CREATE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;TABLE&lt;/span&gt; DocumentStore &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; FileTable &lt;span style="color:#0000ff;"&gt;WITH&lt;/span&gt; FileTable_Directory Document&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt;     FILESTREAM_ON FILESTREAMGroup1;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Pristupanje podacima se radi ili preko T-SQL-a ili preko Win32 API-ja:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Postoje tri funkcije koje se mogu pozvati iz T-SQL-a da bi se dobile informacije o podacima uskladištenim u FileTable objektu: &lt;a href="http://msdn.microsoft.com/en-us/library/ff929056(v=SQL.110).aspx"&gt;AllocationSize&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/ff929166(v=SQL.110).aspx"&gt;GetFileNameSpacePath&lt;/a&gt; i &lt;a href="http://msdn.microsoft.com/en-us/library/ff929108(v=SQL.110).aspx"&gt;GetPathLocator&lt;/a&gt;.&lt;/li&gt;

  &lt;li&gt;Pristup i izmena podataka u FileTable se radi kao sa svakom drugom tabelom, dakle preko običnih DML komandi. Međutim, postoji i nekoliko stvari na koje se mora obratiti pažnja, kao što je &lt;a href="http://msdn.microsoft.com/en-us/library/ff929069(v=SQL.110).aspx"&gt;prikazano u dokumentaciji&lt;/a&gt;.&lt;/li&gt;

  &lt;li&gt;I kao poslednja, ali nikako najmanje važna opcija se javlja i &lt;a href="http://msdn.microsoft.com/en-us/library/ff929083(v=SQL.110).aspx"&gt;Fajl sistem API-ji&lt;/a&gt;, preko kojih se može “sa druge strane”, van SQL Servera pristupati fajlovima koji se nalaze u FileTable-u.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Out.&lt;/p&gt;

&lt;p&gt;B.D.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msforge.net/aggbug.aspx?PostID=4377" width="1" height="1"&gt;</content><author><name>blackdwarf</name><uri>http://msforge.net/members/blackdwarf/default.aspx</uri></author><category term="webdev" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/webdev/default.aspx" /><category term="sinergija" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/sinergija/default.aspx" /><category term="sqlserver" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/sqlserver/default.aspx" /></entry><entry><title>SQL Server 2008 / R2, FTS i FILESTREAM pt. II</title><link rel="alternate" type="text/html" href="/blogs/blackdwarf/archive/2010/12/20/sql-server-2008-r2-fts-i-filestream-pt-ii.aspx" /><id>/blogs/blackdwarf/archive/2010/12/20/sql-server-2008-r2-fts-i-filestream-pt-ii.aspx</id><published>2010-12-20T10:04:12Z</published><updated>2010-12-20T10:04:12Z</updated><content type="html">&lt;p&gt;Pošto smo u prethodnoj “epizodi” videli kako se uz pomoć T-SQL interfejsa radi sa FTS-om i FILESTREAM-om, vreme je da se pozabavimo i zanimljivijim delom ovih mogućnosti, a to je pravljenje aplikacija koje koriste ove mogućnosti. &lt;/p&gt;  &lt;p&gt;Postoji mnogo scenarija koji bi mogli da se implementiraju uz ove dve osobine SQL Server-a, ali da bih mogoa ikada da završim ovaj blog post, pobratiću pažnju na jednu: repozitorijum tekstova, koji omogućava skladištenje istih, kao i pretragu ne samo meta-podataka (recimo, imena autora i sl.), već i samog teksta. &lt;/p&gt;  &lt;h3&gt;&lt;strong&gt;Osnovne postavke&lt;/strong&gt;&lt;/h3&gt;  &lt;p&gt;Pre nego što krenem u objašnjavanje aplikacije, želim samo da prođem kroz nekoliko osnovnih postavki od kojih sam krenuo, i na kojima je aplikacija zasnovana:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;U pitanju je veoma jednostavna ASP.NET MVC, dakle web, aplikacija &lt;/li&gt;    &lt;li&gt;U aplikaciji se neće koristiti “čist” T-SQL u svim slučajevima, samo tamo gde je neophodno. &lt;/li&gt;    &lt;li&gt;Pošto je u pitanju ilustracija, ona nije napravljena da bude preterano performantna.&lt;/li&gt;    &lt;li&gt;Šema baze je relativno prosta, i prati šemu iz prošlog posta.&lt;/li&gt;    &lt;li&gt;Meta-podaci se čuvaju pored samog fajla kao dodatne kolone u tabeli (ne postoji automatizacija njihovog prikupljanja, što bi moglo biti urađeno)&lt;/li&gt;    &lt;li&gt;Aplikacija trenutno podržava samo DOCX (Word) fajlove, mada tu niste ograničeni; dovoljno je samo instalirati dodatne IFiltere na mašini gde se “vrti” SQL Server, i drugi fajlovi mogu da se podrže.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Aplikaciju, inače, možete da preuzmete sa mog &lt;a href="http://cid-6a987abbbcbd5556.office.live.com/self.aspx/.Public/Sinergija10/FileStreamGallery.zip"&gt;SkyDrive foldera&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;&lt;strong&gt;Apstrakcije i ostali demoni&lt;/strong&gt;&lt;/h3&gt;  &lt;p&gt;Raditi preko “običnog” T-SQL-a ovih dana nije baš &lt;em&gt;in&lt;/em&gt;, iako postoje ljudi koji i dalje vole da pišu takav kod, i kao što ćemo videti, nećemo moći da izbegnemo dotičan jezik u svim situacijama. Međutim, pošto su ORM-ovi ovih dana veoma popularni, aplikacija će za pristup podacima koristiti primarno Entity Framework 4.0, mada većina stvari koje ću napisati ovde se odnose na sličan način i na LINQ to SQL.&lt;/p&gt;  &lt;p&gt;EF 4.0 mapira FILESTREAM kolone u objekte na veom jednostavan način, kao property tipa byte[]. Dodavanjem vrednosti u osobine ovako mapiranog tipa, EF će automatski praviti potreban T-SQL upit. Naravno, pošto se radi o fajlu, moramo da pazimo da dodamo Stream koji sadrži fajl poslat na server:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; [HttpPost]&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; ActionResult Upload(ArticleInputModel input)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (input.ArticleContent.ContentLength &amp;lt;= 0)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ApplicationException(&lt;span style="color:#006080;"&gt;&amp;quot;You need to upload a valid file&amp;quot;&lt;/span&gt;);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;     Article a = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Article();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;     a.artGUID = Guid.NewGuid();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;     a.Title = input.Title;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;     a.Abstract = input.Abstract;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;     a.Keywords = input.Keywords;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt;     a.ArticleFile = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;byte&lt;/span&gt;[input.ArticleContent.ContentLength];&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt;     a.Type = Path.GetExtension(input.ArticleContent.FileName);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum14"&gt;  14:&lt;/span&gt;     input.ArticleContent.InputStream.Read(a.ArticleFile, 0, input.ArticleContent.ContentLength);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum15"&gt;  15:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum16"&gt;  16:&lt;/span&gt;     &lt;span style="color:#008000;"&gt;// Add to database&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum17"&gt;  17:&lt;/span&gt;     _entities.Articles.AddObject(a);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum18"&gt;  18:&lt;/span&gt;     _entities.SaveChanges();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum19"&gt;  19:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum20"&gt;  20:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; RedirectToAction(&lt;span style="color:#006080;"&gt;&amp;quot;Index&amp;quot;&lt;/span&gt;);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum21"&gt;  21:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Bitne za shvatanje su sledeće linije:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;#4 – &lt;/strong&gt;proveravamo da li je fajl uplodovan, ako nije, bacamo exception&lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;#12&lt;/strong&gt; – pravimo novi byte[] niz koji ima istu dužinu kao i duižina fajla koji nam je poslat&lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;#14&lt;/strong&gt; – preko standardnim Stream metoda učitavamo sadržaj fajla koji je uplodovan na server&lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;#17 –18&lt;/strong&gt; – dodajemo novi Article objekat u ObjectContext (pod nazivom _entities) i pozivamo SaveChanges() metod da bismo ga perzistirali u bazu podataka&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Korak br. 2 u apstrakcijama: FTS&lt;/h3&gt;

&lt;p&gt;FTS, nažalost, nije dobro podržan od strane ORM alata. Ukoliko pogledamo gornje objekte, ako na bilo kom property-ju koji je tipa string pozovem metod Contains(), dobiću T-SQL upit koji koristi LIKE predikat. Ovakvo ponašanje imaju i EF 4.0 i LINQ to SQL (nisam siguran za ostale ORM-ove, ali pretpostavljam da je ponašanje isto/slično i sa njima). Dakle, da bismo koristili FTS, imamo nekoliko opcija:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Generisanje “čistog” T-SQL koda koji šaljemo serveru. LINQ to SQL je naročito dobar za ovo, pošto ima metod ExecuteQuery&amp;lt;T&amp;gt;, koji prima tekst T-SQL upita, i radi projekciju rezultata u tip T kojim smo specijalizovali metod. &lt;/li&gt;

  &lt;li&gt;Pisanje TVF-a, odnosno SPROC-a, kojem ćemo proslediti ključnu reč kao upit, ik zatim vratiti rezultat. &lt;/li&gt;

  &lt;li&gt;Zaobilaženje ORM-ova kompletno, i pisanje specijalnog repoziturijuma za pretragu sa ručnom projekcijom u tipove koji su nam potrebni. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Od svih gore navedenih opcija, ideja TVF-a ili SPROC-a mi se čini kao zaista najbolja, pogotovo jer ne želim da izgubim moć projektovanja rezultata iz baze podataka u objekte. Pošto koristim EF 4.0, moraću da napišem SPROC i da je mapiram; iz meni nepoznatog razloga, EF 4.0 ne podržava TVF-ove koji bi mi bili generalno preferirani način da uradim ovako nešto. Ukoliko koristite LINQ to SQL )(ili neki drugi ORM koji ume da mapira SQL Server-ove TVF-ove), ovo možete da uradite veoma lako.&lt;/p&gt;

&lt;p&gt;Sama procedura je užasno jednostavna, naravno, jer sve što mi je potrebno jeste da uradim pretragu i da vratim nazad rezultate. Izgleda otprilike ovako:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;CREATE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;PROCEDURE&lt;/span&gt; [dbo].[SearchArticlesContents]  &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt;     @keyword nvarchar(4000) &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;BEGIN&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;     &lt;span style="color:#008000;"&gt;-- SET NOCOUNT ON added to prevent extra result sets from &lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;     &lt;span style="color:#008000;"&gt;-- interfering with SELECT statements. &lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;SET&lt;/span&gt; NOCOUNT &lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; * &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; dbo.Articles &lt;span style="color:#0000ff;"&gt;WHERE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;FREETEXT&lt;/span&gt;(ArticleFile, @keyword) &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt; END&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Naravno, pošto je ovo samo primer, malo “varam”, pa koristim u startu FREETEXT predikat, pošto znam da će potencijalno doći više ključnih reči unutar @keyword parametra, i ne želim da pišem kod, niti klijentski, niti serverski da bih detektovao da li postoji potencijalnpo više reči i slično.&lt;/p&gt;

&lt;p&gt;Za EF 4.0, moraćemo da upakujemo upit koji sadrži FTS predikate u stored proceduru. Zatim ćemo projektovati dotičnu proceduru kao metod &lt;a href="http://msdn.microsoft.com/en-us/library/bb896231.aspx"&gt;na standardan način&lt;/a&gt; za EF. Zatim ćemo koristiti dotičnu metodu iz našeg SearchController-a da bismo uradili pretragu, projektovali rezultate nazad u listu članaka i zatim prosledili metodu:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; [HttpGet]&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; ActionResult Search(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; id)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     List&amp;lt;Article&amp;gt; result = _entities.SearchArticlesContents(id).ToList();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; View(&lt;span style="color:#006080;"&gt;&amp;quot;Search&amp;quot;&lt;/span&gt;,result);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Veoma jasan kod, pozivamo SearchArticlesContents metod na _entities kolekciji, i prosleđujemo ključne reči koje je korisnik ukucao u formular, dobijamo kolekciju članaka nazad, prosleđujemo kao ViewData našem View-u. &lt;/p&gt;

&lt;p&gt;Sa ovim malim dodatkom, imamo komplenu aplikaciju koja:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Dozvoljava korisnicima da unesu meta-podatke&lt;/li&gt;

  &lt;li&gt;Pošalju članak na server&lt;/li&gt;

  &lt;li&gt;Pretraže sadržaj tog istog fajla&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;Memorija i bolji načini &lt;/h3&gt;

&lt;p&gt;Iako se ovaj primer aplikacije fokusirao na jedan način kako se može napraviti ovaj scenario, on nije preterano efikasan, jer alocira memoriju na serveru odjedanput u količini koja je jednaka veličini poslatog fajla. Šta ako je fajl, recimo, više gigabajta?&lt;/p&gt;

&lt;p&gt;Za veoma velike fajlove možete da radite streaming sadržaja fajla koristeći sasvim normalne Stream metode, i alocirajući u memoriji odgovarajući bafer. Primer toga možete da vidite u istom solution-u u kojem se nalazi i web aplikacija, nalazi se u projektu za CLI aplikaciju. Objašnjenje koda nije teško, ali ostaje za još jedan blog post. &lt;img style="border-bottom-style:none;border-right-style:none;border-top-style:none;border-left-style:none;" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://msforge.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/blackdwarf/wlEmoticon_2D00_smile_5F00_751CA48F.png" /&gt;&lt;/p&gt;

&lt;p&gt;Out.&lt;/p&gt;

&lt;p&gt;B.D.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msforge.net/aggbug.aspx?PostID=4372" width="1" height="1"&gt;</content><author><name>blackdwarf</name><uri>http://msforge.net/members/blackdwarf/default.aspx</uri></author><category term="dotnetgeneral" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/dotnetgeneral/default.aspx" /><category term="sinergija" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/sinergija/default.aspx" /></entry><entry><title>SQL Server 2008 / R2, FTS i FILESTREAM</title><link rel="alternate" type="text/html" href="/blogs/blackdwarf/archive/2010/11/27/sql-server-2008-fts-i-filestream.aspx" /><id>/blogs/blackdwarf/archive/2010/11/27/sql-server-2008-fts-i-filestream.aspx</id><published>2010-11-27T13:04:00Z</published><updated>2010-11-27T13:04:00Z</updated><content type="html">&lt;p&gt;Pozdrav svima, i unapred izvinjenje na podužem postu, kao i na činjenici da dugo vremena nisam ni&amp;scaron;ta postovao. U ovom postu ću pokazati kako se može integrisati podr&amp;scaron;ka za indeksiranje i pretragu tekstualnih podataka i binarnih fajlova koja je integrisanja u SQL Server 2008 / R2 sa novim tipom kolone koji je dostupan od iste verzije, čuvenim FILESTREAM-om.&lt;/p&gt;
&lt;h2&gt;
&lt;p&gt;&lt;strong&gt;FTS i kako se pravi&lt;/strong&gt;&lt;/p&gt;
&lt;/h2&gt;
&lt;p&gt;FTS je skraćenica od &lt;em&gt;Full Text Search&lt;/em&gt; i predstavlja servis unutar SQL Servera koji omogućava pretragu nad tekstualnim podacima. &lt;/p&gt;
&lt;p&gt;Naravno, &amp;ldquo;pretraga nad tekstualnim podacima&amp;rdquo; nije ba&amp;scaron; sjajno obja&amp;scaron;enjenje. Do sada su progameri re&amp;scaron;avali problem pretrage tekstualnih podataka unutar relacione baze ili kori&amp;scaron;ćenjem &lt;a href="http://www.google.com/url?sa=t&amp;amp;source=web&amp;amp;cd=1&amp;amp;ved=0CBIQFjAA&amp;amp;url=http%3A%2F%2Fmsdn.microsoft.com%2Fen-us%2Flibrary%2Fms179859.aspx&amp;amp;ei=x-vnTLDLG8_Mswatp8jHCw&amp;amp;usg=AFQjCNH2bEX6rZvE3ID4ux00XmRmkgA11Q"&gt;LIKE&lt;/a&gt; predikata ili obavljanjem pretrage unutar aplikacije (kori&amp;scaron;ćenjem f-ja za manipulaciju stringovima, regularnim izrazima, pravljenjem sopstveng ili kori&amp;scaron;ćenjem gotovo full-tekst indeksa kao &amp;scaron;to je Lucene/Lucene.NET). Naravno, sa svim ovim re&amp;scaron;enjima postoje određeni problemi, sa LIKE ponajvi&amp;scaron;e. FTS unutar SQL Servera poku&amp;scaron;ava re&amp;scaron;i ovaj problem kori&amp;scaron;ćenjem, s jedne strane, full-text indeksa, a s druge strane uvođenjem dva nova predikata koji daju mogućnost daleko bogatije pretrage od LIKE-a ili nekog sličnog re&amp;scaron;enja.&lt;/p&gt;
&lt;p&gt;FUll-text indeksi su bili standardna pojava već od SQL Servera 2000. Međutim, od te verzije, do verzije 2008 (pa samim tim i do verzije 2008 R2 koja je sada aktuelna), full-text indeksi su bili čuvani van SQL Server baze. Sam proces koji je koristio te indekse da bi pretraživao tekstualne podatke je takođe bio eksteran SQL Serveru. Od verzije 2008 SQL Servera, i indeksi, kao i proces koji ih pretražuje se nalaze unutar baze podataka. Pored pravljenja struktura u memoriji koji omogućavau daleko brži dolazak do sadržaja polja, omogućava i pretraživanje dokumenata. &lt;/p&gt;
&lt;p&gt;Kada kažem &amp;ldquo;dokument&amp;rdquo;, mislim upravo na ono &amp;scaron;to vam pada na pamet: binarni fajlovi u, recimo, PDF, XPS, DOCS ili nekom trećem formatu. Ideja je da uzmete jedan dokument, smestite ga u varbinary(max) kolonu i pored njega postavite jo&amp;scaron; jednu tekstualnu kolonu koja određuje ekstenziju. SQL Server FTS će koristiti kolonu u kojoj se nalazi ekstenzija (tip) fajla da učita filter koji može da otvori i pročita taj fajl. Filter je binarni kod koji implementira IFilter interfejs, i sličan je onome koji se koristi unutar Windows desktop pretrage.&lt;/p&gt;
&lt;p&gt;Dakle, ako napravite ovakvu tabelu i napravite full-text indeks na njoj, FTS će umeti da izvuće tip fajla koji je skladi&amp;scaron;ten u tabeli, da učita, ako je na raspolaganju, odgovarajući filter, otvori dokument i indeksira njegov sadržaj. Gornje &amp;ldquo;ako je na raspolaganju&amp;rdquo; je jako bitno jer ne dolaze svi filter OOB sa SQL Serverom. Da bi ste videli koji su filteri trenutno na raspolaganju u va&amp;scaron;oj instalaciji SQL Servera, iskoristite &lt;a href="http://technet.microsoft.com/en-us/library/ms174373.aspx"&gt;sys.fulltext_document_types&lt;/a&gt;, a ako želite da vidite koji su filter učitani na SQL Serveru, pogledajte izlaz &lt;a href="http://technet.microsoft.com/en-us/library/ms187985.aspx"&gt;sp_help_fulltext_system_components&lt;/a&gt; storke sa &amp;lsquo;filter&amp;rsquo; parametrom:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;
&lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span id="lnum1" style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;exec&lt;/span&gt; sp_help_fulltext_system_components &lt;span style="color:#006080;"&gt;&amp;#39;filter&amp;#39;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2&gt;FILESTREAM tip podatka&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://technet.microsoft.com/en-us/library/bb933993.aspx"&gt;FILESTREAM&lt;/a&gt; tip je novina koja je uvedena u SQL-u 2008. U pitanju je tip koji re&amp;scaron;ava jedan poznat scenario. Imam potrebu da skladi&amp;scaron;tim binarne fajlove u bazi podataka. Ukoliko krenem da re&amp;scaron;avam taj problem, imam dva moguća re&amp;scaron;enja:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Smestim ceo fajl u neki BLOB u bazi. Iako na prvi pogled dobro re&amp;scaron;enje, ima dosta problema, na prvom mestu to &amp;scaron;to su BLOB-ovi ui SQL Serveru ograničeni po pitanju prostora na čuvenih 2 GB po redu. Isto tako, rad sa ovim BLOB-ovima nije najsrećnije re&amp;scaron;enje. &lt;/li&gt;
&lt;li&gt;Smestim ceo fajl na fajl sistem, a u bazi samo putanju do njega. Re&amp;scaron;ili smo problem prostora i &amp;ldquo;urednosti&amp;rdquo;, ali sada imamo problem držanja podataka u konzistentnom stanju, jer nam je jedan deo van baze podataka. Kada radimo, recimo, ROLLBACK transkacije, kada da izbri&amp;scaron;emo fajl sa fajl sistema? &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;FILESTREAM radi tako &amp;scaron;to sa jedne strane skladi&amp;scaron;ti u tabeli unutar SQL Servera pointer ka fajlu, a s adruge strane sam fajl fizički drži na fajl sistemu, na lokaciji na kojoj mi kažemo da bi trebalo da se drži pod nekim jedinstvenim GUID-om. Ideja je da se dobije najbolje od oba sveta: fajl sistem za skladi&amp;scaron;tenje fajlova (&amp;scaron;to je njegov posao, na kraju krajeva) i relaciona baza podataka za rad sa njim transparentno. SQL Server se i dalje brine o tom fajlu, on učestvuje u svim transakcijama i tome slično.&lt;/p&gt;
&lt;p&gt;Povezivanjem FTS-a i FILESTREAM-a, možemo da napravimo prilično zanimljive aplikacije. &lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Neke osnovne postavke&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Po&amp;scaron;to radimo sa bazom podataka, prvo ćemo da ustanovimo na kojoj bazi podataka radimo, odnosno koje su nam strukture tabela. Ime baze ovde nije toliko bitno, ali ono &amp;scaron;to jeste bitno jeste struktura tabele:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;
&lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span id="lnum1" style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;CREATE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;TABLE&lt;/span&gt; [Articles](&lt;/pre&gt;

&lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span id="lnum2" style="color:#606060;"&gt;   2:&lt;/span&gt;     [artGUID] UNIQUEIDENTIFIER &lt;span style="color:#0000ff;"&gt;ROWGUIDCOL&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NOT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NULL&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;UNIQUE&lt;/span&gt;,&lt;/pre&gt;

&lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span id="lnum3" style="color:#606060;"&gt;   3:&lt;/span&gt;     Title nvarchar(&lt;span style="color:#0000ff;"&gt;max&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;NOT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NULL&lt;/span&gt;,&lt;/pre&gt;

&lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span id="lnum4" style="color:#606060;"&gt;   4:&lt;/span&gt;     Abstract nvarchar(&lt;span style="color:#0000ff;"&gt;max&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;,&lt;/pre&gt;

&lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span id="lnum5" style="color:#606060;"&gt;   5:&lt;/span&gt;     [Resume] nvarchar(&lt;span style="color:#0000ff;"&gt;max&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;,&lt;/pre&gt;

&lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span id="lnum6" style="color:#606060;"&gt;   6:&lt;/span&gt;     [Keywords] nvarchar(&lt;span style="color:#0000ff;"&gt;max&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;NULL&lt;/span&gt;,&lt;/pre&gt;

&lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span id="lnum7" style="color:#606060;"&gt;   7:&lt;/span&gt;     [Type] &lt;span style="color:#0000ff;"&gt;varchar&lt;/span&gt;(5) &lt;span style="color:#0000ff;"&gt;NOT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NULL&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;DEFAULT&lt;/span&gt; &lt;span style="color:#006080;"&gt;&amp;#39;.docx&amp;#39;&lt;/span&gt;,&lt;/pre&gt;

&lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span id="lnum8" style="color:#606060;"&gt;   8:&lt;/span&gt;     [ArticleFile] [varbinary](&lt;span style="color:#0000ff;"&gt;max&lt;/span&gt;) FILESTREAM &lt;span style="color:#0000ff;"&gt;NOT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NULL&lt;/span&gt;,&lt;/pre&gt;

&lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span id="lnum9" style="color:#606060;"&gt;   9:&lt;/span&gt;     [CreateTimestamp] [&lt;span style="color:#0000ff;"&gt;timestamp&lt;/span&gt;] &lt;span style="color:#0000ff;"&gt;NOT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NULL&lt;/span&gt;,&lt;/pre&gt;

&lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span id="lnum10" style="color:#606060;"&gt;  10:&lt;/span&gt;  &lt;span style="color:#0000ff;"&gt;CONSTRAINT&lt;/span&gt; [PK_FTS_Articles] &lt;span style="color:#0000ff;"&gt;PRIMARY&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;KEY&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;CLUSTERED&lt;/span&gt; (artGUID &lt;span style="color:#0000ff;"&gt;ASC&lt;/span&gt;)&lt;/pre&gt;

&lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span id="lnum11" style="color:#606060;"&gt;  11:&lt;/span&gt;  )&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Iako prosta, ova tabela će nam poslužiti da ilustrujemo sve osnovne koncepte koji su nam potrebni. Primetite u liniji 8 FILESTREAM opciju. Ovo govori SQL Serveru da će ta kolona biti FILESTREAM. Stoga imamo i liniju 2, odnosno određivanje GUID kolone u tabeli, koja je nenophodna da bi FILESTREAM radio. &lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Korak 1: pravljenje &lt;em&gt;full-text &lt;/em&gt;indeksa&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Kreiranje full-text indeksa (od sada skraćeno FTI) je veoma prosto, i počinje prvo od kreiranja full-text catalog-a. Full-text katalozi sadrže u sebi sve indekse koje budete kreirali. Kao i sve druge T-SQL komande, ni ovo nije preterano te&amp;scaron;ka:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;
&lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span id="lnum1" style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;CREATE&lt;/span&gt; FULLTEXT &lt;span style="color:#0000ff;"&gt;CATALOG&lt;/span&gt; TestFtsCatalog&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Zatim možemo da krenemo sa pravljenjem indeksa na tabelama koje nas interesuju. FTI-evi se mogu praviti jedan po koloni, ali jedan indeks može sadržati vi&amp;scaron;e kolona; tipovi koji su dozvoljeni su bilo koji veliki tekstualni tipovi (NVARCHAR(MAX), TEXT, NTEXT), binarni tipovi (VARBINARY(MAX)) kao i XML tip. Kreiranje ove vrste indeksa se radi sledećom T-SQL komandom:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;
&lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span id="lnum1" style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;CREATE&lt;/span&gt; FULLTEXT &lt;span style="color:#0000ff;"&gt;INDEX&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt; &lt;/pre&gt;

&lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span id="lnum2" style="color:#606060;"&gt;   2:&lt;/span&gt; dbo.Articles(Title,Abstract,[Resume],[Keywords],ArticleFile TYPE &lt;span style="color:#0000ff;"&gt;COLUMN&lt;/span&gt; [Type]) &lt;/pre&gt;

&lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span id="lnum3" style="color:#606060;"&gt;   3:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;KEY&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;INDEX&lt;/span&gt; PK_FTS_Articles &lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt; TestFtsCatalog &lt;span style="color:#0000ff;"&gt;WITH&lt;/span&gt; CHANGE_TRACKING = AUTO&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;Veoma jednostavno obja&amp;scaron;njeno:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Kreiramo indeks na tabeli, i prosleđujemo kolone na kojima želimo da napravimo indeks. Specijalna stvar ovde je TYPE COLUMN direktiva, koja određuje koja kolona će FTS-u dati informaciju o tipu fajla. &lt;/li&gt;
&lt;li&gt;KEY INDEX deo komande daje FTS-u ime indeksa koji jedinstveno određuje svaki red. U pitanju je &lt;strong&gt;ime indeksa&lt;/strong&gt;, ne ime kolone. &lt;/li&gt;
&lt;li&gt;WITH CHANGE TRACKING je jasna sama po sebi, i određuje dinamiku populacije indeksa. Sa ovako postavljenom opcijom (AUTO), indeks će se populisati automatski sa promenom podataka u tabeli. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Sa ovom komandom imamo gotov indeks. Ono &amp;scaron;to je sada ostalo jeste da ubacimo nekoliko redova i da radimo &lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Korak 2: ubacivanje redova (fajlova)&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Iako će se ovo činiit kao &amp;ldquo;varanje&amp;rdquo;, generalno nećemo sad apokazati &lt;em&gt;verbatim&lt;/em&gt; komande za unos fajlova, pogotovo zato &amp;scaron;to bi se za to zahtevao programski kod. Umesto toga, pretpotavimo da sam ubacio jedan Word (DOCX) fajl. Ono &amp;scaron;to je jedino bitno jeste da se u tom fajlu nalazi nekoliko ključnih reči koje bi trebalo da potražim.&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Korak 3: pretraga &lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Kada jednom imamo fajl unutar baze podataka, pretraga se radi na identičan način kao i kada pretražujemo &amp;ldquo;generalno&amp;rdquo; kolone sa FTS-om. Za to su nam ostavljena dva nova predikata, &lt;a href="http://msdn.microsoft.com/en-us/library/ms187787.aspx"&gt;CONTAINS&lt;/a&gt; i &lt;a href="http://msdn.microsoft.com/en-us/library/ms176078.aspx"&gt;FREETEXT&lt;/a&gt;, odnosno &lt;a href="http://msdn.microsoft.com/en-us/library/ms189760.aspx"&gt;CONTAINSTABLE&lt;/a&gt; i &lt;a href="http://msdn.microsoft.com/en-us/library/ms177652.aspx"&gt;FREETEXTTABLE&lt;/a&gt; ako želimo da dobijemo i rangiranje. &lt;/p&gt;
&lt;p&gt;Sama pretraga se radi veoma jednostavno, uz pomoć gornjih predikata:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;
&lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span id="lnum1" style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; * dbo.Articles &lt;span style="color:#0000ff;"&gt;WHERE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;CONTAINS&lt;/span&gt;(ArticleFile,’query’)&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;CONTAINS predikat, kao &amp;scaron;to će dokumentacija pokazati, prima samo jednu reč, ali u sebi sadrži i omanji pod-jezik za pretragu. Ukoliko bismo želeli da dodamo i reč &amp;ldquo;performance&amp;rdquo; u pretragu, mogli bismo da kažemo sledeće:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;
&lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span id="lnum1" style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; * &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; dbo.Articles &lt;span style="color:#0000ff;"&gt;WHERE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;CONTAINS&lt;/span&gt;(ArticleFile,’query &lt;span style="color:#0000ff;"&gt;OR&lt;/span&gt; performance’)&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Ali ako ba&amp;scaron; želimo OR logiku, možemo da iskoristimo i FREETEXT predikat, po&amp;scaron;to on prima vi&amp;scaron;e ključnih reči, i podrazumeva OR logiku:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;
&lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span id="lnum1" style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; * &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; dbo:Articles &lt;span style="color:#0000ff;"&gt;WHERE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;FREETEXT&lt;/span&gt;(ArticleFile,’query performance’)&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Kako god da želimo da uradimo, efekat je isti. FTS će iskoristiti indeks, pročitati iz njega da li imamo te ključne reči bilo gde, i ako imamo iste u fajlu, vratiće nam record sa tim fajlom. Ni&amp;scaron;ta lak&amp;scaron;e, zar ne?&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Sledeći koraci&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Ovo je bio samo uvod u FILESTREAM i FTS mogućnosti SQL Servera 2008 / R2. O istima možete pročitati daleko vi&amp;scaron;e u odgavarjućim sekcijama BOL-a na MSDN-u ili TechNetu. U sledećem delu blog postova, prikazaću jednu prostu aplikaciju, i o istim tro&amp;scaron;lu pokazati kako možete da u VS2010, koristeći Entity Framework 4 i ASP.NET MVC napravite veoma jednostavnu aplikaciju za rad sa ovim mogućnostima.&lt;/p&gt;
&lt;p&gt;Out.&lt;/p&gt;
&lt;p&gt;B.D.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msforge.net/aggbug.aspx?PostID=4357" width="1" height="1"&gt;</content><author><name>blackdwarf</name><uri>http://msforge.net/members/blackdwarf/default.aspx</uri></author><category term="dotnetgeneral" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/dotnetgeneral/default.aspx" /><category term="sinergija" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/sinergija/default.aspx" /></entry><entry><title>Sinergija10 – materijali</title><link rel="alternate" type="text/html" href="/blogs/blackdwarf/archive/2010/11/18/sinergija10-kod-i-slajdovi.aspx" /><id>/blogs/blackdwarf/archive/2010/11/18/sinergija10-kod-i-slajdovi.aspx</id><published>2010-11-18T16:26:05Z</published><updated>2010-11-18T16:26:05Z</updated><content type="html">&lt;p&gt;Posle dugo vremena nepostovanja ničega, ukratko smao da postavim linkove ka slajdovima i kodu koji sam koristio na ovogodišnjoj Sinergiji.&lt;/p&gt;  &lt;p&gt;Slajdove (PPTX fajl) i demoe (.sql fajlove i zip sa VS2010 solution-om) možete naći na &lt;a href="http://cid-6a987abbbcbd5556.office.live.com/browse.aspx/.Public/Sinergija10?uc=4"&gt;SkyDrive-u&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Naravno, ovde je kod sma za FILESTREAM i FTS deo. Isto tako, konačno mislim da sam našao vremena da završim blog post o korišćenju i jednog i drugog zajedno, tako da ako niste bili na predavanju, imaćete prilike da pročitate u čemu je poenta uskoro.&lt;/p&gt;  &lt;p&gt;Out.&lt;/p&gt;  &lt;p&gt;B.D.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msforge.net/aggbug.aspx?PostID=4351" width="1" height="1"&gt;</content><author><name>blackdwarf</name><uri>http://msforge.net/members/blackdwarf/default.aspx</uri></author><category term="sinergija08" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/sinergija08/default.aspx" /><category term="dotnetgeneral" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/dotnetgeneral/default.aspx" /><category term="sinergija" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/sinergija/default.aspx" /></entry><entry><title>nuPack, MVC3 Beta i još par stvari za izgubljen vikend</title><link rel="alternate" type="text/html" href="/blogs/blackdwarf/archive/2010/10/07/nupack-mvc3-beta-i-jo-par-stvari-za-izgubljen-vikend.aspx" /><id>/blogs/blackdwarf/archive/2010/10/07/nupack-mvc3-beta-i-jo-par-stvari-za-izgubljen-vikend.aspx</id><published>2010-10-06T22:41:43Z</published><updated>2010-10-06T22:41:43Z</updated><content type="html">&lt;p&gt;OK, postoje trenuci kada zaista mislim da tamo “gore” (severno) sede neki ljudi, koji nešto kapiraju…kanda. &lt;/p&gt;  &lt;p&gt;nuPack je komad softvera koji vam olakšava da pakujete bilbioteku u vašu .NET aplikaciju. Odete na &lt;a href="http://nupack.codeplex.com/documentation?title=Getting%20Started"&gt;http://nupack.codeplex.com/documentation?title=Getting%20Started&lt;/a&gt;, i pratite šta tamo piše. Kada instalirate ovu VS2010 ekstenziju, dovoljno je da u VS-u odete na View –&amp;gt; Other Windows –&amp;gt; Package Manager Console. Dobijete PowerShell konzolu i onda možete da krenete da radite sa njom. Možete i preko GUI-ja, naravno, na desni klik, ali ko još želi tako? (Pored toga nećete, ako ste ikada radili u ActiveState Perlu, osetiti oštru žaoku nostalgije jer sve ovo podseća na &lt;a href="http://en.wikipedia.org/wiki/Perl_package_manager"&gt;ppm&lt;/a&gt;). Reference za CLI komande se nalaze na &lt;a href="http://nupack.codeplex.com/documentation?title=Package%20Manager%20Console%20Command%20Reference"&gt;http://nupack.codeplex.com/documentation?title=Package%20Manager%20Console%20Command%20Reference&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;O istom trošku, možete da odete i na &lt;a href="http://go.microsoft.com/fwlink/?LinkID=191795"&gt;link za installer&lt;/a&gt; za MVC 3 beta i da njega skinete. Ovo još uvek nisam stigao da pogledam, ali sam čitao kod Breda Vilsona da je dodato dosta DI/IoC koda u sam MVC programski kod, radi lakšeg testiranja i kasnije, eventualne, izmene/zamene od strane korisnika.&lt;/p&gt;  &lt;p&gt;Nadam se da imate da odvojite vikend…hm…moram da uradim nešto povodom ovoga… &lt;img style="border-bottom-style:none;border-right-style:none;border-top-style:none;border-left-style:none;" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://msforge.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/blackdwarf/wlEmoticon_2D00_smile_5F00_5C62C1B9.png" /&gt;&lt;/p&gt;  &lt;p&gt;Out.&lt;/p&gt;  &lt;p&gt;B.D.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msforge.net/aggbug.aspx?PostID=4336" width="1" height="1"&gt;</content><author><name>blackdwarf</name><uri>http://msforge.net/members/blackdwarf/default.aspx</uri></author></entry><entry><title>WebMatrix se vraća, sa stilom!</title><link rel="alternate" type="text/html" href="/blogs/blackdwarf/archive/2010/07/07/webmatrix-se-vra-a-sa-stilom.aspx" /><id>/blogs/blackdwarf/archive/2010/07/07/webmatrix-se-vra-a-sa-stilom.aspx</id><published>2010-07-07T06:00:00Z</published><updated>2010-07-07T06:00:00Z</updated><content type="html">&lt;p&gt;WebMatrix je ime koje vraća uspomene. U vreme kada je .NET 1.1 bio aktuelan, Nikhil Kothari je napravio &lt;a href="http://en.wikipedia.org/wiki/ASP.NET_Web_Matrix%20"&gt;lagani alat&lt;/a&gt;, koji se mogao besplatno preuzeti, i koji je služio kao malo razvojno okruženje za ASP.NET razvoj. Imao je neke fine stvari, recimo radnu povr&amp;scaron;inu sličnu kao i tada&amp;scaron;nja verzija Visual Studia (2003 je bila aktuelna), bojenje sintakse, neki rudimentarni Intellisense ako se dobro sećam, i tome slično. Naravno, pojavom Express izdanja, WebMatrix je izgubio na značaju i tome slično. Ako vas interesuje malo istorije, &lt;a href="http://ondotnet.com/pub/a/dotnet/2002/08/12/aspmatrix.html"&gt;onDotNet ima članak&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WebMatrix u novom ruhu&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Juče smo izdali WebMAtric u novom ruhu. U pitanju je itegrisani alat za sve ljude koji žele da veoma brzo i jednostavno naprave web sajt, doteraju neki ili iskoriste postojeću web aplikaciju, a sve to na &lt;a href="http://www.microsoft.com/web/"&gt;Microsoft web platformi&lt;/a&gt;. Vi&amp;scaron;e o njemu možete naći na &lt;a href="http://www.microsoft.com/web/webmatrix"&gt;WebMatrix matičnoj stranici&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Hteo sam da napi&amp;scaron;em sva&amp;scaron;ta ne&amp;scaron;to korisno na ovu temu, ali sam onda pogledao i skapirao da &lt;a href="http://weblogs.asp.net/scottgu/about.aspx"&gt;&amp;ldquo;The Gu&amp;rdquo;&lt;/a&gt; ima jedan od svojih &amp;ldquo;epskih postova&amp;rdquo; u kojem imate sve detaljno opisano. Dovoljno je da &lt;a href="http://weblogs.asp.net/scottgu/archive/2010/07/06/introducing-webmatrix.aspx"&gt;odete na dotični post&lt;/a&gt;, i da pogledate o čemu se radi.&lt;/p&gt;
&lt;p&gt;Pored toga, preporučujem da pogledate i tri druga blog posta koja je napisao, a koji predstavljaju pojedinačne prikaze nekih od kompomentni novog WebMatrix-a:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://weblogs.asp.net/scottgu/archive/2010/06/28/introducing-iis-express.aspx"&gt;IIS Developer Express&lt;/a&gt;, kao &amp;scaron;to mu samo ime kaže, je mini IIS sa svim mogućnostima Microsoft-ovog web servera, ali koji se startuje i radi na sličan način kao i ASP.NET development server.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://weblogs.asp.net/scottgu/archive/2010/06/30/new-embedded-database-support-with-asp-net.aspx"&gt;SQL Server Compact Edition&lt;/a&gt;, &amp;lsquo;nuff said.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://weblogs.asp.net/scottgu/archive/2010/07/02/introducing-razor.aspx"&gt;ASP.NET &amp;ldquo;Razor&amp;rdquo;&lt;/a&gt;, nova sintaksa za aspx strane i (uskoro) novi MVC View engine.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Out.&lt;/p&gt;
&lt;p&gt;B.D.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msforge.net/aggbug.aspx?PostID=4271" width="1" height="1"&gt;</content><author><name>blackdwarf</name><uri>http://msforge.net/members/blackdwarf/default.aspx</uri></author><category term="aspnet" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/aspnet/default.aspx" /><category term="mvc" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/mvc/default.aspx" /><category term="webdev" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/webdev/default.aspx" /><category term="dotnetgeneral" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/dotnetgeneral/default.aspx" /></entry><entry><title>ScriptJunkie</title><link rel="alternate" type="text/html" href="/blogs/blackdwarf/archive/2010/06/19/scriptjunkie.aspx" /><id>/blogs/blackdwarf/archive/2010/06/19/scriptjunkie.aspx</id><published>2010-06-19T06:41:13Z</published><updated>2010-06-19T06:41:13Z</updated><content type="html">&lt;p&gt;Zabavno šta sve moja korporacija ume da napravi…&lt;a title="http://msdn.microsoft.com/scriptjunkie" href="http://msdn.microsoft.com/scriptjunkie"&gt;http://msdn.microsoft.com/scriptjunkie&lt;/a&gt;, novi MSDN sajt fokusiran na CSS, HTML i JavaScript.&lt;/p&gt;  &lt;p&gt;Out.&lt;/p&gt;  &lt;p&gt;B.D.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msforge.net/aggbug.aspx?PostID=4266" width="1" height="1"&gt;</content><author><name>blackdwarf</name><uri>http://msforge.net/members/blackdwarf/default.aspx</uri></author><category term="webdev" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/webdev/default.aspx" /></entry><entry><title>Doing PHP in Tallinn, Estonia</title><link rel="alternate" type="text/html" href="/blogs/blackdwarf/archive/2010/05/28/doing-php-in-tallinn-estonia.aspx" /><id>/blogs/blackdwarf/archive/2010/05/28/doing-php-in-tallinn-estonia.aspx</id><published>2010-05-28T15:36:21Z</published><updated>2010-05-28T15:36:21Z</updated><content type="html">&lt;p&gt;I recently had the immense pleasure of presenting Microsoft’s PHP story in Tallinn, Estonia for around 2.5 hours. Since this blog post is also for the people who attended, it wil be in English (most of my other blog posts are in Serbian). &lt;/p&gt;  &lt;p&gt;In case you didn’t know, Microsoft has done a lot in the past 4 years in terms of getting &lt;a href="http://www.php.net"&gt;PHP&lt;/a&gt; running smoothly and speedely on Windows. This is not just to say that we wanted to improve the dev/test cycle of developing PHP apps, since Windows is used as a development operating system, but also the deployment part of the things. In order to do that, we implemented a lot of features in IIS 7.0 and onwards to that regard. The main one is &lt;a href="http://en.wikipedia.org/wiki/Fastcgi"&gt;FastCGI&lt;/a&gt;, an extension to the venerable &lt;a href="http://en.wikipedia.org/wiki/Common_Gateway_Interface"&gt;CGI&lt;/a&gt; protocol, that allows the server to pool external processes, thus decreasing the cost of starting new PHP interpreter process, which on Windows is slow. &lt;/p&gt;  &lt;p&gt;On top of that, we have developed a huge amount of stuff around PHP, like WinCache, the caching solution for PHP opcode, or the new SQL Server drive (currently in 2.0 development, you can get the CTP) to target SQL Server. &lt;/p&gt;  &lt;p&gt;I have made the deck I presented available on my &lt;a href="http://cid-6a987abbbcbd5556.skydrive.live.com/self.aspx/.Public/php.pptx"&gt;SkyDrive&lt;/a&gt;, and I would just like to provide several important links to all those who are interested in this topic.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;PHP Windows binaries are on &lt;a href="http://windows.php.net/"&gt;http://windows.php.net/&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;You can get the Web Platform Installer on &lt;a href="http://www.microsoft.com/web"&gt;http://www.microsoft.com/web&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;The Web App Gallery you can view on &lt;a title="http://www.microsoft.com/web/gallery/default.aspx" href="http://www.microsoft.com/web/gallery/default.aspx"&gt;http://www.microsoft.com/web/gallery/default.aspx&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;The PHP SQL Server Driver is on &lt;a title="SQL Server Driver for PHP" href="http://www.microsoft.com/sqlserver/2005/en/us/PHP-Driver.aspx"&gt;SQL Server Driver for PHP&lt;/a&gt;, and you can see the team’s blog on &lt;a title="Microsoft SQL Server Driver for PHP Team Blog" href="http://blogs.msdn.com/sqlphp/"&gt;Microsoft SQL Server Driver for PHP Team Blog&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;oData PHP SDK is stationed on CodePlex, of course, on &lt;a title="http://odataphp.codeplex.com/" href="http://odataphp.codeplex.com/"&gt;http://odataphp.codeplex.com/&lt;/a&gt;&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;If you want, you can visit &lt;a href="http://odata.org/producers"&gt;http://odata.org/producers&lt;/a&gt; to see all the feeds you can test out&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;The &lt;a href="http://blogs.msdn.com/b/interoperability/"&gt;Interoperability @ Microsoft&lt;/a&gt; blog is a good place to get new stuff that we do concerning interop with various other platforms, so be sure to get the RSS feed if you’re interested in those things&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;That’s it from my side. Remember, make Web, not War. :)&lt;/p&gt;  &lt;p&gt;Out.&lt;/p&gt;  &lt;p&gt;B.D.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msforge.net/aggbug.aspx?PostID=4251" width="1" height="1"&gt;</content><author><name>blackdwarf</name><uri>http://msforge.net/members/blackdwarf/default.aspx</uri></author><category term="webdev" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/webdev/default.aspx" /></entry><entry><title>Web deploy je…čudo…</title><link rel="alternate" type="text/html" href="/blogs/blackdwarf/archive/2010/05/06/web-deploy-je-udo.aspx" /><id>/blogs/blackdwarf/archive/2010/05/06/web-deploy-je-udo.aspx</id><published>2010-05-06T13:13:52Z</published><updated>2010-05-06T13:13:52Z</updated><content type="html">&lt;p&gt;Ova priča će početi malo zaokolno. Kao što ste sigurno svesni, Microsoft je već nekoliko puta tokom (veoma intezivnog) testiranja Visual Studia 2010 objavio virtuelne mašine za testiranje proizvoda. Brian Keller je, međutim, izdao pravi dragulj, a to je jedna vrituelna mašina (u tri različita formata), sa sve podacima i napakovana do vrha svim mogućim softverom radi testiranja ALM mogućnosti VS2010 familijie proizvoda. Istu možete da skinete &lt;a href="http://blogs.msdn.com/briankel/archive/2010/03/18/now-available-visual-studio-2010-release-candidate-virtual-machines-with-sample-data-and-hands-on-labs.aspx"&gt;na ovom linku&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Gdin. Keller nije još uvek izdao refresh, a pošto svi znamo da se Visual Studio 2010 lako instaslira, odlučio sam da prosto napravim svoju kopiju ove mašine i da na nju instaliram RTM verzije svih potrebnih alata (uglavnom VS2010 Ultimate i TFS 2010).&lt;/p&gt;  &lt;h2&gt;Šok #1: TFS 2010 se deinstalira i instalira za oko 20-ak minuta!&lt;/h2&gt;  &lt;p&gt;Zaista za razliku od prethodne verzije (2008), TFS 2010 se deinstalirao dok sam rekao “keks”, a instalacija je trajala sveukupno 10 minuta. Jedan confg wizard posle instalacije, dobio sam kompletne podatke, pošto TFS 2010 sada konačno ima “upgrade” opciju koja radi savršeno.&lt;/p&gt;  &lt;h2&gt;Šok #2: web deployment zaista radi kako je reklamirano!&lt;/h2&gt;  &lt;p&gt;Naravno, da je sve prošlo kako treba, ne bi bilo ovog posta. Da bih se uverio da sve radi kako treba, pokrenuo sam &lt;a href="http://msdn.microsoft.com/en-us/library/dd286594.aspx"&gt;Test Manager&lt;/a&gt; i pregledao postojeće testove za web aplikaciju koja se isporučuje uz ovu virtuelnu mašinu (radi oprobavanja svih novih funkcionalnosti, naravno).&lt;/p&gt;  &lt;p&gt;Pokrenuo sam test, sve je lepo krenulo, do…recimo 2 koraka, kada mi je &lt;a href="http://msdn.microsoft.com/en-us/library/dd286680.aspx"&gt;test runner&lt;/a&gt; javio da ne može da nađe link koji je potrebno da “pritisne” da bi se test nastavio na sledeći korak. Zbunjen, pogledao sam šta je došlo u instanci browser-a, i video samo prosto error stranu. Posle par pokušaja, shvatio sam da bi popravka tog web sajta, odnosno podešavanja, previše drugo trajala. Uostalom, isti taj projekat postoji i u source control sistemu, pa prema tome…krenuo sam ovako:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Otvorio source control, i iz Main grane otvorio ceo solution. &lt;/li&gt;    &lt;li&gt;Lokalni build, ok, sve naizgled radi na development serveru. &lt;/li&gt;    &lt;li&gt;Pogledao podešavanja za publish/deploy za web projekte &lt;/li&gt;    &lt;li&gt;Napravio &lt;a href="http://msdn.microsoft.com/en-us/library/dd410115.aspx"&gt;deployment package&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Napravio novi sajt u IIS-u, kliknuo desnim dugmetom na njega i rekao “Import application…” &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;I…novi sajt naravno radi. Jednu smicalicu kasnije, u kojoj sam prosto promenio binding-e dva sajta, svi testovi prolaze.&lt;/p&gt;  &lt;h2&gt;Koristite normalne alate&lt;/h2&gt;  &lt;p&gt;Naravno, cela pouka posta je u tome da se koriste normalni alati. Odnosno, koristite sisteme za verzioniranje koda i ako radite sa web aplikacijama, koristite web deployment alate koji su došli sa Visual Studiom 2010 pošto zaista olakšavaju život.&lt;/p&gt;  &lt;p&gt;Out.&lt;/p&gt;  &lt;p&gt;B.D.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msforge.net/aggbug.aspx?PostID=4231" width="1" height="1"&gt;</content><author><name>blackdwarf</name><uri>http://msforge.net/members/blackdwarf/default.aspx</uri></author><category term="aspnet" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/aspnet/default.aspx" /><category term="webdev" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/webdev/default.aspx" /><category term="vs2010" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/vs2010/default.aspx" /></entry><entry><title>Visual Studio 2010 Launch post-event, erratas et al.</title><link rel="alternate" type="text/html" href="/blogs/blackdwarf/archive/2010/05/01/visual-studio-2010-launch-post-event-erratas-et-al.aspx" /><id>/blogs/blackdwarf/archive/2010/05/01/visual-studio-2010-launch-post-event-erratas-et-al.aspx</id><published>2010-05-01T08:45:35Z</published><updated>2010-05-01T08:45:35Z</updated><content type="html">&lt;p&gt;Kao što svi verovatno znate, i kao što vam vaše MSDN pretplate mogu reći, Visual Studio 2010 je lansiranj 12. Aprila 2010. godine širom sveta. U Beogradu smo imali zvanični Launch događaj 27. Aprila 2010. godine, pa tim povodom želim da obavestim ljude da su prezentacije dostupne preko &lt;a href="http://www.microsoft.com/scg/vs2010/agenda.aspx"&gt;zvaničnog sajta VS2010 Launch-a&lt;/a&gt;. Ukoliko biste drugačiji pregled, iste možete da preuzmete i sa &lt;a href="http://cid-6a987abbbcbd5556.skydrive.live.com/browse.aspx/.Public/VS2010%20Launch"&gt;mog SkyDrive-a&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Slike i video fajlovi će biti dodati uskoro, dobićete obaveštenje blagovremeno.&lt;/p&gt;  &lt;h2&gt;&lt;em&gt;Errata&lt;/em&gt;&lt;/h2&gt;  &lt;p&gt;Ko radi taj i greši, a u najboljem maniru izdavaštava želeo bih da dodam nekoliko ispravki, odnosno komentara na pitanja koja sam dobio tokom svojih sesija.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;RedirectPermenant() metod koji sam pominjao da je nov u ASP.NET Web forms 4 šalje HTTP zahtev 301, “Moved”, ne 302. 302 status kod označava standardnu redirekciju, odnosno šalje se kada server “nađe” resurs. 301 klijentu kaže da se resurs permanetno pomerio sa starog URL-a, te da stoga uvek taj resurs treba da traži na novom. Wikipedia vam je &lt;a href="http://en.wikipedia.org/wiki/List_of_HTTP_status_codes"&gt;primarni resurs&lt;/a&gt; ako želite da se upoznate sa ostatkom HTTP status kodova.&lt;/li&gt;    &lt;li&gt;Web routing engine koji je deo .NET sveta još od 3.5 SP1 izdanja je sasvim sposoban, da se tako izrazim, da podnese i URL-ove koji su sa srpskim dijakriticima, odnosno u ćirilici. Ovo je imalo smisla i kada se malo bolje razmisli, jer se “šema” URL-a koji želimo da mapiramo uskladištena kao string, za kojeg znamo da je po default-u Unicode enkodovan. Naravno, ostaje da koristite i adekvatni URL, kao i da u RouteData.Values kolekciji ključ koristite u onom enkokdingu u kom ste definisali i šemu URL-a.&lt;/li&gt;    &lt;li&gt;TFS2010 “Basic” mod može da se instalira i na serveru. Ovo nisam napomenuo, odnosno nisam bio dovoljno jasan. Međutim, ideja je da ako već želite da imate dedikovan server za TFS, onda ne postoji razlog zašto ne biste instalirali i Reporting Services, odnosno SharePoint (WSS) i imali pune pogodnosti koje TFS donosi.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Out.&lt;/p&gt;  &lt;p&gt;B.D.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msforge.net/aggbug.aspx?PostID=4228" width="1" height="1"&gt;</content><author><name>blackdwarf</name><uri>http://msforge.net/members/blackdwarf/default.aspx</uri></author><category term="vs2010" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/vs2010/default.aspx" /></entry><entry><title>ASP.NET MVC2 RTM</title><link rel="alternate" type="text/html" href="/blogs/blackdwarf/archive/2010/03/12/asp-net-mvc2-rtm.aspx" /><id>/blogs/blackdwarf/archive/2010/03/12/asp-net-mvc2-rtm.aspx</id><published>2010-03-12T07:07:07Z</published><updated>2010-03-12T07:07:07Z</updated><content type="html">&lt;p&gt;Konačno…APS.NET MVC 2 je stigao do RTM faze. Više o ovome možete pročitati na &lt;a href="http://weblogs.asp.net/scottgu/archive/2010/03/11/asp-net-mvc-2-released.aspx"&gt;blogu čuvenog Gatrija, Skota&lt;/a&gt;. Slede linkovi za preuzimanje, ali samo da napomenem da su ovo dodaci za Visual Studio 2008. Konačna verzija za Visual Studio 2010 će izaći kao deo samog VS-a i neće biti potrebna nikakva dodatna instalacija. Frameworko možete preuzeti:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://go.microsoft.com/fwlink/?LinkID=185037"&gt;Korišćenjem Web Platform Installer-a&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://go.microsoft.com/fwlink/?LinkID=157074"&gt;Preko Download centra&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Moja iskrena preporuka je da koristite WebPI, pošto je zaista sjajan alat i olakšaće vam život. Pre ovoga skinite ranije verzije framework-a ako ih imate instalirane. &lt;/p&gt;  &lt;p&gt;Sledeći &lt;a href="http://codecamp.msforge.net/"&gt;Code Camp&lt;/a&gt; event u Beogradu će sigurno imati jedno predavnaje posvećeno MVC-u, i verovatno ćemo pokriti baš verziju 2, odnosno novine koje dolaze sa njom. Naravno, bićete obavešteni na vreme.&lt;/p&gt;  &lt;p&gt;Out.&lt;/p&gt;  &lt;p&gt;B.D.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msforge.net/aggbug.aspx?PostID=4187" width="1" height="1"&gt;</content><author><name>blackdwarf</name><uri>http://msforge.net/members/blackdwarf/default.aspx</uri></author><category term="aspnet" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/aspnet/default.aspx" /><category term="mvc" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/mvc/default.aspx" /><category term="vs2010" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/vs2010/default.aspx" /></entry><entry><title>VS2010 &amp; TFS2010 RC + TFS2010 Basic mode upgrade</title><link rel="alternate" type="text/html" href="/blogs/blackdwarf/archive/2010/02/11/vs2010-amp-tfs2010-rc.aspx" /><id>/blogs/blackdwarf/archive/2010/02/11/vs2010-amp-tfs2010-rc.aspx</id><published>2010-02-11T09:59:03Z</published><updated>2010-02-11T09:59:03Z</updated><content type="html">&lt;p&gt;Ako kojim slučajem ne znate, Visual Studio 2010 je doživeo još jedno izdanje pre izlaska konačne, RTM verzije. U pitanju je RC, koji je sada &lt;a title="Spisak linkova ka RC instalacijama" href="http://msdn.microsoft.com/en-us/vstudio/dd582936.aspx"&gt;dostupan svima&lt;/a&gt; (početkom nedelje je bio dostupan samo MSDN pretplatnicima). Glavni razlog izdavanja još jedne verzije posle Bete 2 su bile performanse. Naime, glavni &lt;em&gt;feedback&lt;/em&gt; šire zajednice je bio da je VS2010 Beta 2 spora, odnosno da postoje određeni problemi sa performansama. &lt;a title="Ko je &amp;quot;The Gu&amp;quot;?" href="http://weblogs.asp.net/scottgu/about.aspx"&gt;“The Gu”&lt;/a&gt; ima detaljnije objašnjenje &lt;a href="http://weblogs.asp.net/scottgu/archive/2010/02/08/vs-2010-net-4-release-candidate.aspx"&gt;na svom blogu&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Za sada sam primetio da build, rad sa većim solution-ima i pokretanje testova zaista brže rade u RC-u nego ranije u Beti 2. Rad sa Web Forms dizajnerom je takođe dosta bolji, mada aplikacija na kojoj sam probao nije preterano kompleksna. Moraću još malo da probam, pogotovo build proces na TFS-u 2010.&lt;/p&gt;  &lt;p&gt;Ako instalirate na računar koji već ima Betu, istu pre instalacije uklonite. Ono što je zabavno jeste instalacija TFS 2010 u “Basic” modu o kojem sam &lt;a href="http://msforge.net/blogs/blackdwarf/archive/2009/10/26/team-foundation-server-basic.aspx"&gt;već pričao&lt;/a&gt;, ako ste pre toga koristili Betu 2 u istom modu.&lt;/p&gt;  &lt;p&gt;Kada deinstalirate TFS preko Control Panel-a, wizard će ukloniti samo aplikativni sloj i &lt;em&gt;bits&lt;/em&gt; sa mašine. Baze koje TFS koristi će ostati srećne i vesele u SQL Server instanci u kojoj su bile. Ovo je Jako Dobra Stvar (tm). Naime, kada sam krenuo u instalaciju TFS-a 2010 RC, uradio sam deinstalaciju Bete 2. Sama instalacija je protekla glatko, zatim sam pokrenuo wizard za konfiguraciju i odabrao opciju “Upgrade”. Jedino pitanje koje sam imao jeste da odaberem bazu koju je TFS koristio za skladištenje konfiguracije. Posle nekoliko next klikova, dobio sam 100% gotovu instalaciju TFS-a u Basic modu, sa očuvanim projektima, artefaktima u sors kontroli itd. Isti ovaj proces će biti upotrebljiv i za RTM verziju, i za “veće” instalacije TFS-a i druge verzije, dakle ne samo za Basic mod i ne samo prilikom prelaska sa pre-release na RTM verziju TFS-a 2010, već i prilikom prelaska sa 2008 na 2010 verziju TFS-a, recimo.&lt;/p&gt;  &lt;p&gt;Morao sam da podelim sa širim svetom koliko sam impresioniran trudom koji je tim u Redmondu (i ostalim lokacijama u US gde se TFS pravi) uložio da (konačno) srede instalaciju, konfiguraciju i upgrade TFS-a. &lt;/p&gt;  &lt;p&gt;Out.&lt;/p&gt;  &lt;p&gt;B.D.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msforge.net/aggbug.aspx?PostID=4155" width="1" height="1"&gt;</content><author><name>blackdwarf</name><uri>http://msforge.net/members/blackdwarf/default.aspx</uri></author><category term="vs2010" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/vs2010/default.aspx" /><category term="dotnetgeneral" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/dotnetgeneral/default.aspx" /></entry><entry><title>Sanitizacija HTML koda</title><link rel="alternate" type="text/html" href="/blogs/blackdwarf/archive/2009/12/14/html-fragmenti.aspx" /><id>/blogs/blackdwarf/archive/2009/12/14/html-fragmenti.aspx</id><published>2009-12-14T14:23:05Z</published><updated>2009-12-14T14:23:05Z</updated><content type="html">&lt;p&gt;&lt;a title="Cross Site Scripting" href="http://en.wikipedia.org/wiki/Cross-site_scripting"&gt;XSS&lt;/a&gt; je jedna od najopasnijih ranjivosti web-a, kada pogledamo šta je sve moguće s njom. Iako bi neki stručnjaci (kao recimo &lt;a href="http://msforge.net/blogs/levaja/default.aspx"&gt;Blind Injection&lt;/a&gt;), sigurno daleko bolje i podrobnije objasnili o čemu se ovde radi, za potrebe ovog posta dovoljno je reći da je u pitanju iskorišćavanje jedne od osovnoh osobina browser-a, a to je da izvrši skript koji postoj ina strani. Zlonamerni korisnik ubacuje (“injektuje”) skript koji može da ima razne efekte, od krađe cookies koje korisnik ima, pa do redirekcije na neku stranu pravljenu za phishing.&lt;/p&gt;  &lt;h3&gt;OK, a kako to nastaje?&lt;/h3&gt;  &lt;p&gt;Postoje različiti načini kako da se skript “ubode” u HTML stranu, čak i ako ne koristite Rich Text editore. Problem nastaje kod ispisa onoga što je korisnik uneo, pogotovo ako to radimo bez ikakve provere. Recimo, imamo jedan textarea u koji želimo da korisnik upiše komentar koji posle prikažemo na strani. Ukoliko je ono što je korisnik napisao nešto bezazleno, to je OK, ali šta ako odluči da sadržaj textarea polja bude u stvari neki JS kod koji će uraditi nešto zlobno? Ja ga prosto ispisujem na strani, i &lt;em&gt;presto!&lt;/em&gt;, nastaje problem.&lt;/p&gt;  &lt;h3&gt;Rešenje je prosto!&lt;/h3&gt;  &lt;p&gt;Enkodujte output. Ukoliko koristite ASP.NET, možete da koristite različite biblioteke, &lt;a href="http://www.codeplex.com/AntiXSS"&gt;AntiXSS&lt;/a&gt; bilbioteka od Microsoft-a je jedna od boljih. ASP.NET MVC koristi helper metod Html.Encode() koji to isto radi. Isto tako, ASP.NET engine ima direktivu koja automatski baca exception ako se pojavi bilo kakav HTML kod u input stream-u, a koje se zove ValidateRequest.&lt;/p&gt;  &lt;p&gt;Enkodovanje prosto zameni svaki karakter HTML kodom, tako da “&amp;lt;” postaje “&amp;amp;lt;” i slično. Ovo omogućava da se HTML kod prikaže kao običan tekst u browser-u. Problem rešen.&lt;/p&gt;  &lt;h3&gt;Pa čemu onda blog post?&lt;/h3&gt;  &lt;p&gt;Jer ponekad postoji potreba, kao što je sada imam, da se korisnicima dozvoli da unose HTML kod. Pored toga, nije &lt;strong&gt;svaki&lt;/strong&gt; HTML kod opasan; ne postoji ništa opasno kod sledeće kombinacije:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;div&gt;   &lt;div style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;     &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;p&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;Ja sam &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;b&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;boldovan&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;b&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;.&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;p&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Nedavno sam naleteo na problem da mi se traži da omogućim sređivanje dužih tekstova na web-u. Ništa specijalno, samo da se omogući pravljenje paragrafa, osnovna stilizacija teksta, dodavanje linkova…dakle, ništa “fancy”. Međutim, kada sam pogledao čak i minimalne RTE-ove, svaki od njih omogućava editovanje HTML koda direktno. Još gore, kada jednom omogućim ovako nešto korisnicima, ne mogu više da se oslanjam na Html.Encode(), jer na nekim ispisima moram da ga namenski isključim. Dakle, potrebna mi je sanitizacija. &lt;/p&gt;

&lt;p&gt;Trenutno, ako pokušate da nađete rešenje za ovaj problem, verovatno ćete naići na razna rešenja koja &lt;a title="Jeff Atwood-ov primer" href="http://refactormycode.com/codes/333-sanitize-html"&gt;koriste regex-ove&lt;/a&gt;. U poslednje vreme, ovakav pristup se smatra lošim, uglavnom jer ne pokriva sve slučajeve, recimo atribute na tagovima (pored toga, setimo se šta se priča za &lt;a href="http://regex.info/blog/2006-09-15/247"&gt;programere i regex-ove&lt;/a&gt;). Drugo rešenje je da imate neke od pseudo-markup editora, odnosno dijalekata, kao što su &lt;a href="http://daringfireball.net/projects/markdown/"&gt;Markdown&lt;/a&gt; ili &lt;a href="http://www.textism.com/tools/textile/"&gt;Textile&lt;/a&gt;. Ukoliko su vam korisnici sposobni da ovo koriste, problem je rešen. Na moju štetu, ovako nešto nije bilo moguće.&lt;/p&gt;

&lt;p&gt;Posle pretrage, naleteo sam na verziju &lt;a title="Download" href="http://www.microsoft.com/downloads/details.aspx?familyid=051EE83C-5CCF-48ED-8463-02F56A6BFC09&amp;amp;displaylang=en"&gt;3.1 AntiXSS bilbioteke&lt;/a&gt;. Na moje čudo, ta verzija je dodala dva nova metoda za sanitizaciju GetSafeHtml() i GetSafeHtmlFragment(). Prvi služi za sanitizaciju celih HTML strana, dok drugi služi za sanitizaciju fragmenata. Ono što će ova dva metoda uraditi je da uklone sve “štetne” tagove, odnosno, tačnije rečeno, sve tagove koji su u whitelist-u koji bilbioteka koristi interno. Korišćenje je veoma prosto:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;
    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; HtmlFragment = &lt;span style="color:#006080;"&gt;&amp;quot;&amp;lt;b&amp;gt;Some good input.&amp;lt;/b&amp;gt;&amp;lt;script&amp;gt;document.write(&amp;#39;some bad input&amp;#39;);&amp;lt;/script&amp;gt;&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   2:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; sanitized = AntiXss.GetSafeHtmlFragment(HtmlFragment);&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Posle ovoga, sanitizied string neće više sadržavati &amp;lt;script&amp;gt; tagove. Slično tome, kao dodatak, HTML će biti &lt;em&gt;well-formed&lt;/em&gt;, u smislu da će svi nezatvoreni tagovi biti zatvoreni i slično. Nažalost, trenutno je dokumentacija pomalo škrta; kada jednom instalirate bilbioteku, imate test harness ali koji ne pokazuje sanitizaciju, kao i sample projekat k(web forms aplikaciju) koja vam daje ideju kako se AntiXSS bilbioteka i ceo security engine koji dolaze sa njom koriste. Da bih probao bilbioteku, napisao sam par (veoma) jednostavnih unit testova koji pokazuju kako se koristi bilbioteka. Projekat na &lt;a href="http://cid-6a987abbbcbd5556.skydrive.live.com/self.aspx/.Public/AntiXssTest.zip"&gt;SkyDrive-u&lt;/a&gt;, i možete ga preuzeti odatle.&lt;/p&gt;

&lt;p&gt;Tema XSS-a je svakako daleko veća od ovog blog posta, ali sam želeo da dam odgovor ljudima koji možda takođe tragaju za pametnijim i robustnijim načinom sanitizacije nesigurnog HTML koda koji dolazi od korisnika, ali bez da ukinemo kompletno mogućnost korisnicima koji nisu toliko vešti u korišćenju računara da imaju lepo formatiran tekst na sajtu.&lt;/p&gt;

&lt;p&gt;Out.&lt;/p&gt;

&lt;p&gt;B.D.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msforge.net/aggbug.aspx?PostID=4080" width="1" height="1"&gt;</content><author><name>blackdwarf</name><uri>http://msforge.net/members/blackdwarf/default.aspx</uri></author><category term="aspnet" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/aspnet/default.aspx" /><category term="mvc" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/mvc/default.aspx" /><category term="webdev" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/webdev/default.aspx" /></entry><entry><title>Web-Fu! još jednom</title><link rel="alternate" type="text/html" href="/blogs/blackdwarf/archive/2009/12/14/web-fu-jo-jednom.aspx" /><id>/blogs/blackdwarf/archive/2009/12/14/web-fu-jo-jednom.aspx</id><published>2009-12-14T14:06:28Z</published><updated>2009-12-14T14:06:28Z</updated><content type="html">&lt;p&gt;Web-Fu! je još jednu godinu sa nama! :) 2009. godina je treća godina održavanja događaja (ili, kako mi to u Microsoft-u volimo da kažemo, &lt;em&gt;event&lt;/em&gt;) koji je namenjen izlaženju iz formi standardnih Microsoft konferencija i događaja, i stavljanju fokusa isključivo na web platformu, alate, tehnike i rešenja koja se koriste ili tek dolaze iz Redmonda. Naravno, akcenat nije samo na prezentovanju novih proizvoda, već i praksi za razne probleme sa kojima se web developeri (i developeri koji se bave, u ma kolikom procentu, web-om) susreću svaki dan.&lt;/p&gt;  &lt;p&gt;Ove godine smo se potrudili da agenda bude raznovrsna i da poseduje malo noviteta, malo praksi, malo naprednijih tema, a malo i stvari kojih možda niste bili svesni ni da postoje. &lt;a href="http://www.jankoatwarpspeed.com/"&gt;Janko&lt;/a&gt; će, recimo, podeliti najbolje prakse u pravljenju web formi. Danijel će preći nove osobine Siliverght-a 4, čija je beta izašla prošlog meseca tokom PDC-a. &lt;a href="http://msforge.net/blogs/zmajcek"&gt;Srđan&lt;/a&gt; i Nenad će zaroniti malo “ispod haube” dok predstavljaju REST tehnike i alate, kao i “Velocity”, respektivno. Sergej će prikazati većinu &lt;a href="http://en.wikipedia.org/wiki/Ajax_(programming)"&gt;AJAX&lt;/a&gt; tehnika koje su dostupne tokom izrade ASP.NET aplikacija na primerima iz prakse. Konačno, moja malenkost će prikazati šaroliku lepezu “sitnih” alata za koje možda i niste znali da postoje, a mogu vam pomoći kada pravite web aplikacije.&lt;/p&gt;  &lt;p&gt;Registracija, kao i sve ostale informacije, se nalaze na &lt;a href="http://www.webfu.rs/"&gt;http://www.webfu.rs/&lt;/a&gt;. Naravno, događaj je, kao i prethodnih godina, besplatan, a dešava se 23.12. ove nam tekuće godine u Ateljeu 212 (centar Beograda, Svetogorska ulica).&lt;/p&gt;  &lt;p&gt;Vidimo se tamo!&lt;/p&gt;  &lt;p&gt;Out.&lt;/p&gt;  &lt;p&gt;B.D.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msforge.net/aggbug.aspx?PostID=4079" width="1" height="1"&gt;</content><author><name>blackdwarf</name><uri>http://msforge.net/members/blackdwarf/default.aspx</uri></author><category term="webdev" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/webdev/default.aspx" /><category term="webfu" scheme="http://msforge.net/blogs/blackdwarf/archive/tags/webfu/default.aspx" /></entry></feed>
