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...


zip HtmlBridgeSampleSolution.zip (549 kB)


Balássy György (MS RD, ASP.NET MVP, MCTS)

Balássy György (MS RD, ASP.NET MVP, MCTS) Villamosmérnök, a BME Automatizálási és Alkalmazott Informatikai Tanszékén webportálok fejlesztését oktatja. 2000 óta foglalkozik a Microsoft .NET platformjával, melynek meghonosításában jelentős szerepet vállalt előadóként, konzulensként és A .NET Framework és programozása című könyv társszerzőjeként. Az MSDN Kompetencia Központon belül a Portál Technológiák Csoport vezetője, szakterülete web alapú rendszerek fejlesztése és üzemeltetése. 2004-ben Magyarországon elsőként kapta meg a Most Valuable Professional címet, majd 2005 óta a Microsoft magyarországi regionális igazgatója. Publikációi a Technet Magazinban, az MSDN Kompetencia Központ honlapján és szakmai blogjában olvashatóak.

2009.02.07. 17:02:59 | Permalink | Hozzászólások: 0 | Tárgyszavak: , ,


  • Beágyazott operációs rendszerek, 4. nap (Windows XP Embedded)

    Kővári Bence Windows XP SP3, közel teljes funkcionalitással kicsit több mint 300 MB-nyi merevlemezen, és 72MB RAM induló memóriafoglalással, mindez csalás és hackelés nélkül, hivatalos Microsoftos eszközökkel. Na, erről szól a Windows XP Embedded. Ma röviden áttekintjük, hogyan lehet telepíteni, illetve mire érdemes külön odafigyelni a telepítés során. Tovább »
  • CSS és Javascript minimalizálás MSBuildből

    Balássy György (MS RD, ASP.NET MVP, MCTS) Az ASP.NET Web Site típusú projekt egyik tulajdonsága, hogy nem tartozik hozzá project fájl. Ez ugyan többnyire előny, mert kényelmes, nekem most éppen hátrány, mert MSBuilddel akarom automatizálni nem csak a fordítási folyamatot, hanem a web.config production beállításokkal történő frissítését, a felesleges könyvtárak törlését, továbbá a CSS és Javascript fájlok minimalizálását is. Tovább »


Írja meg Ön is véleményét!


Hozzászólásokat csak regisztrált, bejelentkezett felhasználóktól tudunk elfogadni!

Hozzászólások