Integrating SL 4 Module

Topics: Writing modules
Feb 16, 2011 at 1:43 PM
Edited Feb 16, 2011 at 1:44 PM

I'm developing a module (following MVC pattern and the guidelines for Orchard module development) to integrate my Silverlight 4 App into Orchard. This means using the Silverlight app as the View part (of MVC). So far so good. Is it correct when I say that my Silverlight 4 app can also 'work' (besides calling the controller for 'normal' CRUD actions) autonomous/isolated since I want to call (and get callbacks from) a WCF Duplex Communication service right from my Silverlight app (=not passing via the Controller)?

Thanks.

Developer
Feb 16, 2011 at 3:16 PM

Hi! There already exists a module for embedding Silverlight content (created by me) - maybe you should try it instead of writing your own. Source is available on Codeplex.

Basically I had the same problem - wrote a Silverlight app as a GUI to interact with the underlying WCF service. As I had problems with getting WCF to work with the Autofac DI container (so to be able to inject some objects, eg. IOrchardServices and so on, to the object handling a request) i sticked to the simple controller-based RESTful API via MvcApi project. It works perfectly and totally serves my purposes. So for now, this is the best solution.

As far as I know the integration of WCF with Orchard and Autofac is possible, but involves upgrading the Autofac library to the recent version, which as I suppose the Team doesn't want to do right now (as lot of things has changed and it would totally break the Orchard build).

Of course you can have an isolated WCF service inside Orchard (but without connection to the DI container), as inside any other ASP.NET app, and use from Silverlight embedded in a page.

About the MVC pattern... I know what you mean:) But... Silverlight is a standalone app, which requests data from your service and as such it should not be thought as a "View". View in this case would be eg. the JSON-formatted data Silverlight reads from your service.

Cheers!

 

Feb 16, 2011 at 3:24 PM

Hi,

Thanks.

I used the following example for integrating Silverlight with MVC http://blogs.microsoft.co.il/blogs/helpercoil/archive/2010/04/18/asp-net-mvc-2-0-and-silverlight.aspx
I'll give it a try (your SL module) but I suppose putting the example into the right places in my Orchard module should work also?

Thanks.
Guy

 

Developer
Feb 16, 2011 at 3:52 PM

Yes, putting the example should also work, but I'm not sure if TinyMce HTML editor used in Orchard wouldn't mess the <script> and <object> tags (if you'll try to insert it eg. in the Page item body).

I created that simple module just for making embedding Silverlight easier (basically it registers the necessary .js files and builds an <object> tag according to settings you provide). Just add SilverlightPart to your items, upload your .xap file, set the properties you need and that's all.

Cheers!

Feb 16, 2011 at 9:42 PM

When running the example I get a dialog box "Do you want to save this file, or find a program online to open it."
Any idea what goes wrong here?

Thanks.

Developer
Feb 16, 2011 at 11:04 PM

Take a look at the generated source if the <object> and <script> tag for Silverlight.js are correct. Also check if the correct MIME type is specified in the <object> tag. It looks like your browser doesn't recognize the Silverlight app and tries to download it.

Developer
Feb 16, 2011 at 11:08 PM

The object tag should look like this:

<object data="data:application/x-silverlight-2," type="application/x-silverlight-2"
        width="100%" height="100%">
        <param name="source" value="/MyFolder/My.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="width" value="100px" />
        <param name="height" value="100px"/>
        <param name="initParams" value="" />

        <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>
Feb 17, 2011 at 3:05 PM
Edited Feb 17, 2011 at 3:08 PM

Thanks.

Because I'm rather new to MVC so just to confirm: when url browsing first the system hits the (action code in the) Controller (not the View) and then the (code in the) Controller starts the View?

That means that when integrating a Silverlight App in a cshtml file that first I have to hit an action of the Controller that only starts the View that's hosting the Silverlight App (because when your try to return at that moment eg database records to the view that's hosting the Silverlight App there's no way to provide this info to the Silverlight App) . And after that the Silverlight can take control and initiate in REST-ful way actions in the Controller?

I'm trying to use the ASP.NET Helpers Library to play a Silverlight App (but didn't succeeded until now). Hereunder is the code I have in my View Index.cshtml file.

@using Microsoft.Web.Helpers;

<div>
    @{ Video.Silverlight(
       path: "ClientBin/MySLApp.xap",
    width: "400",
    height: "600",
    bgColor: "white",
    autoUpgrade: true
           ); }
</div>

I get an error CS0234: The type or namespace name 'Helpers' does not exist in the namespace 'Microsoft.Web' (are you missing an assembly reference?)

Feb 17, 2011 at 5:15 PM

in the meantime changed my Index.cshtml file in:

<script type="text/javascript" src="../../Silverlight.js"></script>
<script type="text/javascript">
    function onSilverlightError(sender, args) {
        var appSource = "";
        if (sender != null && sender != 0) {
            appSource = sender.getHost().Source;
        }

        var errorType = args.ErrorType;
        var iErrorCode = args.ErrorCode;

        if (errorType == "ImageError" || errorType == "MediaError") {
            return;
        }

        var errMsg = "Unhandled Error in Silverlight Application " + appSource + "\n";

        errMsg += "Code: " + iErrorCode + "    \n";
        errMsg += "Category: " + errorType + "       \n";
        errMsg += "Message: " + args.ErrorMessage + "     \n";

        if (errorType == "ParserError") {
            errMsg += "File: " + args.xamlFile + "     \n";
            errMsg += "Line: " + args.lineNumber + "     \n";
            errMsg += "Position: " + args.charPosition + "     \n";
        }
        else if (errorType == "RuntimeError") {
            if (args.lineNumber != 0) {
                errMsg += "Line: " + args.lineNumber + "     \n";
                errMsg += "Position: " + args.charPosition + "     \n";
            }
            errMsg += "MethodName: " + args.methodName + "     \n";
        }

        throw new Error(errMsg);
    }
</script>
<div>
    <object data="data:application/x-silverlight-2," type="application/x-silverlight-2"
        width="100%" height="100%">
        <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="width" value="600px" />
        <param name="height" value="400px" />
        <param name="initParams" value="" />
        <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>
</div>

and now get the error message:
Microsoft JScript runtime error: Unhandled Error in Silverlight Application
Code: 2104   
Category: InitializeError      
Message: Could not download the Silverlight application. Check web server settings    

Developer
Feb 17, 2011 at 6:03 PM

It looks like there's a permissions issue with access to /ClientBin or the path you provided is incorrect. This is why I integrated the Media feature in my module. Using relative paths directly in shapes is dangerous, because you can't control the URL under which the shape will be rendered (eg. /mysilverlighpage or /something/other/mysilverlightpage).

If you upload the .xap file to the Media folders in Orchard, then you can access it with the path: /Media/<tenant_name>/.../YourApp.xap. Tenant name is "Default" for the main site.

Feb 17, 2011 at 8:01 PM
Edited Feb 17, 2011 at 8:01 PM

Thanks.
i have put the .xap file Orchard\src\Orchard.Web\Media but still the same error message.

Developer
Feb 17, 2011 at 8:27 PM

Try uploading it via Dashboard --> Media (first create folder, then click "Add Media" and upload your file) and then copy the URL shown on the file details page. It should work without problems.

I guess putting files directly in \Media folder doesn't render it accessible. 

Feb 17, 2011 at 9:18 PM
Edited Feb 17, 2011 at 9:19 PM

Once more many thanks. Now it works.

BTW I suppose I can use from my module(s) Orchard's Authorization and Authentication?

And just to be sure, when browsing to an MVC site: first the system hits the (action code in the) Controller (not the View) and then the (code in the) Controller starts the View? Since that means that when integrating a Silverlight App in a cshtml file that first I have to hit an action of the Controller that only starts the View (so at that moment no database access or wcf access in that controller-action) that's hosting the Silverlight App (because when your try to return at that moment eg database records to the view that's hosting the Silverlight App there's no way to provide this info to the Silverlight App) . And after that the Silverlight can take control and initiate in REST-ful way actions in the Controller?

Thanks.


Feb 17, 2011 at 10:01 PM

Since I develop the Silverlight Apps in separate projects (outside of the Orchard code), its boring everytime having the cycle development -> uploading in Orchard -> Testing ... but it works that's the most important.

 Cheers