NEW!
CSHTML5 has now become OpenSilver!

We are happy to announce that CSHTML5 has been significantly improved and rebranded to 'OpenSilver', which stands for 'Open-source reimplementation of Silverlight'. It is fully backward compatible and it can be downloaded from OpenSilver.net. Upgrading from CSHTML5 to OpenSilver is very easy.
Read the FAQ

Manually Migrate Silverlight/WPF apps to HTML5 using CSHTML5
Silverlight/WPF Manual Migration Guide

 

Note: This page is for "do-it-yourself" migrations. Alternatively, you can hire us to do the full migration for you, and save on licensing costs and more. Learn More

Table of Contents

- Introduction

- What is "C#/XAML for HTML5" exactly and how does the migration work

- You keep coding in C#/XAML

- Differences between a Silverlight/WPF project and a CSHTML5 project

- Main steps for migrating a Silverlight/WPF application

- Deploying the produced app

- Topics of interest

- Support and Assistance

 

Introduction

If you have a Silverlight application, chances are that you are looking for a way to migrate it to other technologies. In fact, Chrome, Edge, and mobile browsers have stopped supporting it long ago, and FireFox has also stopped supporting it in March 2017.

If your app targets only Windows-based devices, and if deployment is not an issue for you, you may consider migrating your application to WPF or UWP. However, if you want your app to run in the browser, or if you want to reach more platforms, you will likely find C#/XAML for HTML5 a compelling choice.

In fact, C#/XAML for HTML5 is the only solution that lets you reuse most of your SL code, keep coding in a Silverlight-like way, and at the same time generate cross-platform HTML5-based apps. Your apps run on any modern browser, without the user installing any plugins, and you can even package them for deployment on iOS and Android via PhoneGap/Cordova, as well as other devices such as Chromebooks, Macs, and Linux-based devices.

What is "C#/XAML for HTML5" exactly, and how does the migration work

C#/XAML for HTML5 (also called "CSHTML5") is an extension for Visual Studio that adds a new kind of project to the "New Project" dialog. This new kind of project is called a "CSHTML5 Project".

Screenshot of Silverlight Migration Edition project templates

A CSHTML5 project is very similar to a Silverlight/WPF project, in that it contains mainly C# and XAML files. For example, a blank new CSHTML5 project is almost identical to a blank new Silverlight/WPF project: it contains App.xaml, App.xaml.cs, MainPage.xaml, and MainPage.xaml.cs.

The main difference between a Silverlight/WPF project and a CSHTML5 project is that the Silverlight project outputs a "XAP" file (or "EXE" file in case of WPF), whereas the CSHTML5 project outputs HTML and JavaScript files.

Therefore, the general idea for migrating a Silverlight/WPF application into cross-platform HTML5 is the following:

  1. You start by creating a new empty "CSHTML5 Project",

  2. You then copy all your C#/XAML files from your Silverlight/WPF project into the new CSHTML5 project,

    UPDATE: a "Silverlight Migration Wizard" is now available to help you create the projects and copy the files. It can be launched from the Tools menu of Visual Studio. Please note that a lot of manual work is still required to migrate a Silverlight application.

    The migration wizard can be launched from the Tools menu of Visual Studio.

  3. You then patch the code until it compiles and runs fine,

  4. And then, every time you build the CSHTML5 project, the compiler generates the final cross-platform HTML and JavaScript files. Those files are auto-generated, so you are not expected to modify them manually (read the section below titled "You keep coding in C#/XAML"). Furthermore, the produced files are self-contained - meaning that they have no dependencies - which means that they can be redistributed very easily, or deployed to any server (read the section below about deployment).

Keep reading for more information and a detailed tutorial.

You keep coding in C#/XAML

With CSHTML5, the transformation of a Silverlight/WPF app into HTML5/JavaScript is not a one-time irreversible operation where you would do a one-time transformation of your C#/XAML code into a set of HTML/JS files, then throw away the C#/XAML code, and keep working in HTML/JS. Instead, CSHTML5 allows you to keep working and maintaining your code in C#/XAML. You never need to modify the generated HTML/JS code manually. 

This approach has several benefits:

  • You can keep leveraging the existing C#/XAML/.NET/VS skills of your team members, instead of forcing them to move to other languages, frameworks, and/or IDE.
  • You can share C# code between the client and the server. This is particularly useful for sharing business objects and entities passed between the client and the server. You can share code using the "Add as link" feature of Visual Studio, and write compiler directives to conditionally comment out portions of the code that are not supported in CSHTML5.

    (Tip: you can use the "Add Service Reference" feature of WCF in a CSHTML5 project. If you do that, as mentioned in the WCF and WebClient Limitations and Tutorials, you need to implement CORS in case of cross-domain communication)
  • You can keep leveraging the power of the C# and XAML languages (type safety, viewmodels, user controls, generics, datatemplates, async/await, namespaces, accessibility modifiers, exception handling, etc.), a subset of the .NET classes (WCF, Linq, etc.), and the powerful Visual Studio IDE (refactoring, debugging, intellisense, source control, snippets, immediate window, code analysis, etc.). Those languages and tools were designed since the beginning to enable the creation of large-scale enterprise-grade rich applications.
  • You can share C# files between the original Silverlight/WPF project and the migrated CSHTML5 project (using the "Add as link" feature of Visual Studio, and compiler directives to specialize portions of the code). This is particularly useful if you would like to keep - at least for a short period of time - both the migrated version AND the original version of your app, in order for example to go to market faster by not having to migrate the whole application at once, or if you want to keep the old application available for a while to at least some kind of users (eg. administrators).

Differences between a Silverlight/WPF project and a CSHTML5 project

There are a few differences between a Silverlight/WPF project and a CSHTML5 project in terms of supported features. Although CSHTML5 is a mature product and is already being used in production, it still only supports a subset of the Silverlight/WPF features (see also the list of limitations). For example, at the moment, you will not be able to use the same 3D rendering API's provided by Silverlight 5 (note: there are JS-based alternatives that can be used in CSHTML5, such as three.js), and neither will you be able to communicate directly with RIA Services (note: you can workaround this limitation by creating SOAP web services - read below for details). Furthermore, due to the fact that a CSHTML5 project can only reference CSHTML5-compatible assemblies - similarly to how a Silverlight project that only reference Silverlight-compatible assemblies -, you will not be able to use 3rd party Silverlight components unless an equivalent CSHTML5-compatible version of the component is made, or an equivalent JavaScript-based library is found (note: with CSHTML5, you can easily call a JS-based library from your C# code). A growing number of 3rd party libraries are being released for CSHTML5.

Note: if you share code between a Silverlight/WPF project and a CSHTML5 project - for example using the "Add as link" feature of Visual Studio-, you will find it useful to know that you can specialize portions of the code by using Compiler Directives (also called Preprocessor Directives), like in the following example:

     #if CSHTML5 
        using Windows.UI.Xaml.Controls;
    #else
        using System.Windows.Controls; //Silverlight or WPF
    #endif

Main steps for migrating a Silverlight/WPF application

Assuming that you have already downloaded and installed CSHTML5, the main steps to migrate a Silverlight/WPF application are the following:

  1. Create one project of type "C#/XAML for HTML5 (Silverlight Migration Edition)" for each of the Silverlight/WPF projects that you want to migrate.

    For example, if your solution has two projects: "MyApplication" and "MyClassLibrary", you should create two separate new projects: one project of type "(Silverlight Migration Edition) Empty Application", and another project of type "(Silverlight Migration Edition) Empty Class Library".

    Screenshot of Silverlight Migration Edition project templates

    In this tutorial, let's assume that you have given the following name to your new CSHTML5 projects: "MyApplication.Cshtml5" and "MyClassLibrary.Cshtml5".

  2. Copy/paste all the C#/XAML files contained in your Silverlight/WPF projects into the newly-created CSHTML5 projects (with the exception of "App.xaml" and "App.xaml.cs", which you may want to merge manually).

    To ensure that the folders structure is preserved, a technique is to open Windows Explorer, select all the files and folders contained in a project (with the notable exception of the folders "bin", "obj", "Properties", and the files "App.xaml" and "App.xaml.cs", which you may want to merge manually), then copy them to the clipboard (by pressing Ctrl+C), then go to Visual Studio, select the CSHTML5 destination project in the Solution Explorer panel, and press Ctrl+V. This will paste all the files into the selected project, while recreating the folders structure.

    Alternatively, instead of copying the files (which will result in redundant duplicates), you can share the files between the Siverlight projects and the CSHTML5 projects. To do so, you can use the "Add as link" feature of Visual Studio: right-click on the destination CSHTML5 project, click "Add => Existing Item...", browse to the original Silverlight/WPF project, select the C# files, and then click "Add as link..." (if you do not know where the "Add as link" button is, look at the screenshots here).
    A few notes though:
     - If you share files, you need to manually recreate the folders structure, because you cannot share entire "folders" in Visual Studio
     - In the current version of CSHTML5, you are encouraged to share C# files, but not to share XAML files, because XAML files do not let you write "compiler directives" to specialize portions of the code, so it may not be practical to adapt the XAML code to CSHTML5 while maintaining compatibility with the original Silverlight/WPF XAML code.

    UPDATE: a "Silverlight Migration Wizard" is now available to help you create the projects and copy the files. It can be launched from the Tools menu of Visual Studio. Please note that a lot of manual work is still required to migrate a Silverlight application.

    The migration wizard can be launched from the Tools menu of Visual Studio.

  3. Make it so that the new projects reference each other in the same way that your Silverlight/WPF projects reference each other.

    For example, if "MyApplication" references "MyClassLibrary", you should make it so that "MyApplication.Cshtml5" references "MyClassLibrary.Cshtml5".

  4. Try compiling your CSHTML5 project and fix the code until it compiles properly.

    If your solution contains multiple projects, instead of trying to compile the whole solution at once (which may result in an unmanageable number of errors), it is recommended that you start by attempting to compile only the smallest projects that have no dependencies (ie. the projects that do not reference other projects). Once you are able to compile those projects, you can move on to attempting to compile larger projects or projects that have more dependencies. Usually, you start with the class libraries, and the main application project is the last one that you attempt to compile, after everything else compiles properly.

    As you attempt to compile the projects, you will likely get some errors, some of which can be fixed easily:
    - You can do a find-and-replace in the whole project to replace "HashSet<" with "HashSet2<" with "HashSet2<" (this is a limitation of the current version that is expected to be fixed in the future).

    Other incompatibilities may require more work to be fixed. Therefore, if you can temporarily disable a feature that is not supported, or comment out a piece of code that is not compatible, it is strongly recommended that you do so at this stage, in order to move on and to start testing the application as early as possible in the migration process. You can come back to address the issue after every else works fine. For example, if you can initially comment out some ControlTemplates (located in your XAML styles) without loosing core functionality in your application, it is strongly recommended that you do so. In fact, ControlTemplates may use complex animations or visual states that need to be migrated, so it may be a good idea to postpone their migration to a later phase. After you have managed to get your application to run fine, you can come back and uncomment the ControlTemplates one by one.e ControlTemplates one by one.

    If you find yourself in a situation where a feature is not supported, here are some things that you can do:
    - First, see if you can find an easy workaround by replacing the piece of code with another piece of code that leads to the same result
    - Otherwise, if the missing feature is a core .NET feature, you can implement it yourself in JavaScript (because the core .NET features are located in the open-source JSIL libraries that are copied to the output folder) or ask the CSHTML5 community or the CSHTML5 Support to implement it for you.

    If you find yourself in a situation where a feature is missing (such as "RadColorPicker" in v1.0), instead of changing every piece of code that uses that control, you can add a "fake" class named "RadColorPicker" so that the rest of your code compiles properly. This is a sort of "stub" that is used temporarily to move on in the migration process. The general idea is that, instead of changing the code that requires a missing feature, you can add new classes that will "fake" the said feature. In the implementation of those classes, you can display a message such as MessageBox("This feature is not yet supported");

    If an important feature is missing, such as a 3rd party control, you can either:
    - Implement it in C#/XAML
    - Implement it in JavaScript or use an existing JavaScript library that does the job (see how to call JavaScript from C#)
    - Ask the author of the 3rd party control, or ask the CSHTML5 community, or ask the CSHTML5 Support to implement it for you.

    A few more tips:
    - In the current version, the XAML designer sometimes causes some incorrect errors to be displayed in the Errors panel of Visual Studio. To make sure that you only see the "real" errors, make sure to close all the open XAML designer tabs before compiling the project.
    - It is usually better to fix the XAML errors before fixing the C# errors because the errors displayed for C# files are accurate only after the XAML files compile properly.

    Be sure to read the Limitations and Known Issues page.

  5. After your CSHTML5 project(s) compile properly, you can finally launch the application to ensure that it runs properly.

    At the beginning, you may see some differences in the layout due to the HTML5 rendering engine.

    You can use the Simulator (which appears when you launch the CSHTML5 application) to do step-by-step debugging in your C# code, and you can use the "Inspect Visual Tree" feature of the Simulator to understand where the differences originate from.

    After you have managed to get the application to run fine in the Simulator, you should test it in the web browser. To do so, click the "Run in browser" button that is in the Simulator.

    You can test on different browsers to ensure that the result is the same on all browsers. The browser that has been tested the most with CSHTML5 is Chrome, but other browsers such as Edge, FireFox, and Safari are also supported and should provide the exact same result.

    When first testing in the browser, you may see some differences compared to the Simulator. Those are not supposed to exist, so you should inform the CSHTML5 Support for fixing. In the current version, the most common things that may cause a difference between the result in the Simulator and the result in web browsers are:
    - Client/server communications and WCF: this may be related to cross-domain calls, which are limited when running in the browser. You can open the browser Console log (F12) to see any error messages. You can fix cross-domain issues by implementing CORS.
    - Linq: some rare features of Linq are not yet supported in the browser. You will see an error in the browser "Console" if you use an unsupported feature.

    If you get any errors while running in web browsers, you can open the Developer Tools of the web browser to read the "Console Log" to see what causes the error. To get more information about a JavaScript error, such as the Stack Trace, which is critical to see the current line of execution in your application code (rather than only seeing the line of JS library code that raised the exception), you should use the "Break on exceptions" option, as explained in the Tips for debugging JavaScript errors with chrome (the tips are similar for other browsers). A common practice is also to blackbox the JSIL scripts so that, when you do step-by-step debugging in the browser, you only step into your own methods and skip the JS libraries. Also, be sure to read the Common Issues and Solutions page for a list of common JavaScript errors and their solution. If you find other JavaScript errors that do not show up in the Simulator, please contact the CSHTML Support.

Deploying the produced app

The files that are generated by CSHTML5 are plain static HTML and JavaScript files, which means that they have the following features:

  • No dependencies. The files are self-contained. They are made of pure HTML and JavaScript code that does not rely on any frameworks (not even jQuery).
  • Pure client-side. Just like Silverlight and WPF, CSHTML5 apps are client-only, meaning that all the code runs on the client machine. Communication with the server is done via web service calls (like in Silverlight). When the client web browser navigates to the place where the HTML/JavaScript files are located, those files are downloaded by the browser into its cache, and the code is executed locally on the client. The produced apps are SPA ("Single Page Application"), which means that there is only one "host" HTML page (though multiple XAML pages may be contained in the app).
  • Static files. No server technology is required to serve the files to the client. There is no need for ASP, PHP, Python, or any other server-side technology. Because the files are pure static HTML/JavaScript files, they can be put on any web server.
  • Compatible with most browsers. The files will run on Chrome, Edge, Firefox, Safari, IE11+, and more.

To deploy your application, you have many choices:

  • Give the HTML and JavaScript files to the end-users. In fact, thanks to the fact that they have no external dependencies, the files can be run even from the local file system, by simply launching the file "index.html" from Windows Explorer without any server at all.

    Note: some browsers, for security reasons, may disable some features - such as Geolocalization or IsolatedStorage - when the files are run from the local file system (ie. when the URL in the browser address bar starts with "file:///..." instead of "http//" or "https://"). During development, this can be easily fixed by uploading the files to a web server, or by using the built-in "Run from localhost" feature of the CSHTML5 Simulator (you will find the "Run from localhost" option by clicking the small arrow located near the "Run in browser" button of the Simulator).
  • Upload the HTML and JavaScript files to a web server and give its URL to the end-users. As mentioned earlier, there are no particular server requirements, because the files are static and have no external dependencies.
  • Package the HTML and JavaScript files into an executable. You can easily make an executable out of your HTML/JavaScript files. You can make executables for Windows, macOS, Linux, and more. For more information, refer to the "Out Of Browser" chapter below.
  • Package the HTML and JavaScript files into an application for iOS (iPhone, iPad, iPod Touch) and Android. To do so, you can use tools such as Apache Cordova or PhoneGap Build (the latter does not require a Mac). More details can be found here.

Topics of interest:

  • Client/server communications
    You can communicate with the server via Web Service calls. CSHTML5 is a client-only technology, similar to Silverlight but without the need for browser plugins. A subset of WCF is supported. You can use the "Add Service Reference" feature of VS to communicate with SOAP web services, or you can use the WebClient control to communicate with REST web services (WebAPI or other). Learn more by reading the WCF Limitations and Tutorials. Alternatively, you can communicate via WebSockets by using the open-source WebSocket extension for CSHTML5, or via SignalR.
  • RIA Services
    Due to the fact that RIA Services are not supported at this time, you should replace them with standard WCF SOAP service calls (read WCF and WebClient Limitations and Tutorials). To make the migration easier, a common practice is to create a new server-side project of type "WCF Service Application" that references your server-side RIA Service and functions as an "adapter" (or "bridge") that will relay the communications between your CSHTML5 app and your RIA Service. In other words, instead of communicating directly with the RIA Service, your CSHTML5 application will communicate with your WCF service - which exposes SOAP endpoints -, and the latter will then communicate with your RIA Service via simple method calls (because they run in the same process on the server). We recommend redefining the business entities that are passed between the client and the server if they are too complex or if they have dependencies on EntityFramework (which is currently not supported).
  • DataBinding
    It works exactly as in Silverlight. To see some examples and source code, check out the sample Showcase application (to do so, launch VS, click File => New Project => C#/XAML for HTML5 => Sample Showcase).
  • Styling, Templating, and Custom Templated Controls
    Styling works exactly as in Silverlight. Please visit the Styles and Templates page for some examples of styles.
  • Accessing a database
    Accessing a database works the same as in Silverlight partial-trust: it is done on the server-side, not the client-side, because the "Connection String", which includes the URL and password of the database, should not be visible to the end-user. The client-side (ie. the CSHTML5-based front-end) communicates with the server (for example an ASP.NET / WCF Service application) via SOAP, REST, WebSockets, SignalR, or other. Please read the section "Client/server communications" above for more information. For an example of database access, please read the page Accessing a database
  • Saving a file to disk
    You can easily save/download a file to the end-user computer by using the open-source FileSaver library for CSHTML5. Some web browsers will display a window similar to the Silverlight SaveFileDialog for choosing the file name and destination folder, while other browsers will simply download the file to the Downloads folder.
  • Opening a file from disk
    You can use the open-source FileOpenDialog library for CSHTML5.
  • Serializing/Deserializing
    You can serialize/deserialize objects using the built-in DataContractSerializer class
  • Printing
    You can print any UIElement in the visual tree using the built-in Printing Features, or, alternatively, using the open-source PrintHelper library for CSHTML5.
  • Compressing/Decompressing
    You can use the open-source ZipFile library for CSHTML5, which provides a subset of the functionalities of Ionic.Zip DotNetZip.
  • Out Of Browser support
    Out Of Browser is useful for many reasons, including the ability to run code that requires Elevated Privileges ("Full Trust"), for example to communicate with USB ports, to interact with installed apps (Office Automation/Interop...), to access restricted folders on the File System, and, more generally, to do anything that you are not allowed to do inside the web browser. There are multiple ways to implement Out Of Browser support for CSHTML5 applications. A common way is to take the output HTML/JS files of your application and make a Windows/Mac/Linux executable out of them. You will find many free tools to do that. Alternatively, you can do this manually by following these simple steps: create a new project of type "WPF application", put a web browser control on the MainWindow (you can either use the default IE-based WebBrowser control, which uses the same version of IE that is installed on the end-user machine, or, better, you can use the CEFSharp control which contains an embedded Chromium browser that has no dependencies and that renders the same on all the machines regardless of what web browser is installed) and add some code to the constructor of your MainWindow to make the web browser URL point to your local HTML/JS files generated by your CSHTML5 project. This technique has several benefits, including the ability to move C#/XAML code that requires Elevated Provileges directly into the WPF application, and then to have your CSHTML5 application communicate with the "host" WPF application via simple JS interop calls.

Support and Assistance

For Silverlight/WPF migration projects, we offer 4 types of support:

  • Bug Fixes: they are resolved free of charge, usually in 3 to 10 business days depending on the complexity of the bug.
  • Custom Developments to accelerate the implementation of missing features. This is the most popular form of support, as more than a hundred features have been developed in the past thanks to companies willing to contribute to accelerate the development of those features. If you need a specific feature to be implemented, and you do not want to implement it on your side (in C# or via C#/JS interop), we can send you an estimation of the cost to have us implement it for you. If the feature is a highly requested feature, we can split the development cost 50/50. Customers have been very happy with the short delivery times and high quality of the results.
  • Analysis of your codebase: we can analyse your application under NDA to report the differences between your current functionality and our implementation/future roadmap. Please contact us if you are interested.

 

To contact us, please follow this link.

Tickets are usually replied to within 24-48 hours. The support team speaks English, French, and Italian.