简体   繁体   中英

How to send an xml serialized object from ASP.NET to Silverlight

On the button click on an ASP.NET page, I need to load a silverlight application, passing a serialized object from ASP.NET codebehind to MainPage.xaml.cs . How to do this?

Why not use WCF? This is a perfect fit for sending serialized objects. Also, WCF hosts well on IIS, so it works great with ASP. Here is a tutorial to get you started. You should be able to see clearly how to define a simply API that you can call from Silverlight. You just need to make your object part of a DataContract.

Some options for you, may help. You could use Javascript - silverlight.net on scripting Silverlight to reach inside the Silverlight object from your page.

Another option is to have the Silverlight object access the AspNet page to ask for it's xml using PageMethods . ( System.Web.Services.WebMethod) once it's loaded.

One option is to configure a Silverlight onLoad event in the <object> tag for your app:

<param name="onLoad" value="setInfo" />

Then use script to push the XML into your app (dynamically insert the XML onto the page from ASP.NET):

<script type="text/javascript">
    function setInfo(sender) {
        var msg = '<yourtag>your info here</yourtag>';
        sender.getHost().content.Page.SetInfo(msg);
    }
</script>

To allow script to call your app, configure as follows:

public MainPage()
{
    HtmlPage.RegisterScriptableObject("Page", this);
    InitializeComponent();
}

[ScriptableMember]
public void SetInfo(string xml)
{
    // do stuff
}

Register onLoad param in your Silverlight <Object> tag:

<object data="data:application/x-silverlight-2," type="application/x-silverlight-2">
 <param name="source" value="ClientBin/MySlApp.xap"/>
 <param name="onError" value="onSilverlightError" />
 <param name="background" value="white" />
 <param name="minRuntimeVersion" value="4.0.50826.0" />
 <param name="autoUpgrade" value="true" />
 <param name="onLoad" value="onSilverlightLoad" />
</object>

and register <Script>

<script type="text/javascript">
function onSilverlightLoad(sender, args)
{
var mySlControl = sender.getHost();
mySlControl.content.Communicator.MyDeserializer("SerializedObjectString")
}
</script>

In your Silverlight app register `Communicator' object so it is the app itself:

namespace MySilverlightApp
{
        public MySilverlightApp()
        {
            InitializeComponent();
            HtmlPage.RegisterScriptableObject("Communicator", this);
        }
}

and create de-serialization function decorated with [ScriptableMember] :

[ScriptableMember]
public void MyDeserializer(string _stringPassedFromHtmlDocument)
{
 //deserialize _stringPassedFromHtmlDocument
}

I have above working in one of Sharepoint projects utilising Silverlight webpart. Serialized object is however rendered into HTML so not sure if that will work for your Button.Click() requirement. One thing though should you go down this route: I encountered many many many issues when trying XML serialization and found JSON to be better alternative.

In your MainPage.xaml.cs, define a property getter/setter for whatever object type you need passed.

In your ASP.NET page button click handler, set the property to the serialized object.

If you need this to maintain the serialized object after the page lifecycle finishes, simply change the property setter in MainPage.xaml.cs to persist the serialized object across page lifecycles.

Hope this helps.

Pete

There are two possible paths here:

1) When the button is pressed, the page posts back to the server, gathers some information, serializes it into XML, shows the silverlight component, which then loads the serialized XML.

2) When the page is loaded, the XML data is available. Pressing the button simply shows the silverlight component and asks it to load the XML data.

Scenario 1

Here are the steps that you need to take for scenario 1.

1) Add the silverlight component to the page and embed it in a container (div, table, whatever you like) that is set to runat server. Note that we also specify an onload param to fire a specific event when the silverlight object has finished loading:

<div id="divDiagram" runat="server">
    <object data="data:application/x-silverlight-2," type="application/x-silverlight-2"
        id="objDiagram">
       <param name="onLoad" value="RefreshDiagram" />
    </object>
</div>

2) In your code-behind, hide this container until the button is pressed. For example:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!this.IsPostBack)
        {
            divDiagram.Visible = false;
        }
    }

    void Button1_Click(object sender, EventArgs e)
    {
        divDiagram.Visible = true;
    }

3) Add a hidden input to hold the serialized data:

<input type="hidden" id="txtSerializedData" runat="server" />

4) Set the contents of this input on the button click:

 txtSerializedData.Value = "some serialized data";

5) Modify the silverlight components code to expose the control to javascript:

    public MainPage()
    {
        InitializeComponent();

        System.Windows.Browser.HtmlPage.RegisterScriptableObject("DiagramPage", this);
    }

6) Add a method to the silverlight control that can be called from javascript (this is the ScriptableMember attribute) to get the serializable content and work with it:

    [System.Windows.Browser.ScriptableMember()]
    public void RefreshDiagram()
    {
        // Fetch the hidden input control from the page
        var serializedElement = System.Windows.Browser.HtmlPage.Document.GetElementById("txtSerializedData");

        // Then fetch its value attribute
        var sSerializedData = serializedElement.GetAttribute("value");

        // Finally, do something with sSerializedData
    }

7) Finally, add the javascript method to the page that is fired when the silverlight control is loaded:

<script type="text/javascript">

    function GetDiagramPageContent() {
        /// <summary>This method retrieves the diagram page object content</summary>
        // Exceptions are handled by the caller

        var oObject = document.getElementById('objDiagram');

        if (oObject) {
            return oObject.Content;
        } else {
            return null;
        }
    }

function RefreshDiagram() {
    try {
        var oContent = GetDiagramPageContent();
        try {
            // If we don't have content or a diagram page, bail
            if ((oContent == null) || (oContent.DiagramPage == null)) {
                return;
            }
        } catch (ex) {
            return;
        }

         // Now ask the control to refresh the diagram
        oContent.DiagramPage.RefreshDiagram();
    } catch (ex) {
        alert('Javascript Error (RefreshDiagram)\r' + ex.message);
    }
}
</script>

Scenario 2

Scenario 2 is very similar to scenario 1, with the following changes:

1) Do not include the onLoad param in the silverlight object. Instead, call the RefreshDiagram javascript method from the client-side button click.

2) Do not show or hide the containing div in code-behind. Instead, use the style attributes to control the visibility:

<div id="divDiagram" runat="server" style="visibility: hidden; visibility: visible">

and in the javascript button click event:

var oDiv = document.getElementById("divDiagram");
oDiv.style.visibility = "";
oDiv.style.display = "";

3) Load the hidden text box in pageload instead of on the server-side button click.

您可以使用Mike Talbot称为SilverlightSerializer的东西

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM