August 1st, 2024

What’s the difference between Data­Package­View.Get­Uri­Async and Data­Package­View.Get­Web­Link­Async?

The Windows Runtime Data­Package object has methods for manipulating three types of URIs:

Standard­Data­Formats value Data­Package method Data­Package­View method
Uri Set­Uri Get­Uri­Async
Web­Link Set­Web­Link Get­Web­Link­Async
Application­Link Set­Application­Link Get­Application­Link­Async

What do the three different URIs mean, and how do they differ?

Once upon a time, there was only one URI data format. And it was called Uri.

Standard­Data­Formats value Data­Package method Data­Package­View method
Uri Set­Uri Get­Uri­Async

Windows 8.1 added a second URI data format called Application­Link, so that apps could add a link that relaunched the app to return to the item that was copied. For example, if the Contoso app copies a customer service record to the clipboard, it can add an Application­Link that is a link into the Contoso app that navigates to that customer service record.

Since we now had two URI data formats, it was confusing to have a data format named simply Uri, so the old Uri format was renamed to Web­Link.

Data format Meaning
WebLink Link to Web resource.
ApplicationLink Link to app to view the item.

For backward compatibility, we still have to support the old unfashionable API, but Uri is just an alternate name for Web­Link. The Uri data format is identical to the the Web­Link data format. The Set­Uri method does exactly the same thing as the Set­Web­Link method. The Get­Uri­Async method does exactly the same thing as the Get­Web­Link­Async method.

For example, if an app uses Set­Uri to set a URI, and you then call Get­Uri­Async, it will produce that same URI. The Uri and Web­Link are literally the same thing.

Our final table therefore is

Standard­Data­Formats value Data­Package method Data­Package­View method
Uri
Web­Link
Set­Uri
Set­Web­Link
Get­Uri­Async
Get­Web­Link­Async
Application­Link Set­Application­Link Get­Application­Link­Async

The fact that Uri and Web­Link are identical means that your program doesn’t have to try to handle both. Just decide which name you want to use for the format (either Uri, the OG name; or Web­Link, the hip new name), and use it.

namespace winrt
{
    using namespace winrt::Windows::Foundation::Uri;
    using namespace winrt::Windows::ApplicationModel::DataTransfer;
}

winrt::Uri TryGetUri(winrt::DataPackageView const& view)
{
    if (view.Contains(StandardDataFormats::ApplicationLink())) {
        return co_await dataPackageView.GetApplicationLinkAsync();
    } else if (view.Contains(StandardDataFormats::WebLink())) {
        return co_await dataPackageView.GetWebLinkAsync();
    } else if (view.Contains(StandardDataFormats::Uri())) {
        return co_await dataPackageView.GetUriAsync();
    }
    return nullptr;
}

The above example decides that it wants to prefer the application link (which takes the user back to the app that provided the data package), and if that’s not available, then it sees if the data package contains a Web link (to view the content in a Web browser), and if even that’s not available, then it looks for a Uri (also to view the content in a Web browser).

But the last test is redundant because Web­Link and Uri are the same thing. If a Uri is present, then Contains(WebLink) will find it. The test for Uri is dead code.

It’s like taking attendance in a class, and there’s a student whose name is Joseph, but he also uses the nickname Joe. If you ask, “Is Joseph here?”, and there is no answer, then there’s no point asking, “Is Joe here?” because Joe and Joseph are the same person. There will never be a response to “Is Joe here?”

So once we know that Joseph isn’t in the data package, there’s no point asking if Joe is in it.

winrt::Uri TryGetUri(winrt::DataPackageView const& view)
{
    if (view.Contains(StandardDataFormats::ApplicationLink())) {
        return co_await dataPackageView.GetApplicationLinkAsync();
    } else if (view.Contains(StandardDataFormats::WebLink())) {
        return co_await dataPackageView.GetWebLinkAsync();
    // } else if (view.Contains(StandardDataFormats::Uri())) {
    //     return co_await dataPackageView.GetUriAsync();     
    }
    return nullptr;
}
Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

2 comments

Discussion is closed. Login to edit/delete existing comments.

  • Ian Horwill

    “For example, if an app uses Set­Uri to set a URI, and you then call Get­Uri­Async, it will produce that same URI.”

    Did you mean to use GetWebLink­Async there to prove the point? Alternatively, you perhaps meant to pair SetWebLink with GetUriAsync?

  • Dmitry

    Hmmm, Biden-related joke 🙂