György's profileBalássy GyörgyPhotosBlogListsMore ![]() | Help |
Balássy GyörgyHarctéri tapasztalatok |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||
Technológiák elsajátítását segítő induló készletek az MSDN Kompetencia Központ honlapján.
|
July 03 Érték szerinti csoportosítás ListView vezérlővelGyakran van szükség arra, hogy a ListView vezérlőben megjelenő rekordokat valamilyen szempont szerint csoportosítsuk. A ListView támogat is csoportosítást, azonban ez a funkció csak arra jó (?), hogy megadott számú elemet tegyünk egy csoportba, azt sajnos nem támogatja, hogy megadott érték szerint csoportosítsuk a rekordokat. Persze hagyományos módon meg lehet oldani ezt is. Ezt tudja a ListView csoportosítás címén: a LayoutTemplate-et GroupTemplate-ekkel tölti fel, közéjük pedig GroupSeparatorTemplate-et rak. Minden egyes GroupTemplate-be a GroupItemCount tulajdonságban megadott számú ItemTemplate kerül. Ha egy csoportban (tipikusan az utolsóban) nincs elég elem, akkor azokat a helyeket EmptyItemTemplate-tel tölti fel. Ez szerintem arra van kitalálva, hogy az ember táblázatba rendezze a rekordokat, ott számít ugyanis, hogy minden sorba ugyanannyi elem kerüljön. De mi van akkor, ha nem darabszám, hanem érték szerint akarjuk csoportosítani a sorokat? Ez esetben kénytelenek leszünk lemondani a beépített csoportosításról és az ASP.NET 1.0-ban megszokott módon megoldani a feladatot. Először is rendezzük a csoportképző mező szerint az adatokat, például ha a Northwind adatbázis Customer táblájának sorait ország szerint csoportosítva, azon belül pedig cégnév szerint rendezve akarjuk megjeleníteni, akkor így: SELECT CompanyName, ContactName, Country FROM Customers ORDER BY Country, CompanyName Az eredmény (részlete): Már csak annyi dolgunk maradt, hogy a Country mezőváltozásai esetén kell megjelenítenünk egy csoportfejlécet. A trükk az, hogy nem használjuk a beépített csoportosítást, hanem (például) egy sima h2 elemre rácuppanunk szerver oldalon (runat=server), majd a Visible tulajdonságát egy szerver oldali metódussal állítjuk be: <asp:ListView runat="server" DataSourceID="sdsCustomers"> <LayoutTemplate> <asp:PlaceHolder ID="itemPlaceholder" runat="server" /> </LayoutTemplate> <ItemTemplate> <h2 runat="server" visible='<%# IsGroupHeaderVisible( Eval( "Country" ) ) %>'> <%# Eval( "Country" ) %> </h2> <%# Eval( "CompanyName" ) %> - <%# Eval( "ContactName" ) %> </ItemTemplate> <ItemSeparatorTemplate> <br /> </ItemSeparatorTemplate> </asp:ListView> Ezek után a code behindban kell egy privát mező az előző érték tárolására és a függvény, ami az aktuális értéket összehasonlítja az előzővel: private string _lastValue; protected bool IsGroupHeaderVisible( object value ) { string currentValue = value.ToString(); if( currentValue.Equals( this._lastValue, StringComparison.OrdinalIgnoreCase ) ) { return false; } else { this._lastValue = currentValue; return true; } } Az eredmény pedig: Látható, hogy az egész azon alapul, hogy a rekordok jó sorrendben legyenek, de egyébként teljesen a mi kezünkben van az irányítás, olyan szempont szerint csoportosítunk, ahogy kedvünk tartja. A cikkhez tartozó forráskód letölthető itt. Inline UpdateProgressNem mondhatom magamról, hogy dizájner vér folyik az ereimben, mégis többen egyetértettek már azon ötletemmel, hogy az AJAXos háttérműveletet jelző pörgő gif az aszinkron postbacket kiváltó vezérlő, tipikusan Button mellett legyen. Az ASP.NET AJAX fejlesztői szerint azonban senki ne akarjon UpdateProgresst inline használni. Ha megnézzük Reflectorban az UpdateProgress forráskódját azonnal látszik, hogy valamelyik idióta elég biztosra ment ezzel kapcsolatban:
Ott virít középen a display:block CSS beállítás. Aki érti, hogy ez miért kell ide, kérem írja meg, úgy szeretném megérteni... Ha már így belekukkantottunk, az is látszik, hogy az UpdateProgress mindig pontosan egy div elemet renderel magából, amire azonban nem tudunk kívülről CSS osztályt ültetni. Csakhogy semmi akadálya, hogy az egészet becsomagoljuk egy külső divbe: <div class="progress"> <asp:UpdateProgress runat="server" AssociatedUpdatePanelID="up" Majd a külső divre megadott CSS classra állítsunk be olyan stílust, ami igazából az UpdateProgress által generált divre fog alkalmazódni: div.progress { display: inline; } div.progress div { display: inline !important; } Íme az eredmény:
June 16 A ListView kétszer mondja. A ListView kétszer mondja.Az ASP.NET ListView vezérlő sajnos a csillagok bizonyos együttállása esetén kétszer fordul az adatbázishoz. Látszólag nincs semmi extra a dologban, mégis SQL Profilerrel megnézve tisztán látszik, hogy a kapcsolt SqlDataSource SelectCommand utasítása kétszer fut be az adatbázis szerverbe. Szerencsére ez nem mindig fordul elő, akkor azonban biztosan, ha a ListViewt beágyazzuk egy Web User Controlba (ascx), majd az beletesszük egy adatkötött vezérlőbe, például egy FormView-ba. Tehát a szerencsétlen csillagállás:
A problémát az okozza, hogy a ListView inicializálásakor is történik egy adatkötés és a FormView is meghívja rajta a DataBind metódust. Sajnos nem ez az egyetlen adatkötési gond a ListView-val, kész csoda, hogy nem száll el StackOverflowExceptionnel. MegoldásAki teljesen biztos magában, megoldhatja a fenti problémát azzal, hogy a FormViewtól érkező DataBindot nem engedi lefolyni a ListViewra, lehet például ezt írni a Web User Controlba: public override void DataBind() { // Kikommentezve: base.DataBind(); } Aki kevésbé merész, vagy szüksége van az ASCX DataBind metódusára, az keresztbetehet az Initben lezajló adatkötésnek azzal, hogy csak később, a Page_Loadban állítja be a ListView adatforrását, például így: protected void Page_Load( object sender, EventArgs e ) { this.ListView1.DataSource = this.SqlDataSource1; } Egyelőre úgy tűnik, hogy a probléma csak a ListView vezérlőt érinti, a Repeaterrel nincs gond. A hibás működést és a javítást tartalmazó példa kód letölthető innen. June 01 Bing Is Not Google*Elindult a Microsoft új keresője, ami most már szerencsére nem Live akármi, hanem egyszerűen csak Bing névre hallgat. Fogadni mernék, hogy ezt a szót hamarosan igeként is fogjuk használni és már nem csak olyan kifejezések hangzanak majd el, mint “meggugliztam”, hanem lesz “megbingeltem” is. A cég nagyon nagyra van vele, még nem jöttem rá, hogy nekem mi hasznom származik belőle. Azt sikerült kideríteni, hogy ha a jobb felső sarokban Hungary van országként kiválasztva, akkor gyakorlatilag a Live Searchöt kapom egy új URL-en, ezért célszerű átállítani mondjuk United Statesre, akkor megjelenik néhány extra funkció:
Nektek mi a véleményetek, tetszik, érdemes használni? ---------- *: Forrás: Christian Weyer May 19 Informatika Tisztán – Megoldásbörze letöltésekLetölthetőek az Informatika Tisztán sorozat múlt heti Megoldásbörzéjén tartott előadásaim prezentációi és videói. Adatokat az intranetre
Gyakran merül fel az igény, hogy egy vállalaton belül összegyűjtött adatbázist, például a partnereink elérhetőségeit szeretnénk a munkatársak között megosztani, webes felületen megjeleníteni, rendezhetővé és kereshetővé tenni. Az előadásban a Windows SharePoint Services webkijelző infrastruktúrájára épülve, SharePoint Designer segítségével, fejlesztés nélkül tesszük közzé a relációs adatbázisban tárolt adatainkat az intraneten.
Teljes változat: Adatokat_az_intranetre.wmv (37:34, 206 722 kB) Rövid összefoglaló: Adatokat_az_intranetre_rovid.wmv (3:46, 20 538 kB) Dokumentumok standardizálása
A vállalati előírásoknak, formuláknak megfelelő dokumentumok manuális előállítása nehézkes és időigényes feladat, különösen akkor, ha a szükséges adatokat nekünk kell más dokumentumokból összevadásznunk. Az előadásban bemutatjuk, hogyan használhatjuk ki a Windows SharePoint Services dokumentumtárait és a SharePoint Designer grafikus lehetőségeit árajánlatokat, szerződéseket és teljesítésigazolásokat létrehozó munkafolyamatok készítésére.
Teljes változat: Dokumentumok_standardizalasa.wmv (46:58, 259 015 kB) Rövid összefoglaló: Dokumentumok_standardizalasa_rovid.wmv (7:54, 42 180 kB) Aki ott volt a Sugárban, vagy esetleg letöltötte és megnézte ezeket a felvételeket, kérem írjon valami visszajelzést, hasznos, megérte? May 18 SSL használata IIS 7 alattAlapértelmezés szerint a kliens és a webszerver közötti kommunikáció titkosítatlanul történik, amely lehetővé teszi az átküldött adatok lehallgatását. Ez különösen akkor kellemetlen, ha a böngésző és a webkiszolgáló között érzékeny adatok utaznak, például egy kitöltött űrlap adatai, felhasználónevek és jelszavak vagy éppen egy hitelesítéshez használt cookie, ugyanis egy támadó eltulajdoníthatja vagy felhasználhatja ezeket az információkat a kliens megszemélyesítésére vagy egy visszajátszásos támadásra. A megoldás a kommunikációs csatorna titkosítása, amely a Secure Sockets Layer (SSL) protokoll segítségével történhet.
Miután megvan a tanúsítvány, még engedélyeznünk kell, hogy egy adott webhely a HTTPS protokollhoz rendelt 443 porton is elérhető legyen, ez az ún. binding. DemóA demóban előbb bemutatjuk, hogyan hozhatunk létre önaláírt tanúsítvány az IIS Manager segítségével, majd hozzárendeljük azt egy webhelyhez, végül pedig kikényszerítjük, hogy a kliens SSL csatornán keresztül kapcsolódjon a webhelyhez. A videó a képre kattintva megtekinthető böngészőben vagy a kép alatti linkre kattintva letölthető: Letöltés: SSL.wmv (12:16, 50.8 MB) Első lépésekElső lépésként szerezzünk be egy hiteles tanúsítványt, vagy ha csak kísérletezünk, akkor használjuk az IIS Manager Server Certificates moduljában a Create Self-Signed Certificate gombot egy önaláírt tanúsítvány előállítására. Ezek után nyissuk meg egy webhelyen a Bindings… ablakot és rendeljük hozzá a webhelyhez a https protokollt és a 443 portot a korábban létrehozott tanúsítvánnyal. Jó tudniAz IIS Managerben lévő Create Self-Signed Certificate varázsló nem kérdezi meg, hogy milyen név szerepeljen a tanúsítványon. Ha tehát a webkiszolgálónk több néven is elérhető, nem fogjuk tudni megadni, hogy melyik névre szóljon a tanúsítvány. Ha a tanúsítvány létrehozásakor meg szeretnénk adni a tanúsítvány paramétereit, akkor célszerű az IIS Manager beépített szolgáltatása helyett az IIS 6 Resource Kitben lévő SelfSSL programot használni. Ez viszont csak akkor fog működni IIS 7 alatt, ha feltelepítjük az IIS 6 Management Compatibility komponenst is. További információkMay 13 Rendezvény meghívó: Legyen saját iwiwed!Az MSDN Kompetencia Központ és a Microsoft Magyarország szervezésében 2009. május 25-én ismét lesz ingyenes ASP.NET tanfolyam, melyen a résztvevők az alapoktól kezdve testközelből ismerhetik meg az ASP.NET technológiát! Az egy napos rendezvény keretén belül minden laptoppal érkező számára virtuális környezetet biztosítunk, és együtt építünk meg egy kapcsolati hálón alapuló közösségi webalkalmazást. A részletes program (és remélhetőleg hamarosan a regisztrációs link is) megtalálható a devPORTALon. May 08 Cannon, p.i.Új sorozat indul: Aki még nem hallott a Microsoft Web Platform Installerről (Web PI) (az új már a korábbi Web Application Installert is tartalmazza), annak ajánlom figyelmébe Dávid Zoli videóit az MSDN Kompetencia Központ Videótárában. May 07 Steve Riley: Good bye, and good luckEzt most olvastam Steve Riley blogjában és nem kicsit sokkolt:
Aki hallotta már Steve valamelyik előadását a TechNet Spotlighton vagy éppen személyesen a TechEden biztosan egyetért velem abban, hogy ez a fickó tud valamit. Nem csak a biztonságról, hanem arról is, hogy hogyan kell róla beszélni, hogyan kell a témát előadni. Korábban már sikerült a hasonló kaliberű Jesper Johanssontól is megválni, aki azért szerencsére konferencia közelben maradt, legalábbis a tavalyi barcelonai TechEden még ott volt. Nem értem a stratégiát. Ezeket az embereket azért fizette a Microsoft, hogy felhívják a figyelmet az informatikai biztonságra és a Trustworthy Computing zászlója alatt kiemeljék az átlag informatikust a sötét középkorból. Most kész lennénk, a mór megtette kötelességét, a mór mehet? Mindenki naprakész lett a biztonsággal kapcsolatos témákból, sőt továbbra is mindenki önerőből naprakészen fogja magát tartani? Ha ez így folytatódik, szerintem szép lassan vissza fogunk süllyedni. Mit gondoltok, ez így nooooooormális? May 05 Active Directory lekérdezése T-SQL-bőlAki valaha is foglalkozott már az Active Directory-val az tudja, hogy a címtár felépítése gyökeresen eltér egy relációs adatbázis szerkezetétől. Nem elég, hogy az egyes elemek konténerekben helyezkednek el, melyek hierarchikus kapcsolatban állnak egymással, de egy konténeren belül teljesen különböző tulajdonságokkal bíró címtár objektumok is lehetnek. És mégis, van lehetőség arra, hogy az SQL Servernek megtanítsuk, hogyan kell lekérdezni a címtárat. Perverzek előnyben :) A megoldás kulcsa, hogy az SQL Server képes ún. linked servereket kezelni, ami gyakorlatilag bármilyen OLE DB adatforrás lehet. Íme egy ábra a Books Online-ból, akit a szöveg is érdekel, itt olvasson tovább:
T-SQL-ben mindez így történik: EXEC sp_addlinkedserver @server = N'ADSI', @srvproduct = N'Active Directory Service Interfaces', @provider = N'ADSDSOObject', @datasrc = N'adsdatasource' GO Az sp_addlinkedserver dokumentációjában egy rakás adatforrásról találunk leírást, de az ADsDSOObject valahogy kimaradt. Ennek valószínűleg az az oka, hogy nincs sok köze az SQL Serverhez, az ADsDSOObject ugyanis Windows 2000-től kezdve az Active Directory Service Interfaces (ADSI) OLE DB Provider, amit már az ADO is ismert sok más providerrel együtt. Persze kell egy felhasználó, akinek a nevében az SQL Server olvashatja a címtárat: EXEC sp_addlinkedsrvlogin @rmtsrvname = N'ADSI', @useself = N'False', @rmtuser = N'TARTOMANY\felhasznalo', @rmtpassword = N'T1tk0sJel520!' GO Persze aki inkább kattintgatni szeret, ugyanezeket beállíthatja SQL Server Management Studioban is: a Server Object ág alatt található Linked Servers ágnál érdemes körülnézni:
Az így létrehozott linked serveren az OPENQUERY utasítással futtathatunk lekérdezéseket. Hogy ezzel ne kelljen mindig küzdeni, én inkább létrehoztam egy nézetet (ahogy Eriktől megtanultam, a tempdb kiváló játszótér erre a célra): CREATE VIEW [dbo].[vw_MyGroup] AS SELECT sAMAccountName AS [Login Name], givenName AS [First Name], sn AS [Last Name], displayName AS [Full Name], mail AS [E-Mail Address], telephoneNumber AS [Phone] FROM OPENQUERY( ADSI, 'SELECT sAMAccountName, givenName, sn, displayName, mail, telephoneNumber FROM ''LDAP://demodc.demodom.local'' WHERE objectClass = ''user'' AND memberOf = ''CN=MyGroup,CN=Users,dc=demodom,dc=local'' ' ) AS t GO A memberOf attribútum lekérdezésével azt sikerült megadni, hogy csak azokat a felhasználókat kapjuk meg, akik tagjai a MyGroup nevű csoportnak. Persze ezeknek a kacifántos LDAP útvonalaknak a megírása okozhat még némi nehézséget, de abban az ADSI Edit nevű eszköz sokat segíthet. Ugyanezzel az eszközzel az objektumok attribútumai között is mazsolázhatunk. Lehet ám még fokozni a képet, például SharePoint bevonásával. Hogy pontosan hogyan és miért, azt a jövő keddi Megoldásbörzén megmutatom. April 30 SQL Express: Failed to generate a user instanceA minap sikerült belefutni ebbe a barátságos hibaüzenetbe Visual Studioban, miközben Local Database File elemet akartam egy SQL Expresst használó Web Site-hoz hozzáadni:
A megoldás az alábbi mappa törlése (a kevésbé kalandvágyók persze menthetnek is előtte):
Ha az SQL Expresst UserInstance=true módban futtatjuk, akkor minden egyes felhasználó esetén az első használatkor ebbe a mappába lemásolódnak a szükséges rendszer adatbázisok, miközben a fehér ember a homokórát bámulja. Mivel UserInstace módban az alkalmazás általában csak a saját adatbázisát piszkálja és nem vesz fel más adatbázisokat vagy loginokat a masterbe, ezért nem gond, ha mindentől megszabadulunk. Technorati-címkék: SQL Server,SQL Server Express Edition,UserInstance,Local Database File,Visual Studio April 18 Mailto mindenestülSokadszorra is levonom a következtetést, hogy nem szabad a felhasználókat arra kérni, hogy e-mailben küldjék el a kért adatokat, mert a fele lemarad és úgy járunk, mint az egyszeri piarista, aki szerint a négy evangélista a következő három: Dávid és Góliát. Ha már nem tudunk a felhasználóknak webes űrlapot adni, akkor legalább adjunk egy félig megírt e-mailt, amit csak ki kell tölteniük, például ilyet:
Ehhez mindössze egy mailto: linkre van szükség, kellően felparaméterezve, mert hogy azt is lehet. A fenti levél akkor jött létre, mikor egy oldalon az alábbi linkre kattintottam (sortörések nélkül): <a href="mailto:gina@example.com; zoli@example.com Amit érdemes észrevenni:
Persze az e-mail címet illene úgy beletenni az űrlapba, hogy lehetőleg kevés spam érkezzen rá, ezzel kapcsolatban ajánlom figyelmetekbe a reCAPTCHA Mailhide szolgáltatását. Hitelesítés és hozzáférés szabályozás az IIS 7-benAz Internet Information Services 7 számos újdonságot hordoz a hitelesítés (authentication) és a hozzáférés szabályozás (authorization) területén, melyek nagyban megkönnyítik a webkiszolgálót üzemeltető rendszergazdák életét.
A hozzáférés szabályozásban újdonság az ASP.NET ihlette URL Authorization, amely lehetővé teszi, hogy a fájlrendszerben található erőforrásoktól függetlenül, URL-ekre adjunk meg hozzáférési szabályokat. A definiált szabályok web.config állományokban tárolódnak, így nincs többé szükség a fájlokon és mappákon megadott hozzáférés-szabályozási listák (ACL-ek) nehézkes mozgatására. Az új URL Authorization modul segítségével ráadásul nem csak Windows felhasználói fiókokra adhatunk meg szabályokat, hanem – mivel a modul képes együttműködni az ASP.NET Membership és Role Providerekkel – akár Forms Authentication eredményeként előállt felhasználói fiókokra és csoportokra is. DemóA demóban bemutatásra kerül az új URL Authorization modul és a hozzáférés szabályozása az új IIS APPPOOL névtér segítségével. A videó a képre kattintva megtekinthető böngészőben vagy a kép alatti linkre kattintva letölthető: Letöltés: Hozzaferes_szabalyozas.wmv (15:29, 70.0 MB) Első lépésekA hitelesítés működéséhez telepítenünk kell legalább egy modult az alábbiak közül: Basic Authentication, Client Certificate Mapping Authentication, Digest Authentication, IIS Client Certificate Mapping Authentication, Windows Authentication vagy az ASP.NET támogatást. Az URL Authorization szintén külön modulként telepítendő. Jó tudniAz ASP.NET-es és az IIS 7-es URL Authorization között sok különbség van:
További információkApril 15 WorkItemTypeDeniedOrNotExistExceptionEbbe a szép hibaüzenetbe tegnap futottunk bele, miközben Visual Studioban egy TFS work itemet akartunk megtekinteni:
A probléma akkor jön elő, ha sikerül a Team Explorert a Visual Studio SP1 után telepíteni. A VS SP1 frissíti a Team Explorert is, azonban ha a Team Explorert telepítjük az SP1 után, akkor abból csak RTM verziónk lesz, ami a jelek szerint nem fér meg a VS SP1 részeivel. A helyes sorrend tehát:
A megoldás az SP1 ismételt telepítése, mivel sajnos Repair install funkciót nem kínál fel (talán parancssorból lehet?). April 04 Linkblog: ASP.NET Menu IE8 alattHa a standard ASP.NET Menu vezérlőnek használjuk a dinamikusan kinyíló funkcióit, akkor készüljünk fel rá, hogy a menünk Internet Explorer 8 alatt nem fog helyesen megjelenni. A problémát a vezérlő által generált kódban léző z-index okozza, és az IE8 megjelenítése valójában helyes, mert ez a standard. Giorgio Sardo blogjában van rá megoldás, illetve létezik már Microsoft hotfix (KB962351) is. Google Maps integrálása ASP.NET-telMeglepően egyszerű a Google térkép szolgáltatásának integrálása egy weboldalba, mindössze egy iframe elemre van szükségünk, aminek code behindból ügyesen beállítjuk az src attribútumát. Nem is értem, miért nem használják ezt több helyen. Történetesen az a feladatom, hogy egy GridView-ban lévő Contact rekordok Address mezőjében lévő címet a grid alatt egy térképen jelenítsem meg. A kérképet egy iframefogja tartalmazni, amihez odacsaptam a runat=”server” attribútumot, hogy kódból el tudjam érni: <iframe runat="server" id="ifMap" width="500" height="300"></iframe> Ezt a trükköt egyébként bármelyik HTML elemmel el lehet játszani, szerver oldalon HtmlGenericControl lesz belőle. Ezért a GridView kapott egy gombot, ami ráadásul a CommandArgument segítségével viszi magával a címet is az eseménykezelőbe: <asp:Button runat="server" A gomb kattintást a RowCommand eseménykor lehet kezelni: if( e.CommandName == "ShowMap" ) { this.ifMap.Attributes[ "src" ] = String.Format( CultureInfo.InvariantCulture, @"http://maps.google.com/maps?q={0}&output=embed", e.CommandArgument ); } A dolognak tehát az az érdekessége, hogy egy sima URL-be be tudok fűzni egy teljes címet, például “Budapest, Magyar Tudósok krt. 2.” és Google Maps rátalál a helyre. Sőt, rátalál olyan földrajzi nevekre is, amiket magyarul és angolul máshogy hívunk: Magyarország, Brazília, Peking. Persze a térkép adatbázisa nem tökéletes, rólunk például azt hiszi, hogy itt tanyázunk, pedig valójában ebben az épületben lehet minket megtalálni (a Live Space nem engedi, hogy iframe-et szúrjak be ide :( ). April 01 SQL Server programozása PL/SQL-ben[2009.04.01.] Miután mindenki számára nyilvánvalóvá vált, hogy az Oracle Server egyáltalán nem “unbreakable”, egyre több cég keresett meg minket azzal a feladattal, hogy az alkalmazás mögött futó Oracle Servert cseréljük le Microsoft SQL Serverre, természetesen a forráskód módosítása nélkül. A két rendszer és a két nyelv között azonban számos különbség van, amit csak azzal tudtunk kiküszöbölni, hogy SQL Servernek közvetlenül megtanítottuk a PL/SQL-t. Az Oracle által támogatott PL/SQL nyelvben számos olyan nyelvi elem található, amely már létezik az SQL Serverben, csak éppen más a szintaktikája. Ilyen például a DECODE() függvény, ami helyett T-SQL-ben CASE van, szekvenciák helyett pedig IDENTITY. Ezen kívül van sok olyan eset, ahol az adott funkció egyáltalán nem létezik T-SQL-ben, például SQL Serveren nincsenek egymásba ágyazott táblák és hiányzik az Oracle DUAL dummy táblájának megfelelője is. Nincs FOR ciklus és a triggerek is csak utasítás szintűek, míg Oracle Serveren akár sor szintűek is lehetnek. Vannak továbbá jogosultsági problémák, hiszen az SQL Server nem támogatja a sor szintű jogosultság szabályozást, az Oracle szerver viszont igen. A probléma megoldására az MSDN Kompetencia Központon belül működő Adatbázisok és Tudásfeltárás Csoport Dr. Iváncsy Renáta vezetésével 2008. júniusában kutatási projektet indított, amelyre nagyon hamar felfigyeltek az ipari partnereink. Ennek köszönhetően a kialakult megoldást éles körülmények között fejleszthettük ki és mára már számos cégnél és intézménynél alkalmazzák. A megoldás technikai lehetőségét az adta, hogy a Microsoft SQL Server lekérdezés feldolgozója bővíthető egy IQueryExtension interfész implementálásával. Ezt úgy kell elképzelni, mint a LINQ-es bővítő metódusokat: ha valahol olyan nyelvi elemet talál a parser, amit nem ismer, megnézi, hogy a bővítmények között van-e olyan komponens, amely megbírkózik vele. Egyszerűnek hangzik? A gyakorlatban nem az, ugyanis vannak olyan utasítások, például a SELECT, amely máshogy paraméterezhető a két nyelvben, így nem volt más választásunk, mint az SQL Server egész lekérdezés feldolgozóját kicserélni egy saját implementációra. Számos debuggolási kör és éles üzemben szerzett tapasztalat (egyeseknek a február 7-i Ügyfélkapu eset jut ilyenkor eszébe) után büszkén jelenthetjük ki, hogy nem csak, hogy implementáltuk a PL/SQL nyelvet a Microsoft SQL Serverben, de az alábbi grafikonról egyérteműen leolvasható, hogy az így nyert rendszer lekérdezés futtatási teljesítménye veri az alap implementáció teljesítményét.
Szintén a projekt létjogosultságát igazolja, hogy sok olyan fejlesztővel találkozunk a munkánk során, akik már régóta SQL Serveren szeretnének fejleszteni – hiszen bizonyítottan jobb, mint az Oracle – viszont nincs lehetősége más nyelvet megtanulni, így kvázi röghöz kötötte az Oracle a PL/SQL nyelv által. A Microsoft MVP és Regional Director csatornákon keresztül sikerült felhívni a redmondi fejlesztőcsapat figyelmét az eredményeinkre, akik nagyon pozitívan álltak hozzá a munkánkhoz. Január vége óta a csapatunk magja Redmondban az SQL teammel szorosan együttműködve azon fáradozik, hogy az SQL Server 2008 következő javítócsomagja már tartalmazza ezt a funkciót, így a Microsoft adatbáziskezelője lesz az első olyan rendszer, amely egyszerre támogatja a T-SQL és a PL/SQL nyelvet is. A fenti grafikonon látható teljesítmény és funkció különbségre felfigyelt a LINQ csapat is, ezért várhatóan a .NET Framework 4.0-ban a LINQ to SQL natívan PL/SQL kódot fog generálni. (Ezzel egyébként megoldottuk a LINQ csapat egyik régi problémáját, a PL/SQL-ben lévő %TYPE ugyanis lehetővé teszi a .NET-es anonymous típusok leképezését adatbázis kódra.) Mivel ez kiemelt fontosságú, ezért elképzelhető, hogy a .NET Framework 4.0 kicsit csúszni fog, cserébe lényegesen nagyobb funkcionalitást fogunk kapni. Az még nem dőlt el, hogy a LINQre épülő egyéb komponensek, például az ADO.NET Data Services már a 4.0 vagy csak egy későbbi Framework verzióban állnak át az új implementációra és használják ki annak lehetőségeit, az viszont már biztos, hogy SQL Server Data Services támogatni fogja a PL/SQL nyelvet is. Akiket érdekel mindez a gyakorlatban, azok számára letölthető egy minta alkalmazás, amely tetszőleges PL/SQL kódot képes SQL Serveren futtatni. Akit pedig az implementációs részletek hoznak lázba, az alábbi linkről a teljes forráskódot és a kutatás teljes dokumentációját is letöltheti: March 27 Az IIS 7 beállításainak mentése és visszatöltéseAz IIS 7 egyik legfontosabb architekturális újdonsága, hogy a webkiszolgáló beállításai XML formátumú .config kiterjesztésű állományokban tárolódnak a C:\Windows\System32\inetsrv\config mappában. Ezeknek a mentését legegyszerűbb módon parancssorból végezhetjük el, felhasználva az appcmd segédprogramot, melynek eredménye a C:\Windows\System32\inetsrv\backup mappába kerül. A mentés elkészítésére az appcmd add backup <backupnév> parancs, a visszatöltéshez pedig az appcmd restore backup <backupnév> parancs használható. Az IIS 6-hoz hasonlóan az IIS 7 is készít automatikus mentést a beállításokat tartalmazó állományokról, ha azok változnak. Ez az ún. Config History szolgáltatás, melyért az Application Host Helper Service felelős. Ez a szolgáltatás alapértelmezés szerint kettő percenként ellenőrzi, hogy változott-e az applicationHost.config vagy az administration.config állomány és ha igen, akkor másolatot készít róluk a C:\inetpub\history mappába. A szolgáltatás konfigurálása az applicationHost.config fájlban a configHistory szekció módosításával lehetséges. DemóA demóban bemutatjuk a mentés és a visszatöltés lépéseit parancssorból és egy szabadon letölthető kiegészítés használatával, majd rátérünk a Config History szolgáltatás használatára és az alapbeállítások módosítására. A videó a képre kattintva megtekinthető böngészőben vagy a kép alatti linkre kattintva letölthető: Letöltés: Mentes.wmv (18:24, 92.1 MB) Első lépésekElső lépésként nézzük meg, hogy milyen mentések készültek korábban a rendszerről. Erre használhatjuk az appcmd list backups parancsot. Jó tudniMind a Config History, mind pedig az appcmd csak a kiszolgáló szintű beállításokat menti. Az alkalmazás szintű beállítások az alkalmazások mappáiban található web.config fájlokba kerülnek, ezek mentéséről egyéb módon kell gondoskodni. További információkMarch 20 Az IE 6-nak mennie kellBiztos sokakhoz már eljutott a hír, megjelent az Internet Explorer 8, ingyenesen letölthető, telepíthető, telepítendő! Én a béta 1 változattól kezdve használom és bevallom semmi problémám nem volt vele. Ha egy webhely nem támogatta, a Compatibility View segítségével akkor is tökéletesen lehetett használni az oldalt. Merem ajánlani. A korábbi verzióknak, különösen az IE 6-nak immár mennie kell! Az IE 6-tal sok gond van, nem véletlenül szeretne tőle minden webfejlesztő megszabadulni. Az elmúlt hónapokban kampány indult az IE 6 kipusztítására: Mivel nem csak webfejlesztőként, hanem felhasználóként a személyi adatokat és a biztonságot szem előtt tartva sem szerencsés az IE 6 használata, ezért mától mi is felhívjük erre az ilyen böngészővel honlapunkra látogatók figyelmét:
Persze felmerül a kérdés, hogy ez hány látogatót fog érinteni? Bár az IE 6 2001. augusztus 27-én, több mint 7 éve jelent meg, még mindig meglepően sokan használják. Íme néhány általunk mért webhely statisztikája, az IE 6 arány ijesztően nagy egy ennyire elavult, ráadásul ingyenesen frissíthető termékhez képest:
Tisztában vagyok vele, hogy néhányan kényszerből (vagy mert ez a policy vagy mert valamilyen alkalmazás csak ezzel megy), de meggyőződésem, hogy nagyon sokaknál csak az akaráson múlik, hogy verziót váltanak-e.
March 17 Az IIS 7 konfigurációs fájljaiAz Internet Information Services 6-hoz képest az IIS 7 konfigurációs rendszere teljesen megváltozott, a metabase-t a .NET platformon már megszokott XML formátumú konfigurációs fájlok váltották fel. Az IIS 7 szorosan összefonódik a .NET platformmal, a webszerver beállításai a .NET-es alkalmazások beállításaival azonos helyen tárolódnak.
A fentieken kívül az IIS 7-hez még két konfigurációs fájl tartozik, amelyek azonban nem vesznek részt a hierarchiában. A redirection.config fájlt a rendszer akkor használja, ha bekonfiguráltuk az ún. Shared Configuration szolgáltatást; ebben az esetben ez a fájl határozza meg, hogy milyen megosztott mappában találhatóak a konfigurációs állományok. A másik önálló fájl az administration.config, amely kizárólag az IIS Manager által használt és a grafikus üzemeltetői felület által használt modulok beállításait tartalmazza. DemóA demóban bemutatjuk az IIS 7 konfigurációs fájljainak felépítését, és a Feature delegation valamint a Shared configuration szolgáltatásokat. A videó a képre kattintva megtekinthető böngészőben vagy a kép alatti linkre kattintva letölthető: Letöltés: Konfiguracio.wmv (14:55, 58.6 MB) Első lépésekBár a legfontosabb beállítások módosítása elvégezhető az IIS Manager felhasználói felületéről, létezhetnek olyan modulok, amelyekhez nem tartozik felhasználói felület. Ezért érdemes megismerkedni a konfigurációs fájlok belső felépítésével, illetve megtekinteni azokat a C:\Windows\System32\inetsrv\config mappában. Mivel az IIS 7 a .NET-es konfigurációs fájlok struktúráját és logikáját követi, ezért célszerű megismerkedni a .NET-es .config fájlok használatával is. Jó tudniAz IIS Managerben van lehetőség az egyes szekciók felülírhatóságát szabályozni a Feature delegation modul segítségével. Ez a funkció azonban csak egész konfigurációs szekciókra használható. Ha ennél finomabban, például XML elem vagy attribútum szinten szeretnénk meghatározni, hogy az alsóbb szinteken felül lehet-e definiálni az értéket, használjuk a .NET platform szolgáltatásait: erre találták ki a lockAttributes, lockAllAttributesExcept, lockElements, lockAllElementsExcept és lockItem attribútumokat. Ezek alkalmazásához azonban közvetlenül kell módosítanunk a .config állományokat. További információk
March 14 Kliens oldali validálás és OnClientClickHa egy weboldalon valaminek a törlésére készítünk funkciót, postback előtt mindig célszerű rákérdeznünk a felhasználónál, hogy valóban szeretné-e törölni a kiválasztott elemet. Az ilyen “valóban használni kívánja a légzsákot” jellegű kérdések megvalósítására kiváló hely a Button osztály OnClientClick tulajdonsága, az egyetlen hátránya, hogy összevész a validator vezérlők kliens oldali szkriptjeivel. A megerősítést kérő ablak feldobása mindössze ennyi: <asp:Button ID="btnGo" runat="server" Text="Mehet" OnClientClick="return confirm('Biztos, hogy ezt akarod?');" onclick="btnGo_Click" /> Ez tökéletesen működik egészen addig, amíg a gombhoz nem kapcsolódik validator, ebben az esetben ugyanis hiába van engedélyezve a validator kliens oldali szkriptje, megtörténik a postback és csak a válasz megérkezése után jelenik meg a hibaüzenet kliens oldalon. E helyzet még rosszabb, ha a gomb szerver oldali eseménykezelőjéből kifelejtjük a Page.IsValid ellenőrzést, mert akkor még le is fut a teljes kódunk, mintha a validator ott sem lenne. A probléma tehát az, hogy rossz a kliens oldali szkriptek futásának sorrendje. Szerencsére a validatorokhoz van kliens oldali API, ami részben dokumentált, részben pedig erős nézés módszerével (ld. pl. IE8 script debugger) megfejthető. Ez utóbbi úton jutottam az alábbi megoldáshoz, ami megoldja a fenti problémát: <asp:Button ID="btnGo" runat="server" Text="Mehet" OnClientClick="Page_ClientValidate('myGroup'); if(!Page_IsValid) return false; return confirm('Biztos, hogy ezt akarod?');" onclick="btnGo_Click" March 13 Fiddlerezzünk JSONt localhostonEgy klienshez ADO.NET Data Services-zel készítettem a szerver oldali komponenst, ami JSON-ban küldte vissza az adatokat a kliensnek. Hibakeresés közben bele kellett néznem az utazó adatokba, ami még Fiddlerrel sem bizonyult egyszerűnek. Fiddler kontra ASP.NET Development ServerA Fiddler egyik óriási előnye a kényelmes használata, nem kell konfigurálni semmit (na jó, Firefoxot kell), csak elindítani és máris mutatja a böngésző és a szerver közötti forgalmat. Kivéve, ha localhoston dolgozunk, azt ugyanis némi trükközés nélkül nem képes elkapni. Megoldás lehet localhost helyett a gépnév használata, ami tökéletesen működik IIS-sel, az ASP.NET Development Server viszont csak localhostra hallgat, arra is csak IPv4-en. A trükk az, hogy FQDN-ként az ipv4.fiddler hostot kell használni és máris megy minden, mint a karikacsapás. Böngésző kontra AstoriaAz ADO.NET Data Services (Astoria) által szolgáltatott URL-ek alapértelmezés szerint Atom formátumban küldik vissza az adatokat, amire korunk brilliáns böngészői azonnal ráharapnak és megpróbálják az RSS olvasó oldalukkal megjeleníteni. Ami gyakorlatilag használhatatlanná teszi a böngészőt, mint Astoria klienst:
Természetesen kattintgathatnám a jobb egérgombot és a View Source menüpontot az Atom feed forrásának megtekintéséhez, de ezt percenként többször nem akaródzik megtenni. Nem beszélve arról, ha a kliensnek nem Atom, hanem JSON formátumú adat kell. Ehhez szerver oldalon nem kell konfigurálni semmit, mindössze annyi szükséges, hogy a kliens JSONt kérjen, és ezt a HTTP request Accept fejlécében feltüntesse. A böngésző végképp nem alkalmas arra, hogy request header mezőket faragjunk vele... Fiddler és az Accept fejlécA Fiddlerben van egy kiváló Request Builder funkció, amivel összerakhatjuk a kérést és még a fejléc mezőket is megadhatjuk. Feltüntetve, hogy Accept: application/json, máris JSONban jön a válasz:
Hibalehetőségek:
Fiddler és a JSONMár csak annyi maradt hátra, hogy a JSON választ meg kellene nézni. Ha hostként ipv4.fiddlert adtunk meg, akkor a bal oldali listából ki tudjuk választani a kérésünket és jobb oldalon az Inspectors fülön látjuk is a forgalmat:
Így elég nehézkes JSONt nézegetni, ezért érdemes letölteni a CodePlexről az ingyenes JsonViewert. A letölthető csomagban találunk egy önálló .exe alkalmazást, egy Fiddler plugint és egy Visual Studioba beépülő visualizert. A telepítés az útmutató követve pikkpakk megvan és a Fiddler újraindítása után máris barátságosabb formában láthatjuk a JSON választ:
Technorati Tags: ADO.NET Data Services,Astoria,Fiddler,JSON,Atom,JsonViewer,Cassini,ASP.NET Development Server,IIS March 12 Lockdown Policy Prevents This RequestAz egyik webalkalmazásunkkal kapcsolatban több megkeresés érkezett, hogy a felhasználókat nagyon zavarja a sok tanúsítvány figyelmeztetés, ezért jó lenne a Root CA tanúsítványát közvetlenül letölthetővé tenni a bejelentkező oldalról. Fogtam hát a tanúsítványkiadó tanúsítványát .cer formátumban, felmásoltam a webszerverre, majd kissé meglepődve bámultam a böngészőben megjelenő 404 – Not Found hibaüzenetet. Persze IIS 6-ról lévén szó, tudtam, hogy akármit nem enged letölteni a webszerver, ezért végignéztem a Mime Map beállításokat, de nem segített. Kénytelen voltam megnézni a webszerver naplóját (olvasott embernek párja nincs :) ), ahol nem csak a HTTP hibakód, hanem az alhibakód is látszik: 404.2. Erről a Technet oldalon kiderült, hogy a jelentése Lockdown Policy Prevents This Request, tehát valami ISAPI vagy CGI a ludas. Az Application Configuration ablakot megnyitva megjelent a hiba oka:
A .cer kiterjesztés kiszolgálásáért az ASP (nem ASP.NET!) feldolgozó motor felelős, ami persze alapértelmezés szerint nincs engedélyezve az IIS 6 Web Server Extensions listájában. Két megoldás maradt:
March 09 IdentityNotMappedExceptionNem először sikerül belefutnom az alábbi kivételbe, szinte mindig valamilyen egyedi telepítő futtatása közben: “System.Security.Principal.IdentityNotMappedException: Nem lehet lefordítani néhány azonosítási hivatkozást, illetve egyet sem.”Na kösz, és ez mit jelent?
Angolul egy kicsit közelebb juthatunk a megoldáshoz:
Már csak az a kérdés, hogy mi az az identity reference és mi az a translate. A problémát az eddigi esetekben mindig az jelentette, hogy a telepítő jogosultságot akart osztogatni egy mappán vagy registry kulcson, mégpedig egy konkrét felhasználó számára, tehát itt kell elkezdenünk keresgélni. A feladat valóban megoldható .NET-ben, a System.Security.Principal névteret használva, az NTAccount osztály segítségével meg tudok nevezni (reference) egy felhasználót (identity) és tudok neki jogot adni. A Windows hozzáférés szabályozási listáiban (Access Control List – ACL) az Access Control Entry-k mindig SID (Security IDentifier)-jogosultság párosokat tartalmaznak, tehát hiába adok meg egy felhasználó nevet, azt mindig SID-dé kell változtatni (translate), hogy tudjunk neki jogot adni. Szerencsére ezt a háttérben a .NET Framework osztályai megoldják helyettünk. A fenti IdentityNotMappedException akkor keletkezik, amikor nem sikerült a névből SIDet gyártani, ez pedig tipikusan akkor fordul elő, amikor a “Rendszergazda” vagy a “Hálózatszolgáltatás” felhasználóra vagy éppen a “Rendszergazdák” csoportra hivatkozunk és a kódunkat angol operációs rendszeren futtatjuk, ahol nincs ilyen csoport. Vagy éppen fordítva, magyar Windowson keres a kódunk “Network Service” nevű felhasználót. Ha a kódot nem mi írtuk, akkor a megoldás egy csoport létrehozása “Network Service” néven, amibe belepakoljuk a “Hálózatszolgáltatás” felhasználót és egy csapásra működni fog a kód. Ha a kódot mi írtuk, akkor a megoldás az, hogy elszégyelljük magunkat, mert még nem hallottunk az ún. nevezett well-known SID-ekről vagy mert lusták voltunk használni őket. A standard felhasználóknak és csoportoknak a SID-jük is standard, nem csoda, hogy van rá enum a .NET Frameworkben, úgy hívják hogy WellKnownSidType. A használata pofonegyszerű, annyi a lényeg, hogy nem az NTAccount osztályt kell használni, hanem annak testvérét, a SecurityIdentifiert: DirectoryInfo di = new DirectoryInfo( @"C:\Teszt" ); DirectorySecurity acl = di.GetAccessControl(); SecurityIdentifier sid = new SecurityIdentifier( WellKnownSidType.NetworkServiceSid, null ); FileSystemAccessRule ace = new FileSystemAccessRule( sid, FileSystemRights.Write, AccessControlType.Deny ); acl.AddAccessRule( ace ); di.SetAccessControl( acl ); Ez már nem fog olyan könnyen elhasalni. Technorati Tags: ACL,ACE,Access Control List,Access Control Entry,security,well-know SID,Security IDentifier,.NET March 03 Elindul a Kitörés programKérdés: Készítettem egy ASP.NET alkalmazást, ki fogja nekem ingyenesen hosztolni? Egy lehetséges válasz:
Bővebbe információk: http://devportal.hu/kitores Ti hova szoktátok feltölteni? Ha itt jártál, kérlek hagyj üzenetet a vendégkönyvben, hogy tudjam, van még odakint valaki! Köszönöm!
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|