ASP.NET MVC to Silverlight Communication

2019-08-01 20:28发布

问题:

So I have an ASP.NET MVC web application that has a silverlight application embedded in it and I'd like the SL client to communicate with the database through a SL enabled WCF service that runs inside the ASP.NET MVC application. I have had no luck in getting this to work, the silverlight application gets a service reference to the WCF service just fine. When I run the silverlight client and call the web service it returns a NOT FOUND exception every single time. I can see through debugging that the WCF service does get called, but the silverlight errors out and nothing gets passed back.

I did try enabling the

serviceDebug includeExceptionDetailInFaults="true"

But I still get the NOT FOUND exception. Any thoughts?

回答1:

The first trick would be to get your silverlight to communicate with your WCF properly. NOT FOUND occurs on MANY scenarios. It could be that your Web Service is not running in IIS, it could be that you are trying to communicate using some sort of object that violates the service contract. E.g. Your object has a property of type "object" that can be anything. The first step to narrow down this process would be to install Fiddler2 to show you the network traffic between your client and your server.

Once this is done, i.e., once you are sure that your silverlight app can communicate with the webserver, then you can take the approach of communicating between your asp.net and silverlight application. Now, keep in mind that Silverlight runs on the client, and asp.net runs on the server, therefore, communicating from and aspx code behind page to a silverlight light object must happen through some sort of common proxy - that proxy being JavaScript. Define a javascript method that would access a bridge to the silverlight/object container and pass the method. And vice versa, define a method that would allow the silverlight to talk back to the javascript.

For example, let's say you have a category listing that is displayed in silverlight on your aspx/html page. Most likely, that category listing exists in a XAP file in you ClientBin folder for your asp.net project.
Example:

<div style="margin:auto; float:left; height:auto;">
    <div id="silverlightControlHost_Categoris" style="height:auto;">

        <object id="silverlightControl_Categories" data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" style="height:100%">
        <param name="source" value="ClientBin/Categories.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="ScaleMode" value="Stretch" />
        <param name="EnableAutoZoom" value="True" />
        <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50826.0" style="text-decoration:none">
            <img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight" style="border-style:none"/>
        </a>
    </object><iframe id="Iframe2" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe>
    </div>
</div>

Next, in your loaded event for your Silverlight Project, register the object as scriptable:

using System.Windows.Browser;

namespace CategoryListing
{
[ScriptableType]
public partial class MainPage : UserControl
{
    public MainPage()
    {
        InitializeComponent();
    }

    private void UserControl_Loaded(object sender, RoutedEventArgs e)
    {
        categoryListing1.DataContext = new MyLibrary.ViewModel.TCategoryListingViewModel();
        //categoryListing1 is the name of the control whose data context is the view model
        HtmlPage.RegisterScriptableObject("categoriesBridge", (categoryListing1.DataContext as MyLibrary.ViewModel.TCategoryListingViewModel));
    }

}

}

Define the javascript method to talk to some method in the category listing view model

function selectCategory(category_id) {
var plugin = document.getElementById("silverlightControl_Categories");
//note the reference to the categoriesBridge property that was registered as scriptable
if (plugin != null)
    plugin.content.categoriesBridge.SelectCategory(category_id);

}

Define the SelectCategory Method:

[ScriptableMember]
    public void SelectCategory(string category_id)
    {
        //select the category here
    }

If you wanted to call this method from ANOTHER silverlight object on the page:

try
                {
                    HtmlWindow window = HtmlPage.Window;
                    window.Invoke("SelectCategory", new object[] { "Category1" });
                }
                catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); }

At the end of it all, you should be able to use your html/aspx markup on your page to invoke the javascript method to call the silverlight object.

Enjoy.



回答2:

I was able to figure this out - the objects I was using as data contracts were not marked as such and even though they were "accepted" by the silverlight app and were generated by the service reference they would always through this acception after the WCF service returned.