Monthly Archives: February 2009

ASP.NET adatbázis minimumon

Az ASP.NET egyik nagy előnye, hogy bizonyos funkciók megvalósításához standard megoldást kínál. A felhasználókezelés, a profil, az eseménynapló és a webkijelzők esetén a standard megoldás része a standard adatbázis is, amely alapértelmezés szerint 11 táblából, 9 nézetből, 55 tárolt eljárásból és 13 szerepkörből áll. Ezeknek jelentős részére azonban sok esetben nincs szükség, szabaduljunk meg tőlük!

Az ASP.NET standard adatbázis objektumainak létrehozásához az ASP.NET SQL Server Registration Tool nevű programot (aspnet_regsql.exe) szoktuk használni, tipikusan a grafikus felületen a varázslót végigkattintgatva. A varázsló nem kérdez túl sokat, beleömleszt mindent abba az adatbázisba, amit megadunk neki.

Ám ha az aspnet_regsqlt parancssorból futtatjuk, sokkal finomabban tudjuk szabályozni, hogy mire van szükségünk. A –A kapcsoló után megadhatjuk, hogy kell-e membership (m), role (r), profile (p), webpart (c) és web events (w) funkció az alkalmazáshoz. Ha csak felhasználókezelés, szerepkörök és naplózás kell, akkor ezt kell írnunk:

aspnet_regsql –S localhost –d MyDatabase –E –A mrw

Az eszköz arra is képes, hogy egy kész adatbázisból törölje a felesleges objektumokat, ehhez –A helyett a –R kapcsolót kell használnunk. A fenti parancs egyébként mindössze 7 táblát, 5 nézetet, 36 tárolt eljárást és 7 szerepkört hoz létre, a különbség tehát jelentős, érdemes foglalkozni vele.

A parancssorból történő futtatás további előnye, hogy szkriptelhetjük vele az adatbázis létrehozását, ami automatizált tesztelésnél vagy release menedzsmentnél hasznos lehet. Ha kíváncsiak vagyunk, hogy mit művel az eszköz a háttérben, adjuk meg a –sqlexportonly kapcsolót, amely hatására nem történik változás az adatbázisban, csak kiíródnak fájlba az SQL utasítások.

Ugyanezt az eszköz szolgál az SQL Cache Dependency és a Session State adatbázissal kapcsolatos beállításainak kezelésére is. A parancssori paraméterekről itt találunk részletes leírást.

Webhelyek, mappák és alkalmazások az IIS 7-ben

Az IIS 7 felügyeletével kapcsolatos alapfeladatok közé tartozik egy mappa tartalmának publikálása a webkiszolgálóra. Ehhez először egy webhelyet (site) kell létrehoznunk, amelynél ún. kötések (bindings) segítségével határozzuk meg, hogy milyen IP címre, port számra, hoszt névre és protokollra érkező kérések esetén kell a webkiszolgálónak ehhez a webhelyhez irányítania a klienst. A webhelyekhez mindenképpen meg kell adnunk egy fizikai mappát (content directory, physical path), amelyben a webhelyhez tartozó fájlok találhatóak. A fizikai mappákon kívül az IIS Managerben létrehozhatunk virtuális mappát (virtual directory) is, amelyhez tartozó álnév (alias) megjelenik az URL-ekben, miközben a tartalma fizikailag egy másik mappából kerül kiszolgálásra.

A mappákat át lehet konvertálni alkalmazásokká (application), amely annyiban különbözik a hagyományos mappáktól, hogy egy alkalmazáskészlethez (application pool) van rendelve. Az azonos alkalmazáskészlethez tartozó alkalmazásokra irányuló kéréseket közös feldolgozó folyamat (worker process, w3wp.exe) szolgálja ki. Az alkalmazáskészlet beállításainál tudjuk megadni, hogy a kérés kiszolgálása milyen felhasználó nevében történjen (identity), valamint azt is, hogy a feldolgozást végző folyamat maximum mennyi erőforrást (processzor, memória) használhat. Ezekkel a beállítási lehetőségekkel az alkalmazáskészletek lehetővé teszik az alkalmazások és webhelyek egymástól történő elszigetelését a webkiszolgálón.

Demó

A demóban létrehozunk egy új webhelyet, amely a 8080-as portra érkező kéréseket szolgálja ki statikus tartalommal. A webhelyen bemutatjuk a Default document funkció használatát, fizikai és virtuális mappák létrehozásának módját IIS Managerben, valamint az alkalmazások és az alkalmazáskészletek képességeit, külön kitérve azok újraindítására.

A videó a képre kattintva megtekinthető böngészőben vagy a kép alatti linkre kattintva letölthető:

Webhelyek, mappák és alkalmazások az IIS 7-ben screencast megtekintése

Letöltés: 03_IIS7_Webhelyek_(Balassy_Gyorgy).wmv (20:49, 81.4 MB)

Első lépések

Első lépésként fejtsük meg, hogy pontosan milyen alapbeállításokkal települ fel a webkiszolgáló. Írjuk be a böngészőbe a http://localhost címet, majd nézzük meg az IIS Managerben, hogy milyen beállítások szükségesek ahhoz, hogy a böngészőben az IIS 7 kezdőlapja megjelenjen. Próbáljunk létrehozni egy másik webhelyet http://localhost:8000 címen, amely egy másik mappából jelenít meg egy kezdőlapot.

Jó tudni

Az IIS képes hostname alapján megkülönböztetni a webhelyeket, azaz egyetlen fizikai gépen, egyetlen IP címen üzemeltethetjük a http://example.com és a http://example.net webhelyeket. Ez a megoldás azonban nem fog működni, ha mindkét webhely https protokollt használ, ez a protokoll ugyanis titkosítja a hostname paramétert is. Ebben az esetben nincs más lehetőségünk, vagy el kell térnünk az https-hez alapértelmezés szerint rendelt 443-as porttól, vagy pedig külön IP címeket kell rendelnünk a webhelyekhez.

További információk

A cikk a Microsoft TechNet Portál támogatásával készült.

Technet

WCF szolgáltatás IIS-en: 404 Page Not Found

Ebbe elég könnyű belefutni és pofonegyszerű a megoldás, csak nem biztos, hogy elsőre beugrik, ezért inkább leírom. Adott egy prímán megírt WCF szolgáltatás, ám amikor IIS-re telepítjük, nem működik. Böngészőben megnézve az .svc fájlt HTTP Error 404: Not Found fogad, pedig a fájl ott van. Csak szegény IIS nem tud róla.

A Windows Communication Foundationt ugyanúgy regisztrálni kell a webkiszolgálóba, mint az ASP.NET-et. ASP.NET esetén erre az aspnet_regiis.exe szolgál, WCF esetén pedig a ServiceModelReg.exe. Az ész nélküli telepítést ugyanúgy a –i kapcsoló szolgáltatja, a telepítés ellenőrzésére viszont a –vi kapcsolót kell használnunk. A ServiceModelReg.exe a .NET Framework 3.0 telepítése után a C:WindowsMicrosoft.NETFrameworkv3.0Windows Communication Foundation mappában található, futtatásához rendszergazdai jogok szükségesek.

CryptographicException: Keyset does not exist

Korábban CardSpace használatakor futottam bele a fenti hibaüzenetbe, most egy IIS-ben hosztolt WCF szolgáltatás készítésekor jött elő. Elvesztettem volna a kulcsaimat? A problémát az okozza, hogy a web.config fájlban szerepel egy tanúsítvány hivatkozás a <serviceCertificate> ágban, de az IIS worker process felhasználói fiókjának, alapértelmezés szerint a Network Service fióknak, nincs joga hozzáférni a tanúsítványhoz. De hogy adok egy tanúsítványra olvasási jogot?

A CardSpace esetén bemutatott megoldás persze most is működik: letöltjük a Web Services Enhancements (WSE) 3.0-t és a WseCertificate3.exe segítségével Read jogot adunk a felhasználónak.

Ha nincs kéznél WSE, akkor használhatjuk a WCF példák között elérhető Find Private Key Toolt (letölthető innen is). Listázhatjuk vele az egyes tanúsítványtárakban lévő tanúsítványokat. Legegyszerűbben így:

FindPrivateKey.exe My LocalMachine

Erre megkapjuk ezt:

Select Certificate ablak

A tanúsítvány kiválasztása után kattintsunk az OK gombra és máris megtudjuk, hol lakik a tanúsítvány:

FindPrivateKey.exe eredmény

Nincs más dolgunk, mint elnavigálni a megadott C:ProgramDataMicrosoftCryptoRSAMachineKeys mappába és a megadott 0a38f98… nevű fájl tulajdonságlapján a Network Service felhasználónak Read jogot adni. Nem kell több, elég a Read!

Almás gomb Silverlightban

Nagy fába vágtam a fejszém, amikor szerettem volna valami igazán szépet alkotni Silverlightban, ugyanis a dizájnhoz egyáltalán nem értek. Valahonnan viszont rémlett, hogy az Expression Design tud Photoshopból importálni és XAML-be exportálni, így letöltöttem egy pofás iPhone stílusú gombot a netről .psd formátumban és megpróbáltam .xaml-lé alakítani. Nem sikerült 😦

Szerencsétlen Expression Designnak volt pofája PNG fájlként kimenteni, majd a XAML-be egy Image taget tenni. Noooooormális?

Így nem volt más hátra, nekem kellett rajzolnom. Szerencsére Buck Wilson oldalán találtam egy Photoshop tutorialt, csak ugyanazt kellett Expressionben végigkattintgatnom.

Kezdjük egy keret nélküli, lekerekített négyzettel:

    <Rectangle x:Name="background" Width="180" Height="180" 
RadiusX
="30" RadiusY="30" Fill="#FF0677D5" StrokeThickness="0" />

iPhone_background

Az alsó színátmenethez a háttérre rákerült egy ugyanekkora négyzet, átlátszóba tűnő színátmenettel:

    <Rectangle x:Name="underglow" Width="180" Height="180" 
Stroke
="#FF000000" RadiusX="30" RadiusY="30" StrokeThickness="0"> <Rectangle.Fill> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#00FFFFFF" Offset="0.7"/> <GradientStop Color="#B2FFFFFF" Offset="1"/> </LinearGradientBrush> </Rectangle.Fill> </Rectangle>

iPhone_underglowA felső részhez lemásoltam a négyzetet Blendben, majd rárajzoltam egy elliszist és vettem a két objektum metszetét az Intersect menüpont segítségével. Így lett egy alulról íves, felülről lekerekített Path objektumom, amit színátmenettel tudtam kitölteni:

    <Path x:Name="topglare" Height="93.5" Margin="10,10,10,96" 
Stretch
="Fill" Stroke="#FF000000" StrokeThickness="0" Data="..."> <Path.Fill> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#B2FFFFFF"/> <GradientStop Color="#4CFFFFFF" Offset="1"/> </LinearGradientBrush> </Path.Fill> </Path>iPhone_topglare

Sokat kísérleteztem a szép árnyékkal, végül több körvonallal sikerült megoldani:

    <Canvas x:Name="shadow" Margin="6, 7, 0, 0">
        <Border CornerRadius="30" Canvas.Left="4" Canvas.Top="4" Width="180" Height="180" 
BorderThickness
="1" BorderBrush="Black" Opacity="0.50" /> <Border CornerRadius="31" Canvas.Left="3" Canvas.Top="3" Width="182" Height="182"
BorderThickness
="1" BorderBrush="Black" Opacity="0.40" /> <Border CornerRadius="32" Canvas.Left="2" Canvas.Top="2" Width="184" Height="184"
BorderThickness
="1" BorderBrush="Black" Opacity="0.20" /> <Border CornerRadius="33" Canvas.Left="1" Canvas.Top="1" Width="186" Height="186"
BorderThickness
="1" BorderBrush="Black" Opacity="0.10" /> </Canvas>iPhone_shadow

Ezzel a gomb lényegében elkészült, már csak egy nyilat akartam rárajzolni. Ehhez rajzoltam egy négyzetet, elforgattam 45 fokkal, hogy a sarkán álljon, majd elmetszettem egy négyzettel. Így lett egy csúcsán álló háromszögem, amit csak hozzá kellett ragasztanom egy téglalaphoz és kész is lett a nyilat leíró Path:

    <Path x:Name="arrow" Fill="#FFFFFFFF" Stretch="Fill" Stroke="#FF0677D5" StrokeThickness="4" 
Data
="..." Height="94.641" Margin="0,25.479,-8.949,79.521"
RenderTransformOrigin
="0.251,0.202"
d
:LayoutOverrides="Height" Width="95" HorizontalAlignment="Right"> <Path.RenderTransform> <TransformGroup> <RotateTransform Angle="45"/> <TranslateTransform X="-43.27" Y="23.665"/> </TransformGroup> </Path.RenderTransform> </Path> iPhone_arrow

A nyíl vastag körvonalat kapott (StrokeThickness=”4”) és olyan körvonal színt, mint a háttér. Ha más színű gombot szeretnék, csak a #FF0677D5 színt kell másikra cserélni.

A tapasztalatom az, hogy ha az ember tudja, mit akar rajzolni, egészen jól lehet az Expression Blendben boldogulni. A generált Path objektumokat viszont fehér ember biztosan nem fogja kódból módosítani Visual Studioban.

Akinek épp ilyen gombra van szüksége, letöltheti a teljes XAML fájlt.

Az IIS Manager használata

Az IIS 7 kiszolgáló oldali felügyeleti eszköze teljesen megújult az előző verzió óta. Az új alkalmazás továbbra is a %SystemRoot%System32Inetsrv mappában található inetmgr.exe, azonban ez egy teljesen újraírt alkalmazás Windows Forms alapokon, amely teljes egészében kiváltja a korábbi MMC alapú felügyeleti konzolt. Az IIS Manager lehetővé teszi a webkiszolgáló távoli felügyeletét, amely a Web Management Service segítségével standard HTTPS protokoll felett valósul meg, alapértelmezés szerint a 8172-es porton.

IIS Manager Az IIS Manager által végzett beállítások – akár távol, akár helyben futtatjuk – mindig egy XML konfigurációs fájlba íródnak, vagy a kiszolgálóhoz tartozó applicationHost.config vagy valamelyik web.config állományba. Az IIS 7 rugalmas konfigurációs sémája lehetővé teszi a webkiszolgáló szolgáltatásainak bővítését, amely a felügyeleti konzolra is kiterjed: az IIS Managerhez tartozó administration.config fájlban határozhatjuk meg, hogy az eszköz milyen modulokat jelenítsen meg.

Az IIS Manager teljes felhasználói felülete megújult, nagyobb teret biztosítva a konfiguráció kezelésének a tartalommal szemben. A korábban már megszokott fa hierarchia mellett a középső területen szolgáltatások szerint rendezve találjuk meg az egyes beállításokat, a jobb oldali panelen pedig helyzetérzékenyen jelennek meg az aktuálisan végrehajtható parancsok.

Demó

A demóban bemutatjuk az IIS 7 felügyeleti eszközének, az IIS Managernek a használatát. A videó a képre kattintva megtekinthető böngészőben vagy a kép alatti linkre kattintva letölthető:

Az IIS Manager használata screencast megtekintése

Letöltés: 02_IIS7_IIS_Manager_(Balassy_Gyorgy).wmv (14:00, 60.2 MB)

Első lépések

A Start Menu Administrative Tools csoportjából indítsuk el az Internet Information Services (IIS) Manager parancsot és a bal oldali fában a Connect to a Server… parancs segítségével kapcsolódjunk a webkiszolgálóhoz.

Jó tudni

Amikor az IIS Managerben módosítunk egy konfigurációs beállítást, a módosítás az applicationHost.config vagy valamelyik web.config állományba íródik be. Miközben az aktuális beállítást szerkesztjük, érdemes egy pillantást vetnünk az alsó státuszsorra, itt ugyanis megjelenik, hogy éppen melyik konfigurációs állományt szerkesztjük.

A cikk a Microsoft TechNet Portál támogatásával készült.

Technet

Elindult a Videótár

Az MSDN Kompetencia Központ honlapjának forgalomelemzéséből kiderült, hogy az Induló Készletek mellett sokan a korábban publikált screencastokat keresitek az oldalon. A kevesebb keresgélés érdekében ezért kialakítottunk egy könnyen átlátható Videótár oldalt, és a jövőben minden új videót itt is meg fogunk jelentetni.

A készlet gyarapítása érdekében a TechNet Portállal együttműködve újabb screencastokat készítettünk, melyek segíthetnek egy-egy technológia megismerésében. A Videótárban már elérhetőek az SQL Server 2008 adatbányászati funkcióiról szóló felvételek, hamarosan pedig IIS 7, PHP, SQL és SharePoint demókkal jelentkezünk. Mi érdekel legjobban?

A videótár közvetlenül az alábbi címen érhető el:

http://www.msdnkk.hu/Videotar

MVP interjú

Talán nem annyira közismert, hogy pontosan mi is az MVP program, ezért különösen örülök, hogy a TechNet Portálon külön rovat foglalkozik a programmal és a magyarországi díjazottakkal. Az oldalon a gyakran ismételt kérdések mellett nemrég elindult egy interjúsorozat a magyar MVP-kkel, ami segít kicsit bepillantani abba, hogy belülről hogyan látjuk ezt a címet. A héten én voltam az interjúalany, a beszélgetés már olvasható a TechNet Portálon. Remélem egy kicsit a regional director program céljára is sikerült rávilágítanom.

Kommunikáció ASP.NET és Silverlight között

Mostanában divat azon vitatkozni, hogy az ASP.NET vagy a Silverlight-e a jövő webfejlesztő technológiája. Különösen az utóbbi hívei között vannak olyanok, akik szeretik azt hinni, hogy kis kedvencük minden helyzetben tökéletes választás. Szerintem a két technológiát együtt fogjuk használni a jövőben: amit nem lehet vagy nem célszerű a böngészőben megoldani, ott fogunk a böngésző bővítményhez folyamodni. Ehhez persze nélkülözhetetlen, hogy a két világ tudjon egymással kommunikálni.

Silverlight alkalmazás inicializálása ASP.NET-ből

Egy Silverlightos alkalmazásnak induláskor adatokat adhatunk át az initParams paraméterben. Egyetlen stringben, vesszővel elválasztva kell felsorolnunk az átadandó kulcs-érték párokat.

HTML:

    <object data="data:application/x-silverlight-2," ...>
        <param name="source" value="ClientBin/SilverlightApplet.xap"/>
        <param name="initParams" value="p1=Első paraméter,p2=Második paraméter" />
        ...
    </object>

ASP.NET-ben a beágyazó asp:Silverlight vezérlő InitParameters tulajdonságát kell használnunk akár code behindból, akár ASPX markupból:

    <asp:Silverlight ID="slPlugin" runat="server" Source="~/ClientBin/SilverlightApplet.xap"
        MinimumVersion="2.0.31005.0" Width="100%" Height="100%"
        InitParameters="p1=Első paraméter,p2=Második paraméter" />

Az így átadott paraméterek Silverlightban az App.xaml.cs fájlban lévő Application_Startup metódus StartupEventArgs e paraméterében érkeznek meg egy szótár típusú változóban. Ha nem csak itt akarjuk elérni, akkor szerintem érdemes kitenni statikus változóba:

    // Silverlight: 
public partial class App : Application { internal static IDictionary<string, string> InitParams; private void Application_Startup( object sender, StartupEventArgs e ) { App.InitParams = e.InitParams; this.RootVisual = new Page(); }
}

Ez persze bárhonnan elérhető a Silverlight alkalmazáson belül:

    // Silverlight: A bemenő paramétereket vesszővel kell elválasztani, különben KeyNotFoundException jön.
    this.lblInitParams.Text = String.Format( CultureInfo.InvariantCulture, 
        "Param1={0}, Param2={1}", App.InitParams[ "p1" ], App.InitParams[ "p2" ] );

Érték átadása a weboldalról

Az ASP.NET és a Silverlight együttélésének a kulcsa a Silverlight HTML Bridge nevű komponense, aminek segítségével felügyelt kódból érhetjük el a böngészőben futó oldalt, illetve a felügyelt kódunk bizonyos részeit tehetjük böngészőből elérhetővé. Ahhoz, hogy a weboldalról adatot tudjunk átadni egy Silverlight alkalmazásnak, egy felügyelt metódust kell publikálnunk, melyet majd JavaScriptből hívunk meg. A kiválasztott metódus elé a [ScriptableMember] attribútumot kell biggyesztenünk. Ha a metódust más néven akarjuk szkriptből meghívni, használhatjuk az attribútum ScriptAlias tulajdonságát. Ha egy osztály összes metódusát publikálni szeretnénk, akkor az osztály elé tehetjük a [ScriptableType] attribútumot.

    // Silverlight
    // [ScriptableType]
    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();
            HtmlPage.RegisterScriptableObject( "MyScriptableType", this );
        }

        [ScriptableMember]
        public string SayHello( string name )
        {
            this.lblMessageIn.Text = name;
            return "Szia " + name;
        }
}

A következő lépés a HtmlPage.RegisterScriptableObject meghívása. Az első paraméterben tetszőleges sztringet megadhatunk, ilyen néven lesz elérhető a második paraméterben megadott objektumunk JavaScriptből.

A példában egy HTML szövegdoboz értékét adjuk át gombnyomásra a fenti SayHello metódusnak, ami az slPlugin azonosítójú asp:Silverlight vezérlőben fut:

    <!-- ASPX -->
<asp:ScriptManager runat="server" />

    <input type="text" id="txtName" />
    <input type="button" value="Küldés" onclick="sendToSilverlight()" />
    <script type="text/javascript" language="javascript">
        function sendToSilverlight()
        {
            var slPlugin = $get( '<%= this.slPlugin.ClientID %>' );
            var txtName = $get( 'txtName' );
            var result = slPlugin.Content.MyScriptableType.SayHello( txtName.value );
            alert( 'Válasz: ' + result );
        }
    </script>

A JavaScript írásakor ne várjunk az IntelliSensre, nem lesz.

Érték átadása a weboldalnak

Silverlightból adhatunk át adatokat a weboldalnak, a HTML Bridge segítségével ugyanis gyakorlatilag a teljes DOM-ot kezelhetjük felügyelt kódból. (Na ezt kellene valakinek megírnia egy kicsit típusosabban ASP.NET-ben…) Arra kell csak figyelni, hogy a Silverlight pluginon vagy az őt tartalmazó div elemen ne legyen display:none vagy visibility:hidden. Szépen is néznénk ki, ha láthatatlan vezérlők rángathatnák a weboldalunkat 🙂

Íme az ASPX oldalunknak az a része, amely fogadni fogja az adatot a Silverlight alkalmazástól:

    Fogadott: <span id="lblName">(még nem jött semmi)</span>

Silverlight oldalon faragtam egy mini űrlapot:

    <StackPanel Orientation="Horizontal">
        <TextBlock Text="Küldendő üzenet: " FontWeight="Bold" VerticalAlignment="Center" />
        <TextBox x:Name="txtMessageOut" Width="100" />
        <Button x:Name="btnSend" Content="Küldés" Click="btnSend_Click" />
    </StackPanel>

A lényeg persze a gomb eseménykezelője:

    // Silverlight 
private void btnSend_Click( object sender, RoutedEventArgs e ) { HtmlDocument doc = HtmlPage.Document; HtmlElement lblName = doc.GetElementById( "lblName" ); lblName.SetAttribute( "innerHTML", this.txtMessageOut.Text ); }

Weboldal esemény kezelése Silverlightban

Arra is van lehetőségünk, hogy felügyelt kódban kezeljük egy HTML DOM objektum valamely eseményét, ráadásul ehhez nem kell JavaScriptet írni. Készíthetünk például egy combo boxot a weblapunkra:

    <!-- HTML / ASPX -->
    <select id="selWelcome">
        <option>Szia</option>
        <option>Helló</option>
        <optiondv</option>
    </select>

A select objektumnak van egy changed eseménye, amire feliratkozhatunk Silverlightból:

    // Silverlight: feliratkozás weblap esem?nyre
    HtmlDocument doc = HtmlPage.Document;
    HtmlElement selWelcome = doc.GetElementById( "selWelcome" );
    selWelcome.AttachEvent( "onchange", new EventHandler<HtmlEventArgs>( this.OnWelcomeChanged ) );

Sajnos itt sem lesz IntelliSense az eseménykezelő megírásához, ezért jó tudni, hogy létezik egy HtmlEventArgs paraméter típus:

    private void OnWelcomeChanged( object sender, HtmlEventArgs e )
    {
        HtmlElement selWelcome = sender as HtmlElement;

        string selection = String.Empty;
        foreach( HtmlElement option in selWelcome.Children )
        {
            object selectedProperty = option.GetProperty( "selected" );

            if( selectedProperty != null )
            {
                if( selectedProperty.ToString().Equals( "true", StringComparison.OrdinalIgnoreCase ) )
                {
                    selection = option.GetProperty( "innerHTML" ).ToString();
                }
            }
        }
        MessageBox.Show( "Ezt választottad az oldalon: " + selection );
    }

A fenti kódból talán látszik, hogy a HTML Bridge az összes HTML elemet egyetlen HtmlElement osztályra képezi le. Ez persze nem rossz, de most éppen kicsit nehézkes megkeresni a kiválasztott gyermekelemet. Persze bevethetünk egy kis LINQ-et 🙂

    string selection = ( from HtmlElement option in selWelcome.Children
                         let o = option.GetProperty( "selected" )
                         where
                           p != null &&
                           p.ToString().Equals( "true", StringComparison.OrdinalIgnoreCase )
                         select option.GetProperty( "innerHTML" ).ToString()
).First();

A felhasznált osztályok a System.Windows.Browser névtérben találhatóak. Érdemes ott körülnézni, van ott még más hasznos típus is…

A cikkhez tartozó forráskód letölthető: HtmlBridgeSampleSolution.zip (549 kB)

SharePoint teljes webhelytartalom oldal nem jön be

Ma sikerült belefutnom az alábbi kedves üzenetbe egy Windows SharePoint Services oldalon, mikor a webhelyen lévő listákat (viewlsts.aspx) akartam megnézni:

An item with the same key has already been added.

Ilyet egy .NET-es alkalmazásban akkor szoktunk kapni, ha egy szótár típusú változóban már létezik elem azzal a kulccsal, amivel épp egy újat akarunk hozzáadni. Weben tipikusan postbacknél szokott előfordulni, nem pedig az oldal első lekérdezésénél. (De mint tudjuk, a SharePoint szinte bármire képes, így WSS-ben ez első oldal betöltésnél is elő tudott jönni.) Hagyományosan ilyenkor ki szoktuk javítani a kódot, de mivel ez a WSS beépített oldala volt, itt ez a lehetőség szóba se jöhetett. Így jobb híján maradt az a kalapács, amivel a SharePointos hibaüzenetek 130%-át le lehet csapni:

IISRESET

Működött.