66namespace Microsoft . Toolkit . Uwp . Notifications
77{
88 /// <summary>
9- /// A portable string serializer/deserializer for .NET .
9+ /// A class that supports serializing simple key/value pairs into a format that's friendly for being used within toast notifications. The serialized format is similar to a query string, however optimized for being placed within an XML property (uses semicolons instead of ampersands since those don't need to be XML-escaped, doesn't url-encode all special characters since not being used within a URL, etc) .
1010 /// </summary>
1111 public sealed class ToastArguments : IEnumerable < KeyValuePair < string , string > >
1212 {
@@ -66,16 +66,14 @@ public bool TryGetValue(string key, out string value)
6666 return _dictionary . TryGetValue ( key , out value ) ;
6767 }
6868
69+ #if ! WINRT
6970 /// <summary>
7071 /// Attempts to get the value of the specified key. If no key exists, returns false.
7172 /// </summary>
7273 /// <typeparam name="T">The enum to parse.</typeparam>
7374 /// <param name="key">The key to find.</param>
7475 /// <param name="value">The key's value will be written here if found.</param>
7576 /// <returns>True if found the key and set the value, otherwise false.</returns>
76- #if WINRT
77- [ return : System . Runtime . InteropServices . WindowsRuntime . ReturnValueName ( "found" ) ]
78- #endif
7977 public bool TryGetValue < T > ( string key , out T value )
8078 where T : struct , Enum
8179 {
@@ -87,6 +85,7 @@ public bool TryGetValue<T>(string key, out T value)
8785 value = default ( T ) ;
8886 return false ;
8987 }
88+ #endif
9089
9190 /// <summary>
9291 /// Gets the value of the specified key, or throws <see cref="KeyNotFoundException"/> if key didn't exist.
@@ -138,6 +137,16 @@ public float GetFloat(string key)
138137 return float . Parse ( Get ( key ) ) ;
139138 }
140139
140+ /// <summary>
141+ /// Gets the value of the specified key, or throws <see cref="KeyNotFoundException"/> if key didn't exist.
142+ /// </summary>
143+ /// <param name="key">The key to get.</param>
144+ /// <returns>The value of the key.</returns>
145+ public byte GetByte ( string key )
146+ {
147+ return byte . Parse ( Get ( key ) ) ;
148+ }
149+
141150 /// <summary>
142151 /// Gets the value of the specified key, or throws <see cref="KeyNotFoundException"/> if key didn't exist.
143152 /// </summary>
@@ -148,6 +157,7 @@ public bool GetBool(string key)
148157 return Get ( key ) == "1" ? true : false ;
149158 }
150159
160+ #if ! WINRT
151161 /// <summary>
152162 /// Gets the value of the specified key, or throws <see cref="KeyNotFoundException"/> if key didn't exist.
153163 /// </summary>
@@ -164,6 +174,7 @@ public T GetEnum<T>(string key)
164174
165175 throw new KeyNotFoundException ( ) ;
166176 }
177+ #endif
167178
168179 /// <summary>
169180 /// Gets the number of key/value pairs contained in the toast arguments.
@@ -203,14 +214,20 @@ public void Add(string key, string value)
203214 /// Sets a key. If there is an existing key, it is replaced.
204215 /// </summary>
205216 /// <param name="key">The key.</param>
206- public void Set ( string key )
217+ /// <returns>The current <see cref="ToastArguments"/> object.</returns>
218+ #if WINRT
219+ [ return : System . Runtime . InteropServices . WindowsRuntime . ReturnValueName ( "toastArguments" ) ]
220+ #endif
221+ public ToastArguments Set ( string key )
207222 {
208223 if ( key == null )
209224 {
210225 throw new ArgumentNullException ( nameof ( key ) ) ;
211226 }
212227
213228 _dictionary [ key ] = null ;
229+
230+ return this ;
214231 }
215232
216233 /// <summary>
@@ -219,6 +236,10 @@ public void Set(string key)
219236 /// <param name="key">The key.</param>
220237 /// <param name="value">The optional value of the key.</param>
221238 /// <returns>The current <see cref="ToastArguments"/> object.</returns>
239+ #if WINRT
240+ [ Windows . Foundation . Metadata . DefaultOverload ]
241+ [ return : System . Runtime . InteropServices . WindowsRuntime . ReturnValueName ( "toastArguments" ) ]
242+ #endif
222243 public ToastArguments Set ( string key , string value )
223244 {
224245 if ( key == null )
@@ -237,6 +258,9 @@ public ToastArguments Set(string key, string value)
237258 /// <param name="key">The key.</param>
238259 /// <param name="value">The value of the key.</param>
239260 /// <returns>The current <see cref="ToastArguments"/> object.</returns>
261+ #if WINRT
262+ [ return : System . Runtime . InteropServices . WindowsRuntime . ReturnValueName ( "toastArguments" ) ]
263+ #endif
240264 public ToastArguments Set ( string key , int value )
241265 {
242266 return SetHelper ( key , value ) ;
@@ -248,6 +272,9 @@ public ToastArguments Set(string key, int value)
248272 /// <param name="key">The key.</param>
249273 /// <param name="value">The value of the key.</param>
250274 /// <returns>The current <see cref="ToastArguments"/> object.</returns>
275+ #if WINRT
276+ [ return : System . Runtime . InteropServices . WindowsRuntime . ReturnValueName ( "toastArguments" ) ]
277+ #endif
251278 public ToastArguments Set ( string key , double value )
252279 {
253280 return SetHelper ( key , value ) ;
@@ -259,6 +286,9 @@ public ToastArguments Set(string key, double value)
259286 /// <param name="key">The key.</param>
260287 /// <param name="value">The value of the key.</param>
261288 /// <returns>The current <see cref="ToastArguments"/> object.</returns>
289+ #if WINRT
290+ [ return : System . Runtime . InteropServices . WindowsRuntime . ReturnValueName ( "toastArguments" ) ]
291+ #endif
262292 public ToastArguments Set ( string key , float value )
263293 {
264294 return SetHelper ( key , value ) ;
@@ -270,11 +300,15 @@ public ToastArguments Set(string key, float value)
270300 /// <param name="key">The key.</param>
271301 /// <param name="value">The value of the key.</param>
272302 /// <returns>The current <see cref="ToastArguments"/> object.</returns>
303+ #if WINRT
304+ [ return : System . Runtime . InteropServices . WindowsRuntime . ReturnValueName ( "toastArguments" ) ]
305+ #endif
273306 public ToastArguments Set ( string key , bool value )
274307 {
275308 return Set ( key , value ? "1" : "0" ) ; // Encode as 1 or 0 to save string space
276309 }
277310
311+ #if ! WINRT
278312 /// <summary>
279313 /// Sets a key and value. If there is an existing key, it is replaced.
280314 /// </summary>
@@ -285,6 +319,7 @@ public ToastArguments Set(string key, Enum value)
285319 {
286320 return Set ( key , ( int ) ( object ) value ) ;
287321 }
322+ #endif
288323
289324 private ToastArguments SetHelper ( string key , object value )
290325 {
@@ -347,18 +382,20 @@ public bool Remove(string key)
347382 return _dictionary . Remove ( key ) ;
348383 }
349384
350- private static string UrlEncode ( string str )
385+ private static string Encode ( string str )
351386 {
352- return Uri . EscapeDataString ( str )
353-
354- // It incorrectly encodes spaces as %20, should use +
355- . Replace ( "%20 " , "+ " ) ;
387+ return str
388+ . Replace ( "%" , "%25" )
389+ . Replace ( ";" , "%3B" )
390+ . Replace ( "= " , "%3D " ) ;
356391 }
357392
358- private static string UrlDecode ( string str )
393+ private static string Decode ( string str )
359394 {
360- // Doesn't handle decoding the +, so we manually do that
361- return Uri . UnescapeDataString ( str . Replace ( '+' , ' ' ) ) ;
395+ return str
396+ . Replace ( "%25" , "%" )
397+ . Replace ( "%3B" , ";" )
398+ . Replace ( "%3D" , "=" ) ;
362399 }
363400
364401 /// <summary>
@@ -373,7 +410,7 @@ public static ToastArguments Parse(string toastArgumentsStr)
373410 return new ToastArguments ( ) ;
374411 }
375412
376- string [ ] pairs = toastArgumentsStr . Split ( '& ' ) ;
413+ string [ ] pairs = toastArgumentsStr . Split ( '; ' ) ;
377414
378415 ToastArguments answer = new ToastArguments ( ) ;
379416
@@ -386,13 +423,13 @@ public static ToastArguments Parse(string toastArgumentsStr)
386423
387424 if ( indexOfEquals == - 1 )
388425 {
389- name = UrlDecode ( pair ) ;
426+ name = Decode ( pair ) ;
390427 value = null ;
391428 }
392429 else
393430 {
394- name = UrlDecode ( pair . Substring ( 0 , indexOfEquals ) ) ;
395- value = UrlDecode ( pair . Substring ( indexOfEquals + 1 ) ) ;
431+ name = Decode ( pair . Substring ( 0 , indexOfEquals ) ) ;
432+ value = Decode ( pair . Substring ( indexOfEquals + 1 ) ) ;
396433 }
397434
398435 answer . Add ( name , value ) ;
@@ -407,13 +444,13 @@ public static ToastArguments Parse(string toastArgumentsStr)
407444 /// <returns>A string that can be used within a toast notification.</returns>
408445 public sealed override string ToString ( )
409446 {
410- return string . Join ( "& " , this . Select ( pair =>
447+ return string . Join ( "; " , this . Select ( pair =>
411448
412449 // Key
413- UrlEncode ( pair . Key ) +
450+ Encode ( pair . Key ) +
414451
415452 // Write value if not null
416- ( ( pair . Value == null ) ? string . Empty : ( "=" + UrlEncode ( pair . Value ) ) ) ) ) ;
453+ ( ( pair . Value == null ) ? string . Empty : ( "=" + Encode ( pair . Value ) ) ) ) ) ;
417454 }
418455
419456 /// <summary>
0 commit comments