{"id":110085,"date":"2024-08-01T07:00:00","date_gmt":"2024-08-01T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=110085"},"modified":"2024-08-01T10:35:10","modified_gmt":"2024-08-01T17:35:10","slug":"20240801-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20240801-00\/?p=110085","title":{"rendered":"What&#8217;s the difference between <CODE>Data&shy;Package&shy;View.<WBR>Get&shy;Uri&shy;Async<\/CODE> and <CODE>Data&shy;Package&shy;View.<WBR>Get&shy;Web&shy;Link&shy;Async<\/CODE>?"},"content":{"rendered":"<p>The Windows Runtime <code>Data\u00adPackage<\/code> object has methods for manipulating three types of URIs:<\/p>\n<table class=\"cp3\" style=\"border-collapse: collapse;\" border=\"1\" cellspacing=\"0\" cellpadding=\"3\">\n<tbody>\n<tr>\n<th><tt>Standard\u00adData\u00adFormats<\/tt> value<\/th>\n<th><tt>Data\u00adPackage<\/tt> method<\/th>\n<th><tt>Data\u00adPackage\u00adView<\/tt> method<\/th>\n<\/tr>\n<tr>\n<td><code>Uri<\/code><\/td>\n<td><code>Set\u00adUri<\/code><\/td>\n<td><code>Get\u00adUri\u00adAsync<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>Web\u00adLink<\/code><\/td>\n<td><code>Set\u00adWeb\u00adLink<\/code><\/td>\n<td><code>Get\u00adWeb\u00adLink\u00adAsync<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>Application\u00adLink<\/code><\/td>\n<td><code>Set\u00adApplication\u00adLink<\/code><\/td>\n<td><code>Get\u00adApplication\u00adLink\u00adAsync<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>What do the three different URIs mean, and how do they differ?<\/p>\n<p>Once upon a time, there was only one URI data format. And it was called <code>Uri<\/code>.<\/p>\n<table class=\"cp3\" style=\"border-collapse: collapse;\" border=\"1\" cellspacing=\"0\" cellpadding=\"3\">\n<tbody>\n<tr>\n<th><tt>Standard\u00adData\u00adFormats<\/tt> value<\/th>\n<th><tt>Data\u00adPackage<\/tt> method<\/th>\n<th><tt>Data\u00adPackage\u00adView<\/tt> method<\/th>\n<\/tr>\n<tr>\n<td><code>Uri<\/code><\/td>\n<td><code>Set\u00adUri<\/code><\/td>\n<td><code>Get\u00adUri\u00adAsync<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Windows 8.1 added a second URI data format called <code>Application\u00adLink<\/code>, 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 <code>Application\u00adLink<\/code> that is a link into the Contoso app that navigates to that customer service record.<\/p>\n<p>Since we now had two URI data formats, it was confusing to have a data format named simply <code>Uri<\/code>, so the old <code>Uri<\/code> format was renamed to <code>Web\u00adLink<\/code>.<\/p>\n<table class=\"cp3\" style=\"border-collapse: collapse;\" border=\"1\" cellspacing=\"0\" cellpadding=\"3\">\n<tbody>\n<tr>\n<th>Data format<\/th>\n<th>Meaning<\/th>\n<\/tr>\n<tr>\n<td><code>WebLink<\/code><\/td>\n<td>Link to Web resource.<\/td>\n<\/tr>\n<tr>\n<td><code>ApplicationLink<\/code><\/td>\n<td>Link to app to view the item.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>For backward compatibility, we still have to support the old unfashionable API, but <code>Uri<\/code> is just an alternate name for <code>Web\u00adLink<\/code>. The <code>Uri<\/code> data format is identical to the the <code>Web\u00adLink<\/code> data format. The <code>Set\u00adUri<\/code> method does exactly the same thing as the <code>Set\u00adWeb\u00adLink<\/code> method. The <code>Get\u00adUri\u00adAsync<\/code> method does exactly the same thing as the <code>Get\u00adWeb\u00adLink\u00adAsync<\/code> method.<\/p>\n<p>For example, if an app uses <code>Set\u00adUri<\/code> to set a URI, and you then call <code>Get\u00adUri\u00adAsync<\/code>, it will produce that same URI. The <code>Uri<\/code> and <code>Web\u00adLink<\/code> are literally the same thing.<\/p>\n<p>Our final table therefore is<\/p>\n<table class=\"cp3\" style=\"border-collapse: collapse;\" border=\"1\" cellspacing=\"0\" cellpadding=\"3\">\n<tbody>\n<tr>\n<th><tt>Standard\u00adData\u00adFormats<\/tt> value<\/th>\n<th><tt>Data\u00adPackage<\/tt> method<\/th>\n<th><tt>Data\u00adPackage\u00adView<\/tt> method<\/th>\n<\/tr>\n<tr>\n<td><code>Uri<\/code><br \/>\n<code>Web\u00adLink<\/code><\/td>\n<td><code>Set\u00adUri<\/code><br \/>\n<code>Set\u00adWeb\u00adLink<\/code><\/td>\n<td><code>Get\u00adUri\u00adAsync<\/code><br \/>\n<code>Get\u00adWeb\u00adLink\u00adAsync<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>Application\u00adLink<\/code><\/td>\n<td><code>Set\u00adApplication\u00adLink<\/code><\/td>\n<td><code>Get\u00adApplication\u00adLink\u00adAsync<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The fact that <code>Uri<\/code> and <code>Web\u00adLink<\/code> are identical means that your program doesn&#8217;t have to try to handle both. Just decide which name you want to use for the format (either <code>Uri<\/code>, the OG name; or <code>Web\u00adLink<\/code>, the hip new name), and use it.<\/p>\n<pre>namespace winrt\r\n{\r\n    using namespace winrt::Windows::Foundation::Uri;\r\n    using namespace winrt::Windows::ApplicationModel::DataTransfer;\r\n}\r\n\r\nwinrt::Uri TryGetUri(winrt::DataPackageView const&amp; view)\r\n{\r\n    if (view.Contains(StandardDataFormats::ApplicationLink())) {\r\n        return co_await dataPackageView.GetApplicationLinkAsync();\r\n    } else if (view.Contains(StandardDataFormats::WebLink())) {\r\n        return co_await dataPackageView.GetWebLinkAsync();\r\n    } else if (view.Contains(StandardDataFormats::Uri())) {\r\n        return co_await dataPackageView.GetUriAsync();\r\n    }\r\n    return nullptr;\r\n}\r\n<\/pre>\n<p>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&#8217;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&#8217;s not available, then it looks for a Uri (also to view the content in a Web browser).<\/p>\n<p>But the last test is redundant because <code>Web\u00adLink<\/code> and <code>Uri<\/code> are the same thing. If a <code>Uri<\/code> is present, then <code>Contains(WebLink)<\/code> will find it. The test for <code>Uri<\/code> is dead code.<\/p>\n<p>It&#8217;s like taking attendance in a class, and there&#8217;s a student whose name is Joseph, but he also uses the nickname Joe. If you ask, &#8220;Is Joseph here?&#8221;, and there is no answer, then there&#8217;s no point asking, &#8220;Is Joe here?&#8221; because Joe and Joseph are the same person. There will never be a response to &#8220;Is Joe here?&#8221;<\/p>\n<p>So once we know that Joseph isn&#8217;t in the data package, there&#8217;s no point asking if Joe is in it.<\/p>\n<pre>winrt::Uri TryGetUri(winrt::DataPackageView const&amp; view)\r\n{\r\n    if (view.Contains(StandardDataFormats::ApplicationLink())) {\r\n        return co_await dataPackageView.GetApplicationLinkAsync();\r\n    } else if (view.Contains(StandardDataFormats::WebLink())) {\r\n        return co_await dataPackageView.GetWebLinkAsync();\r\n    \/\/ <span style=\"border: dashed 1px currentcolor; border-bottom: none;\"><span style=\"text-decoration: line-through;\">} else if (view.Contains(StandardDataFormats::Uri())) {<\/span><\/span>\r\n    \/\/ <span style=\"border: dashed 1px currentcolor; border-top: none;\"><span style=\"text-decoration: line-through;\">    return co_await dataPackageView.GetUriAsync();     <\/span><\/span>\r\n    }\r\n    return nullptr;\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Just improving on an ambiguous name.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-110085","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Just improving on an ambiguous name.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/110085","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=110085"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/110085\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=110085"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=110085"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=110085"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}