-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Deep link parsers and tests #368
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deep link parsers and tests #368
Conversation
Hi @brandonh-msft, I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution!
TTYL, MSBOT; |
.Select(param => | ||
{ | ||
var kvp = param.Split('='); | ||
return new KeyValuePair<string, string>(kvp[0], kvp[1]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You've essentially done this conversion to KeyValuePair list twice now, could we move this to a helper method instead?
var origString = validatedUri.OriginalString; | ||
int queryStartPosition = origString.IndexOf('?'); | ||
if (queryStartPosition == -1) | ||
{ // No querystring on the URI |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think style suggests that comments should be on the next line.
int queryStartPosition = origString.IndexOf('?'); | ||
if (queryStartPosition == -1) | ||
{ // No querystring on the URI | ||
this.Root = origString; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove usages of this.
up |
@deltakosh i submitted a new push, should be able to merge it in no problem. |
@brandonh-msft it seems like there are conflicts that must be resolved. |
UnitTests/DeepLinkParserTests.cs
Outdated
{ | ||
public TestContext TestContext { get; set; } | ||
|
||
private const string SAMPLELINK = @"MainPage/Options?option1=value1&option2=value2&option3=value3"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this should be SampleLink not SAMPLELINK
UnitTests/DeepLinkParserTests.cs
Outdated
public TestContext TestContext { get; set; } | ||
|
||
private const string SAMPLELINK = @"MainPage/Options?option1=value1&option2=value2&option3=value3"; | ||
private static readonly DeepLinkParser _parser = new TestDeepLinkParser(SAMPLELINK); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also _parser should be Parser
UnitTests/DeepLinkParserTests.cs
Outdated
public class CollectionCapableDeepLinkParserTests | ||
#pragma warning restore SA1402 // File may only contain a single class | ||
{ | ||
private const string SAMPLELINK = @"MainPage/Options?option1=value1&option2=value2&option3=value3&option2=value4"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SAMPLELINK Should be SampleLink too
UnitTests/DeepLinkParserTests.cs
Outdated
#pragma warning restore SA1402 // File may only contain a single class | ||
{ | ||
private const string SAMPLELINK = @"MainPage/Options?option1=value1&option2=value2&option3=value3&option2=value4"; | ||
private static readonly DeepLinkParser _parser = new TestCollectionCapableDeepLinkParser(SAMPLELINK); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_parser should be Parser
Is there a specific reason why you do not open this up for use with normal string or uri arguments? Parsing options from uri strings is a very common scenario, not only useful for deeplinks but also all other kinds of links. Even when only using this for deep links, it should be opened up for string arguments as well: I am pretty sure that in almost all apps, the string will be passed to a frame's navigate function. So in the app class, only the .Root will be checked to get the page type. Only later in the page's navigate function, the user will actually want to parse out the parameters from the string argument. So a DeepLinkParser which only works with IActivatedEventArgs would be pretty useless for most apps, I think. I would propose to at least give it a public string overload. And if you ask me, I'd even rename it to something like LinkParser or LinkQueryParser and add an Uri overload as well, to make it truly universal. |
@lukasf |
Do you mind fixing conflicts and checking @IbraheemOsama ask? |
@deltakosh |
@lukasf you might want to check out a branch i already had in my fork but haven't yet updated to the latest code if you're interested in this approach. |
@brandonh-msft My point is, the vast majority of apps use frame navigation, they will need to have the link options accessible in the page's OnNavigatedTo() function. It does not help much to have the link options available in the App class, when there is no way to pass complex objects (such as the DeepLinkParser, Dictionaries, etc) through there without breaking Frame's navigation state serialization. So the easiest way for all these apps to work with deep links is to pass the deep link as string parameter to Frame.Navigate() and then parse out the options in Page.OnNavigatedTo(). The goal of this toolkit is to simplify things for developers. It would be very unfortunate if nearly all app devs would need to inherit DeepLinkParser, only to successfully use it with frame navigation apps. |
@lukasf Regardless, i'll work on shoring up the string-capable version of this PR and add it in. |
@brandonh-msft Normally I would fully agree with you. But unfortunately there is this restriction that the parameter passed to the Page through Frame.Navigate can only be one of the simple types string, numeric, char or Guid. No complex values are allowed, no dicts or arrays. So passing data as a single string is the only feasible way. If there is no string overload in DeepLinkParser, devs would have to serialize the parsed options again in the app and then deserialize in the page. With string overload, they can just move the options parsing right into the page and save the whole serialize/deserialize. I am sure that this will be very useful to a lot of devs. |
Eh? That's simply not true. Frame.Navigate can have anything passed through, I do it all the time. |
@ScottIsAFool Well right, you can pass anything, but then the next call to GetNavigationState() will fail with an exception. If you want to persist the frame naviagation state on app suspend/resume, you cannot pass complex values. This is also mentioned in the msdn docs for Frame.Navigate(). |
@lukasf right, you made no comment about this originally, hence the confusion :) thanks for clarifying. |
@ScottIsAFool Sure, no worries. :) Sorry for the confusion. |
@lukasf |
Conflicts :( Sorry should be because of last merges) |
nice exception for repeated keys when using DeepLinkParser more meaningful var name more single-char var name fixes xml doco fix Uri & string overloads along with UTs
…ng of query parameters from a string or Uri in to a collection that can be iterated on
adding StyleCop analyzers to UT project Stylecop ignoring as did review call stack.
Just discussed with @brandonh-msft regarding doc |
The purpose of this PR is to provide UWP devs an easy way to deal with Deep link URIs as they become more and more a part of the services we create for devs to consume. Bot Framework, Cortana launches, etc all rely on deep links in to apps to ultimately provide value.
DeepLinkParser
This class provides a way to create, from
IActivatedEventArgs
aDictionary<string,string>
-inheriting object that provides an additional.Root
property to pull the base path of the URI (eg: inMainPage/Options?option1=value1
,.Root
would beMainPage/Options
.Once you have an instance, simply saying
instance["optionName"]
will pull the value from the querystring for that option.CollectionFormingDeepLinkParser
Some consumers want to be able to do something like
?pref=this&pref=that&pref=theOther
and have a pull ofpref
come back withthis,that,theOther
as its value. This derivative ofDeepLinkParser
provides this functionality.Both of these are createable using a
.Create(IActivatedEventArgs)
method. Should a user wish to create one in a different manner, the default constructor isprotected
so inheriting from either of these can provide extensibility should they wish to pass in just astring
, etc. The method that does the heavy lifting of parsing in to theDictionary<string,string>
is alsoprotected
so can be used by any inheriting class.