Bug 54415 - URI properties cannot be specified in XAML as strings
Summary: URI properties cannot be specified in XAML as strings
Status: RESOLVED NOT_ON_ROADMAP
Alias: None
Product: Forms
Classification: Xamarin
Component: Windows ()
Version: 2.3.4
Hardware: PC Windows
: --- normal
Target Milestone: ---
Assignee: Jason Smith [MSFT]
URL:
Depends on:
Blocks:
 
Reported: 2017-04-03 18:13 UTC by Rich Zwaap
Modified: 2017-06-19 21:11 UTC (History)
4 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
Solution and source files containing repro app (96.52 KB, application/x-zip-compressed)
2017-04-03 18:13 UTC, Rich Zwaap
Details
Simple test project (314.81 KB, application/zip)
2017-05-01 20:42 UTC, Jon Goldberger [MSFT]
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED NOT_ON_ROADMAP

Description Rich Zwaap 2017-04-03 18:13:24 UTC
Created attachment 21158 [details]
Solution and source files containing repro app

When a URI property is specified as a string in XAML as follows the XamlParseException is thrown at run time on UWP:

Cannot assign property "<property name>": type mismatch between "System.String" and "System.Uri"

String to URI type conversion is supported in Xamarin Forms XAML for iOS and Android, and has been supported natively by UWP since version 10586.

A test app project that demonstrates the issue is attached.  The key line of XAML in the sample is the following in MapPage.xaml:

<data:ServiceFeatureTable Source="http://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/FeatureServer/0"/>

Here, the ServiceFeatureTable.Source property is of type System.Uri.  This line is parsed without issue in the iOS and Android versions of the app, but fails on UWP.
Comment 1 Stephane Delcroix 2017-04-06 13:09:58 UTC
While assigning a value to a property, the Xaml parser looks for a [TypeConverter] attribute on the target property (here, Source), then on the type (System.Uri) and then check for well-known conversions.

In this case, the Esri.ArcGISRuntime.Mapping.ArcGISTiledLayer.Source property (whatever that is) is attributed with a [TypeConverter(typeof(Esri.ArcGISRuntime.Internal.StringToUriConverter))] but as the name implies, that converter is internal and it's constructor is inaccessible. This is why this is failing.

I don't understand, but I'm no-one to judge, why that property is attributed as System.Uri is already attributed with a [TypeConverter], and the converter is publicly accessible.

You should see that with the owner of that library.

It works on iOS and android, probably because the runtime is a bit more permissive, but for once, the UWP behavior is the right one.
Comment 2 Rich Zwaap 2017-04-07 15:16:41 UTC
This is not resolved.  As you say:

> In this case, the Esri.ArcGISRuntime.Mapping.ArcGISTiledLayer.Source
> property (whatever that is) is attributed with a
> [TypeConverter(typeof(Esri.ArcGISRuntime.Internal.StringToUriConverter))]

That's correct.  We implemented this as a workaround for the lack of an implicit (i.e. built into the API) string to URI type converter on UWP.  As I said, refer to the ServiceFeatureDataTable.Source property (which does not have a TypeConverter defined) for the problematic behavior.  I could have created a reproducer app independent of our API, but this is so straightforward that it seemed like overkill in this case.

> You should see that with the owner of that library.

We are the owner of this library.

> for once, the UWP behavior is the right one.

Sorry, but that's not the correct conclusion.  Native UWP includes built-in string to URI conversion, meaning that, when building a native UWP app, you can specify a property of type System.Uri in XAML as a string.  This was not present in UWP SDK 10240, but has been ever since 10586.  As I understand it, version 10240 will soon be deprecated, if it has not already been with the release of the Creator's Update for Windows.  So there will no longer be any supported version of the UWP SDK that does not provide built-in string to URI conversion.

Xamarin Forms UWP clearly ought to provide the same built-in behavior.  Not only would that be consistent with the underlying UWP platform, but it would also provide cross-platform consistency.  Once it does, we will remove our own string to URI type converters from the URI properties in our API.

Re-opening.
Comment 3 Rich Zwaap 2017-04-07 16:08:07 UTC
I should also add, regarding this:

> that converter is internal and it's constructor is inaccessible. This is
> why this is failing.

It's incorrect that that's the cause of the failuire.  It *is* true that that converter is internal.  However, that works just fine in the example I shared, though it incidentally does fail when XamlCompilation is enabled.  Whether that ought to be the case can be debated, but that's not what's being reported here.

The error thrown at run-time in the example I shared is instead on parse of the ServiceFeatureTable.Source property, and the error message is:

Cannot assign property "<property name>": type mismatch between "System.String" and "System.Uri"

The error very plainly flags up the problem - the types don't match, and there is no type conversion happening between string and URI.
Comment 4 Jon Goldberger [MSFT] 2017-05-01 20:42:16 UTC
Created attachment 21909 [details]
Simple test project

Setting status as confirmed as I can reproduce the issue in a simple test project (attached).

The test project just subclasses a Label adding a Source property of type Uri and then sets that property in XAML using a String. On iOS and Android, no exception is thrown, but on UWP a XAML parse exception is thrown as noted in the bug description. 

It seems odd to me that an implicit type conversion from String to Uri works on Android and iOS but not on UWP. 

## Steps to reproduce using the simple test project

1. Load the attached Simple Test Project into Visual Studio

2. Run the UWP app

Expected result: No XAML parse exception

Actual Result: XAML parse exception:

>Xamarin.Forms.Xaml.XamlParseException was unhandled by user code
> HResult=-2146233088
> Message=Position 8:12. Cannot assign property "Source": Property does not exists, or is not assignable, or mismatching type between value and property
> Source=Xamarin.Forms.Xaml
> StackTrace:
>      at Xamarin.Forms.Xaml.ApplyPropertiesVisitor.SetPropertyValue(Object xamlelement, XmlName propertyName, Object value, Object rootElement, INode node, HydratationContext context, IXmlLineInfo lineInfo)
>      at Xamarin.Forms.Xaml.ApplyPropertiesVisitor.Visit(ValueNode node, INode parentNode)
>      at Xamarin.Forms.Xaml.ElementNode.Accept(IXamlNodeVisitor visitor, INode parentNode)
>      at Xamarin.Forms.Xaml.RootNode.Accept(IXamlNodeVisitor visitor, INode parentNode)
>      at Xamarin.Forms.Xaml.XamlLoader.Load(Object view, String xaml)
>      at Xamarin.Forms.Xaml.Extensions.LoadFromXaml[TXaml](TXaml view, Type callingType)
>      at App1.MainPage.InitializeComponent()
>      at App1.MainPage..ctor()
>      at App1.App..ctor()
>      at App1.UWP.MainPage..ctor()
>      at App1.UWP.App1_UWP_XamlTypeInfo.XamlTypeInfoProvider.Activate_4_MainPage()
>      at App1.UWP.App1_UWP_XamlTypeInfo.XamlUserType.ActivateInstance()
Comment 6 Rich Zwaap 2017-05-02 14:30:17 UTC
> It seems odd to me that an implicit type conversion from String to Uri works on
> Android and iOS but not on UWP.

Yes, thanks.  Additionally, the implicit conversion is present in native UWP, despite the XAML parser in UWP being more restrictive (as Stephane mentioned earlier).  So Xamarin Forms UWP is the only XAML variant in the mix where this does not work.
Comment 7 Jason Smith [MSFT] 2017-06-19 21:11:01 UTC
Stephanes answer clearly explains why this doesn't work on UWP and the correct manner to fix the issue.