Windows Dev Center

Guidelines for creating custom data formats

Users share a variety of information when they're online. Successful apps take the time to analyze the types of information that users are most likely to share with others, and package that information so that the receiving apps can process it correctly. In many cases, the information users want to share falls into one of the six standard formats that Windows supports. However, there are some instances in which having a more targeted data type can create a better user experience. For these situations, your app can support custom data formats.


To illustrate how to think about creating a custom format, consider the following example.

At the fictional company, Fabrikam, a developer writes an app that shares files stored online. One option would be to use stream-backed StorageItems, but that could be time-consuming and inefficient because the target app would end up downloading the files locally to read them. Instead, the developer decides to create a custom format for use with these file types.

First, the developer considers the definition of the new format. In this case, it's a collection of any file type (document, image, and so on) that is stored online. Because the files are on the web instead of the local machine, the developer decides to name the format WebFileItems.

Next, the developer needs to decide on the specifics of the format, and decides on the following:

  • The format should consist of an IPropertyValue that contains an InspectableArray that represents the Uniform Resource Identifiers (URIs).
  • The format must contain at least 1 item, but there is no limit as to how many items it can contain.
  • Any valid URI is allowed.
  • URIs that are not accessible outside of the source application's boundary (such as authenticated URIs) are discouraged.

With this information mapped out, the developer now has enough information to create and use a custom format.

Should my app use custom formats?

The share feature in Windows 10 supports six standard data formats:

  • text
  • HTML
  • bitmap
  • StorageItems
  • URI
  • RTF

These formats are very versatile, which makes it easy for your app to quickly support sharing and receiving shared content. The drawback to these formats is that they don't always provide a rich description of the data for the receiving app. To illustrate this, consider the following string, which represents a postal address:

1234 Main Street, New York, NY 98208

An app can share this string using DataPackage.setText. But because the app that receives the text string won't know exactly what the string represents, it is limited in what it can do with that data. By using a custom data format, the source app can define the data being shared as a "place" using the format. This gives the receiving app some additional information that it can use to process the information in way the user expects. Using existing schema formats allows your app to hook into a larger database of defined formats.

Custom formats can also help you provide more efficient ways of sharing data. For example, a user has a collection of photos stored on Microsoft OneDrive, and decides to share some of them on a social network. This scenario is tricky to implement using the standard formats, for a few reasons:

  • You can only use the URI format to share one item at a time.
  • OneDrive shares collections as stream-backed StorageItems. Using StorageItems in this scenario would require that your app download each picture, and then share them.
  • Text and HTML let you provide a list of links, but the meaning of those links is lost—the receiving app won't know that these links represent the pictures the user wants to share.

Using an existing schema format or a custom format to share these pictures provides two main benefits:

  • Your app can share the pictures faster, because you could create a collection of URIs, instead of downloading all the images locally.
  • The receiving app would understand that these URIs represent images, and could process them accordingly.

Dos and don'ts

Defining a custom format

If you decide that your app can benefit from defining a custom format, there are a few things you should consider:

  • Be sure you understand the standard data formats, so you don't create a custom format unnecessarily. You should check to see if there is an existing format on that would suit your scenario. It is more likely that another app would use an existing format over your custom format, which means that a greater audience could achieve your desired end-to-end scenarios.
  • Consider the experiences you want to enable. It's important that you think about what actions your users want to take, and what data format best supports those actions.
  • Make the definition of your custom format available to other app developers.
  • When naming your format, make sure the name matches the contents of the format. For example, UriCollection indicates that any URI is valid, while WebImageCollection indicates that it contains only URIs that point to online images.
  • Carefully consider the meaning of the format. Have a clear understanding of what the format represents and how it should be used.
  • Review the structure of the format. Think through whether the format supports multiple items or serialization, and what limitations the format has.
  • Don't change your custom format after you publish it. Consider it like an API: elements might get added or deprecated, but backward-compatibility and long-term support are important.
  • Don't rely on format combinations. For example, don't expect an app to understand that if sees one format, it should also look for a second format. Each format must be self-contained.

Adding custom formats to your app

After you define a custom format, follow these recommendations when adding the format to your app:

  • Test the format with other apps. Make sure that the data is processed correctly from the source app to the target app.
  • Stick to the intended purpose of the format. Don't use it in unintended ways.
  • If you're writing a source app, provide at least one standard format as well. This ensures that users can share data with apps that don't support the custom format. The experience may not be as ideal for the user, but it is better than not letting them share data with the apps they want. You should also document your format online so that other applications can know to adopt it.
  • If you're writing a target app, consider supporting at least one standard format. This way, your app can receive data from source apps—even if they don't use the custom format you prefer.
  • If you want to accept a specific custom format from another app, particularly one from a different company, you should double-check to see that it is documented publicly online. Undocumented formats are more likely to change without notice, potentially creating inconsistencies or breaking your app.

Additional usage guidance

Choosing a data type

One of the most important decisions you’ll make when defining a custom format is the WinRT data type used for transferring it between source and target applications. The DataPackage class supports several data types for a custom format:

When defining a format, select the type appropriate for that data. It is very important that all consumers and recipients of this format use the same data type—even if there are different options—otherwise it may lead to unexpected data type mismatch failures in target applications.

If you choose string as the data type for your format, you can retrieve it on the target side using the GetTextAsync(formatId) form of the GetTextAsync function. This function performs data-type checking for you. Otherwise, you have to use GetDataAsync, which means you must protect against potential data-type mismatches. For example, if a source application provides a single URI, and the target attempts to retrieve it as a collection of URIs, a mismatch occurs. To help prevent these collisions, you can add code similar to this:

Populating the DataPackage

var uris = new Array();
uris[0] = new Windows.Foundation.Uri("");
uris[1] = new Windows.Foundation.Uri("");
var dp = new Windows.ApplicationModel.DataTransfer.DataPackage();
dp.setData("UriCollection", uris);

Retrieving the data

if (dpView.contains("UriCollection")) {
    dpView.getDataAsync("UriCollection").done(function(uris) {
        // Array.isArray doesn’t work – uris is projected from InspectableArray
        if (uris.toString() === "[object ObjectArray]") {
            var validUriArray = true;
            for (var i = 0; (true === validUriArray) && (i < uris.length); i++) {
                validUriArray = (uris[i] instanceof Windows.Foundation.Uri);
            if (validUriArray) {
                // Type validated data 

Related topics

For developers (HTML)
Choosing data formats for sharing
Quickstart: Sharing content
Quickstart: Receiving shared content
For developers (XAML)
Choosing data formats for sharing
Quickstart: Sharing content
Receiving shared content
Sharing content source app sample
Sharing content target app sample



© 2015 Microsoft