From 82f35fe514779e458a747a377178b2ec24458146 Mon Sep 17 00:00:00 2001 From: David Claux Date: Thu, 23 Apr 2015 17:13:54 -0700 Subject: [PATCH 1/2] - Fixes KeyNotFound exception in DictionaryProperty when a value is removed from dictionary - Introduces new Folder.WellKnwonFolderNameAsString property to expose a folder's well known name even if that name isn't defined in the WellKnownFolderName enumeration - Fixes a bug in StreamingSubscriptionConnection that made it impossible to re-open the connection in its OnDisconnect handler --- ComplexProperties/DictionaryProperty.cs | 4 +-- Core/EwsUtilities.cs | 32 ++++++++++++++++++--- Core/ServiceObjects/Folders/Folder.cs | 27 +++++++++++++++-- Core/ServiceObjects/Schemas/FolderSchema.cs | 5 ++-- 4 files changed, 56 insertions(+), 12 deletions(-) diff --git a/ComplexProperties/DictionaryProperty.cs b/ComplexProperties/DictionaryProperty.cs index f0e35608..07ccd06f 100644 --- a/ComplexProperties/DictionaryProperty.cs +++ b/ComplexProperties/DictionaryProperty.cs @@ -218,7 +218,7 @@ internal void InternalRemove(TKey key) } this.addedEntries.Remove(key); - this.modifiedEntries.Remove (key); + this.modifiedEntries.Remove(key); } /// @@ -525,4 +525,4 @@ bool ICustomUpdateSerializer.WriteDeleteUpdateToJson(ExchangeService service, Se #endregion } -} +} \ No newline at end of file diff --git a/Core/EwsUtilities.cs b/Core/EwsUtilities.cs index 3c594fc9..8bffbe19 100644 --- a/Core/EwsUtilities.cs +++ b/Core/EwsUtilities.cs @@ -78,7 +78,7 @@ internal static class EwsUtilities /// Dictionary of enum type to ExchangeVersion maps. /// private static LazyMember>> enumVersionDictionaries = new LazyMember>>( - () => new Dictionary>() + () => new Dictionary>() { { typeof(WellKnownFolderName), BuildEnumDict(typeof(WellKnownFolderName)) }, { typeof(ItemTraversal), BuildEnumDict(typeof(ItemTraversal)) }, @@ -93,7 +93,7 @@ internal static class EwsUtilities /// Dictionary of enum type to schema-name-to-enum-value maps. /// private static LazyMember>> schemaToEnumDictionaries = new LazyMember>>( - () => new Dictionary> + () => new Dictionary> { { typeof(EventType), BuildSchemaToEnumDict(typeof(EventType)) }, { typeof(MailboxType), BuildSchemaToEnumDict(typeof(MailboxType)) }, @@ -106,7 +106,7 @@ internal static class EwsUtilities /// Dictionary of enum type to enum-value-to-schema-name maps. /// private static LazyMember>> enumToSchemaDictionaries = new LazyMember>>( - () => new Dictionary> + () => new Dictionary> { { typeof(EventType), BuildEnumToSchemaDict(typeof(EventType)) }, { typeof(MailboxType), BuildEnumToSchemaDict(typeof(MailboxType)) }, @@ -119,7 +119,7 @@ internal static class EwsUtilities /// Dictionary to map from special CLR type names to their "short" names. /// private static LazyMember> typeNameToShortNameMap = new LazyMember>( - () => new Dictionary + () => new Dictionary { { "Boolean", "bool" }, { "Int16", "short" }, @@ -720,6 +720,30 @@ internal static T Parse(string value) } } + /// + /// Tries to parses the specified value to the specified type. + /// + /// The type into which to cast the provided value. + /// The value to parse. + /// The value cast to the specified type, if TryParse succeeds. Otherwise, the value of result is indeterminate. + /// True if value could be parsed; otherwise, false. + internal static bool TryParse(string value, out T result) + { + try + { + result = EwsUtilities.Parse(value); + + return true; + } + //// Catch all exceptions here, we're not interested in the reason why TryParse failed. + catch (Exception) + { + result = default(T); + + return false; + } + } + /// /// Converts the specified date and time from one time zone to another. /// diff --git a/Core/ServiceObjects/Folders/Folder.cs b/Core/ServiceObjects/Folders/Folder.cs index 6a6de8ff..60f3d465 100644 --- a/Core/ServiceObjects/Folders/Folder.cs +++ b/Core/ServiceObjects/Folders/Folder.cs @@ -663,12 +663,33 @@ public ArchiveTag ArchiveTag } /// - /// Gets the name of the well known folder. + /// Gets the well known name of this folder, if any, as a string. /// - /// The name of the well known folder. + /// The well known name of this folder as a string, or null if this folder isn't a well known folder. + public string WellKnownFolderNameAsString + { + get { return (string)this.PropertyBag[FolderSchema.WellKnownFolderName]; } + } + + /// + /// Gets the well known name of this folder, if any. + /// + /// The well known name of this folder, or null if this folder isn't a well known folder. public WellKnownFolderName? WellKnownFolderName { - get { return (WellKnownFolderName?)this.PropertyBag[FolderSchema.WellKnownFolderName]; } + get + { + WellKnownFolderName result; + + if (EwsUtilities.TryParse(this.WellKnownFolderNameAsString, out result)) + { + return result; + } + else + { + return null; + } + } } #endregion diff --git a/Core/ServiceObjects/Schemas/FolderSchema.cs b/Core/ServiceObjects/Schemas/FolderSchema.cs index ed91f018..f0930768 100644 --- a/Core/ServiceObjects/Schemas/FolderSchema.cs +++ b/Core/ServiceObjects/Schemas/FolderSchema.cs @@ -171,12 +171,11 @@ private static class FieldUris /// [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "Immutable type")] public static readonly PropertyDefinition WellKnownFolderName = - new GenericPropertyDefinition( + new StringPropertyDefinition( XmlElementNames.DistinguishedFolderId, FieldUris.DistinguishedFolderId, PropertyDefinitionFlags.CanSet | PropertyDefinitionFlags.CanFind, - ExchangeVersion.Exchange2013, - true); + ExchangeVersion.Exchange2013); /// /// Defines the PolicyTag property. From 66d9fd582d89ccfcf1b53b31998c2beb01eb626f Mon Sep 17 00:00:00 2001 From: David Claux Date: Fri, 24 Apr 2015 11:27:30 -0700 Subject: [PATCH 2/2] Actually adding fix for StreamingSubscriptionConnection not allowing re-open in OnDisconnect --- Notifications/StreamingSubscriptionConnection.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Notifications/StreamingSubscriptionConnection.cs b/Notifications/StreamingSubscriptionConnection.cs index 54a6675b..fdef52fb 100644 --- a/Notifications/StreamingSubscriptionConnection.cs +++ b/Notifications/StreamingSubscriptionConnection.cs @@ -262,12 +262,12 @@ public void Close() /// The exception that caused the disconnection. May be null. private void InternalOnDisconnect(Exception ex) { + this.currentHangingRequest = null; + if (this.OnDisconnect != null) { this.OnDisconnect(this, new SubscriptionErrorEventArgs(null, ex)); } - - this.currentHangingRequest = null; } ///