Documentation Coverage Report
Current view: top level - Azure/Cqrs.Azure.Storage - EntityPropertyConverter.cs Hit Total Coverage
Version: 2.2 Artefacts: 7 7 100.0 %
Date: 2018-08-07 15:04:50

          Line data    Source code
       1             : // -----------------------------------------------------------------------------------------
       2             : // <copyright file="EntityPropertyConverter.cs" company="Microsoft">
       3             : //    Copyright 2013 Microsoft Corporation
       4             : //
       5             : //    Licensed under the Apache License, Version 2.0 (the "License");
       6             : //    you may not use this file except in compliance with the License.
       7             : //    You may obtain a copy of the License at
       8             : //      http://www.apache.org/licenses/LICENSE-2.0
       9             : //
      10             : //    Unless required by applicable law or agreed to in writing, software
      11             : //    distributed under the License is distributed on an "AS IS" BASIS,
      12             : //    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      13             : //    See the License for the specific language governing permissions and
      14             : //    limitations under the License.
      15             : // </copyright>
      16             : // -----------------------------------------------------------------------------------------
      17             : 
      18             : using System.Collections;
      19             : using System.Diagnostics;
      20             : using Newtonsoft.Json;
      21             : using Newtonsoft.Json.Converters;
      22             : 
      23             : namespace Microsoft.WindowsAzure.Storage.Table
      24             : {
      25             :         using System;
      26             :         using System.Collections.Generic;
      27             :         using System.Globalization;
      28             :         using System.IO;
      29             :         using System.Linq;
      30             :         using System.Reflection;
      31             :         using System.Runtime.CompilerServices;
      32             :         using System.Runtime.Serialization;
      33             : 
      34             :         /// <summary>
      35             :         /// EntityPropertyConverter class.
      36             :         /// </summary>
      37             :         public static class EntityPropertyConverter
      38           1 :         {
      39             :                 /// <summary>
      40             :                 /// The default <see cref="JsonSerializerSettings"/> to use.
      41             :                 /// </summary>
      42             :                 public static JsonSerializerSettings DefaultSettings { get; private set; }
      43             : 
      44             :                 static EntityPropertyConverter()
      45             :                 {
      46             :                         DefaultSettings = new JsonSerializerSettings
      47             :                         {
      48             :                                 Formatting = Formatting.None,
      49             :                                 MissingMemberHandling = MissingMemberHandling.Ignore,
      50             :                                 DateParseHandling = DateParseHandling.DateTimeOffset,
      51             :                                 DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind,
      52             :                                 Converters = new List<JsonConverter> { new StringEnumConverter() },
      53             :                                 DateFormatHandling = DateFormatHandling.IsoDateFormat,
      54             :                                 DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate,
      55             :                                 FloatFormatHandling = FloatFormatHandling.DefaultValue,
      56             :                                 NullValueHandling = NullValueHandling.Include,
      57             :                                 PreserveReferencesHandling = PreserveReferencesHandling.All,
      58             :                                 ReferenceLoopHandling = ReferenceLoopHandling.Error,
      59             :                                 StringEscapeHandling = StringEscapeHandling.EscapeNonAscii,
      60             :                                 TypeNameHandling = TypeNameHandling.All
      61             :                         };
      62             :                 }
      63             : 
      64             :                 /// <summary>
      65             :                 /// The property delimiter.
      66             :                 /// </summary>
      67             :                 public const string DefaultPropertyNameDelimiter = "_";
      68             : 
      69             :                 /// <summary>
      70             :                 /// Traverses object graph, flattens and converts all nested (and not nested) properties to EntityProperties, stores them in the property dictionary.
      71             :                 /// The keys are constructed by appending the names of the properties visited during pre-order depth first traversal from root to each end node property delimited by '_'.
      72             :                 /// Allows complex objects to be stored in persistent storage systems or passed between web services in a generic way.
      73             :                 /// </summary>
      74             :                 /// <param name="root">The object to flatten and convert.</param>
      75             :                 /// <param name="operationContext">An <see cref="OperationContext"/> object that represents the context for the current operation.</param>
      76             :                 /// <returns>The result containing <see cref="IDictionary{TKey,TValue}"/> of <see cref="EntityProperty"/> objects for all properties of the flattened root object.</returns>
      77           1 :                 public static Dictionary<string, EntityProperty> Flatten(object root, OperationContext operationContext)
      78             :                 {
      79             :                         return Flatten(root, new EntityPropertyConverterOptions { PropertyNameDelimiter = DefaultPropertyNameDelimiter }, operationContext);
      80             :                 }
      81             : 
      82             :                 /// <summary>
      83             :                 /// Traverses object graph, flattens and converts all nested (and not nested) properties to EntityProperties, stores them in the property dictionary.
      84             :                 /// The keys are constructed by appending the names of the properties visited during pre-order depth first traversal from root to each end node property delimited by '_'.
      85             :                 /// Allows complex objects to be stored in persistent storage systems or passed between web services in a generic way.
      86             :                 /// </summary>
      87             :                 /// <param name="root">The object to flatten and convert.</param>
      88             :                 /// <param name="entityPropertyConverterOptions">A <see cref="EntityPropertyConverterOptions"/> object that specifies options for the entity property conversion.</param>
      89             :                 /// <param name="operationContext">An <see cref="OperationContext"/> object that represents the context for the current operation.</param>
      90             :                 /// <returns>The result containing <see cref="IDictionary{TKey,TValue}"/> of <see cref="EntityProperty"/> objects for all properties of the flattened root object.</returns>
      91           1 :                 public static Dictionary<string, EntityProperty> Flatten(object root, EntityPropertyConverterOptions entityPropertyConverterOptions, OperationContext operationContext)
      92             :                 {
      93             :                         if (root == null)
      94             :                         {
      95             :                                 return null;
      96             :                         }
      97             : 
      98             :                         Dictionary<string, EntityProperty> propertyDictionary = new Dictionary<string, EntityProperty>();
      99             :                         HashSet<object> antecedents = new HashSet<object>(new ObjectReferenceEqualityComparer());
     100             : 
     101             :                         return Flatten(propertyDictionary, root, string.Empty, antecedents, entityPropertyConverterOptions, operationContext) ? propertyDictionary : null;
     102             :                 }
     103             : 
     104             :                 /// <summary>
     105             :                 /// Reconstructs the complete object graph of type T using the flattened entity property dictionary and returns reconstructed object.
     106             :                 /// The property dictionary may contain only basic properties, only nested properties or a mix of both types.
     107             :                 /// </summary>
     108             :                 /// <typeparam name="T">The type of the object to populate</typeparam>
     109             :                 /// <param name="flattenedEntityProperties">The flattened entity property dictionary.</param>
     110             :                 /// <param name="operationContext">An <see cref="OperationContext"/> object that represents the context for the current operation.</param>
     111             :                 /// <returns>The result containing the reconstructed object with its full object hierarchy.</returns>
     112           1 :                 public static T ConvertBack<T>(IDictionary<string, EntityProperty> flattenedEntityProperties, OperationContext operationContext)
     113             :                 {
     114             :                         return ConvertBack<T>(flattenedEntityProperties, new EntityPropertyConverterOptions { PropertyNameDelimiter = DefaultPropertyNameDelimiter }, operationContext);
     115             :                 }
     116             : 
     117             :                 /// <summary>
     118             :                 /// Reconstructs the complete object graph of type T using the flattened entity property dictionary and returns reconstructed object.
     119             :                 /// The property dictionary may contain only basic properties, only nested properties or a mix of both types.
     120             :                 /// </summary>
     121             :                 /// <typeparam name="T">The type of the object to populate</typeparam>
     122             :                 /// <param name="flattenedEntityProperties">The flattened entity property dictionary.</param>
     123             :                 /// <param name="entityPropertyConverterOptions">A <see cref="EntityPropertyConverterOptions"/> object that specifies options for the entity property conversion.</param>
     124             :                 /// <param name="operationContext">An <see cref="OperationContext"/> object that represents the context for the current operation.</param>
     125             :                 /// <returns>The result containing the reconstructed object with its full object hierarchy.</returns>
     126           1 :                 public static T ConvertBack<T>(
     127             :                         IDictionary<string, EntityProperty> flattenedEntityProperties,
     128             :                         EntityPropertyConverterOptions entityPropertyConverterOptions,
     129             :                         OperationContext operationContext)
     130             :                 {
     131             :                         if (flattenedEntityProperties == null)
     132             :                         {
     133             :                                 return default(T);
     134             :                         }
     135             : 
     136             :                         T root = (T)Activator.CreateInstance(typeof(T));
     137             : 
     138             :                         return flattenedEntityProperties.Aggregate(root, (current, kvp) => (T)SetProperty(current, kvp.Key, kvp.Value.PropertyAsObject, entityPropertyConverterOptions, operationContext));
     139             :                 }
     140             : 
     141             :                 /// <summary>
     142             :                 /// Traverses object graph, flattens and converts all nested (and not nested) properties to EntityProperties, stores them in the property dictionary.
     143             :                 /// The keys are constructed by appending the names of the properties visited during pre-order depth first traversal from root to each end node property delimited by '.'.
     144             :                 /// Allows complex objects to be stored in persistent storage systems or passed between web services in a generic way.
     145             :                 /// </summary>
     146             :                 /// <param name="propertyDictionary">The property dictionary.</param>
     147             :                 /// <param name="current">The current object.</param>
     148             :                 /// <param name="objectPath">The object path.</param>
     149             :                 /// <param name="antecedents">The antecedents of current object, used to detect circular references in object graph.</param>
     150             :                 /// <param name="entityPropertyConverterOptions">A <see cref="EntityPropertyConverterOptions"/> object that specifies options for the entity property conversion.</param>
     151             :                 /// <param name="operationContext">An <see cref="OperationContext"/> object that represents the context for the current operation.</param>
     152             :                 /// <returns>The <see cref="bool"/> to indicate success of conversion to flattened EntityPropertyDictionary.</returns>
     153             :                 private static bool Flatten(
     154             :                         Dictionary<string, EntityProperty> propertyDictionary,
     155             :                         object current,
     156             :                         string objectPath,
     157             :                         HashSet<object> antecedents,
     158             :                         EntityPropertyConverterOptions entityPropertyConverterOptions,
     159             :                         OperationContext operationContext)
     160             :                 {
     161             :                         if (current == null)
     162             :                         {
     163             :                                 return true;
     164             :                         }
     165             : 
     166             :                         Type type;
     167             :                         do
     168             :                         {
     169             :                                 type = current.GetType();
     170             :                                 EntityProperty entityProperty = CreateEntityPropertyWithType(current, type);
     171             : 
     172             :                                 if (entityProperty != null)
     173             :                                 {
     174             :                                         propertyDictionary.Add(objectPath, entityProperty);
     175             :                                         return true;
     176             :                                 }
     177             :                                 // Better support for IEnumerable
     178             :                                 if (current is IEnumerable && !(current is string))
     179             :                                         current = string.Format("_$¿={0}", JsonConvert.SerializeObject(current, GetSerialisationSettings()));
     180             :                                 else
     181             :                                         break;
     182             :                         } while (true);
     183             : 
     184             :                         IEnumerable<PropertyInfo> propertyInfos = type.GetProperties();
     185             : 
     186             :                         if (!propertyInfos.Any())
     187             :                         {
     188             :                                 throw new SerializationException(string.Format(CultureInfo.InvariantCulture, SR.UnsupportedPropertyTypeForEntityPropertyConversion, type, objectPath));
     189             :                         }
     190             : 
     191             :                         bool isAntecedent = false;
     192             : 
     193             :                         if (!type.IsValueType)
     194             :                         {
     195             :                                 if (antecedents.Contains(current))
     196             :                                 {
     197             :                                         throw new SerializationException(string.Format(CultureInfo.InvariantCulture, SR.RecursiveReferencedObject, objectPath, type));
     198             :                                 }
     199             : 
     200             :                                 antecedents.Add(current);
     201             :                                 isAntecedent = true;
     202             :                         }
     203             : 
     204             :                         string propertyNameDelimiter = entityPropertyConverterOptions != null ? entityPropertyConverterOptions.PropertyNameDelimiter : DefaultPropertyNameDelimiter;
     205             : 
     206             :                         bool success = propertyInfos
     207             :                                 .Where(propertyInfo => !ShouldSkip(propertyInfo, objectPath, operationContext))
     208             :                                 .All(propertyInfo =>
     209             :                                 {
     210             :                                         if (propertyInfo.Name.Contains(propertyNameDelimiter))
     211             :                                         {
     212             :                                                 throw new SerializationException(string.Format(CultureInfo.InvariantCulture, SR.PropertyDelimiterExistsInPropertyName, propertyNameDelimiter, propertyInfo.Name, objectPath));
     213             :                                         }
     214             : 
     215             :                                         object value;
     216             :                                         try
     217             :                                         {
     218             :                                                 value = propertyInfo.GetValue(current, index: null);
     219             :                                         }
     220             :                                         catch (Exception)
     221             :                                         {
     222             :                                                 // Support for unsupported data types
     223             :                                                 value = string.Format("_$¿={0}", JsonConvert.SerializeObject(current, GetSerialisationSettings()));
     224             :                                         }
     225             : 
     226             :                                         return Flatten(
     227             :                                                 propertyDictionary,
     228             :                                                 value,
     229             :                                                 string.IsNullOrWhiteSpace(objectPath) ? propertyInfo.Name : objectPath + propertyNameDelimiter + propertyInfo.Name,
     230             :                                                 antecedents,
     231             :                                                 entityPropertyConverterOptions,
     232             :                                                 operationContext);
     233             :                                 });
     234             : 
     235             :                         if (isAntecedent)
     236             :                         {
     237             :                                 antecedents.Remove(current);
     238             :                         }
     239             : 
     240             :                         return success;
     241             :                 }
     242             : 
     243             :                 /// <summary>
     244             :                 /// Returns <see cref="DefaultSettings"/>
     245             :                 /// </summary>
     246             :                 /// <returns><see cref="DefaultSettings"/></returns>
     247             :                 static JsonSerializerSettings GetSerialisationSettings()
     248             :                 {
     249             :                         return DefaultSettings;
     250             :                 }
     251             : 
     252             :                 /// <summary>Creates entity property with given type.</summary>
     253             :                 /// <param name="value">The value.</param>
     254             :                 /// <param name="type">The type.</param>
     255             :                 /// <returns>The <see cref="EntityProperty"/>.</returns>
     256             :                 private static EntityProperty CreateEntityPropertyWithType(object value, Type type)
     257             :                 {
     258             :                         if (type == typeof(string))
     259             :                         {
     260             :                                 return new EntityProperty((string)value);
     261             :                         }
     262             :                         else if (type == typeof(byte[]))
     263             :                         {
     264             :                                 return new EntityProperty((byte[])value);
     265             :                         }
     266             :                         else if (type == typeof(bool))
     267             :                         {
     268             :                                 return new EntityProperty((bool)value);
     269             :                         }
     270             :                         else if (type == typeof(bool?))
     271             :                         {
     272             :                                 return new EntityProperty((bool?)value);
     273             :                         }
     274             :                         else if (type == typeof(DateTime))
     275             :                         {
     276             :                                 return new EntityProperty((DateTime)value);
     277             :                         }
     278             :                         else if (type == typeof(DateTime?))
     279             :                         {
     280             :                                 return new EntityProperty((DateTime?)value);
     281             :                         }
     282             :                         else if (type == typeof(DateTimeOffset))
     283             :                         {
     284             :                                 return new EntityProperty((DateTimeOffset)value);
     285             :                         }
     286             :                         else if (type == typeof(DateTimeOffset?))
     287             :                         {
     288             :                                 return new EntityProperty((DateTimeOffset?)value);
     289             :                         }
     290             :                         else if (type == typeof(double))
     291             :                         {
     292             :                                 return new EntityProperty((double)value);
     293             :                         }
     294             :                         else if (type == typeof(double?))
     295             :                         {
     296             :                                 return new EntityProperty((double?)value);
     297             :                         }
     298             :                         else if (type == typeof(Guid?))
     299             :                         {
     300             :                                 return new EntityProperty((Guid?)value);
     301             :                         }
     302             :                         else if (type == typeof(Guid))
     303             :                         {
     304             :                                 return new EntityProperty((Guid)value);
     305             :                         }
     306             :                         else if (type == typeof(int))
     307             :                         {
     308             :                                 return new EntityProperty((int)value);
     309             :                         }
     310             :                         else if (type == typeof(int?))
     311             :                         {
     312             :                                 return new EntityProperty((int?)value);
     313             :                         }
     314             :                         else if (type == typeof(uint))
     315             :                         {
     316             :                                 return new EntityProperty(unchecked((int)Convert.ToUInt32(value, CultureInfo.InvariantCulture)));
     317             :                         }
     318             :                         else if (type == typeof(uint?))
     319             :                         {
     320             :                                 return new EntityProperty(unchecked((int?)Convert.ToUInt32(value, CultureInfo.InvariantCulture)));
     321             :                         }
     322             :                         else if (type == typeof(long))
     323             :                         {
     324             :                                 return new EntityProperty((long)value);
     325             :                         }
     326             :                         else if (type == typeof(long?))
     327             :                         {
     328             :                                 return new EntityProperty((long?)value);
     329             :                         }
     330             :                         else if (type == typeof(ulong))
     331             :                         {
     332             :                                 return new EntityProperty(unchecked((long)Convert.ToUInt64(value, CultureInfo.InvariantCulture)));
     333             :                         }
     334             :                         else if (type == typeof(ulong?))
     335             :                         {
     336             :                                 return new EntityProperty(unchecked((long?)Convert.ToUInt64(value, CultureInfo.InvariantCulture)));
     337             :                         }
     338             :                         else if (type.IsEnum)
     339             :                         {
     340             :                                 return new EntityProperty(value.ToString());
     341             :                         }
     342             :                         else if (type == typeof(TimeSpan))
     343             :                         {
     344             :                                 return new EntityProperty(value.ToString());
     345             :                         }
     346             :                         else if (type == typeof(TimeSpan?))
     347             :                         {
     348             :                                 return new EntityProperty(value != null ? value.ToString() : null);
     349             :                         }
     350             :                         else
     351             :                         {
     352             :                                 return null;
     353             :                         }
     354             :                 }
     355             : 
     356             :                 /// <summary>Sets the property given with the property path on the passed in object.</summary>
     357             :                 /// <param name="root">The root object.</param>
     358             :                 /// <param name="propertyPath">The full property path formed by the name of properties from root object to the target property(included), appended by '.'.</param>
     359             :                 /// <param name="propertyValue">The property value.</param>
     360             :                 /// <param name="entityPropertyConverterOptions">A <see cref="EntityPropertyConverterOptions"/> object that specifies options for the entity property conversion.</param>
     361             :                 /// <param name="operationContext">An <see cref="OperationContext"/> object that represents the context for the current operation.</param>
     362             :                 /// <returns>The updated <see cref="object"/>.</returns>
     363             :                 private static object SetProperty(
     364             :                         object root,
     365             :                         string propertyPath,
     366             :                         object propertyValue,
     367             :                         EntityPropertyConverterOptions entityPropertyConverterOptions,
     368             :                         OperationContext operationContext)
     369             :                 {
     370             :                         if (root == null)
     371             :                         {
     372             :                                 throw new ArgumentNullException("root");
     373             :                         }
     374             : 
     375             :                         if (propertyPath == null)
     376             :                         {
     377             :                                 throw new ArgumentNullException("propertyPath");
     378             :                         }
     379             : 
     380             :                         try
     381             :                         {
     382             :                                 string propertyNameDelimiter = entityPropertyConverterOptions != null ? entityPropertyConverterOptions.PropertyNameDelimiter : DefaultPropertyNameDelimiter;
     383             : 
     384             :                                 Stack<Tuple<object, object, PropertyInfo>> valueTypePropertyHierarchy = new Stack<Tuple<object, object, PropertyInfo>>();
     385             :                                 string[] properties = propertyPath.Split(new[] { propertyNameDelimiter }, StringSplitOptions.RemoveEmptyEntries);
     386             : 
     387             :                                 object parentProperty = root;
     388             :                                 bool valueTypeDetected = false;
     389             : 
     390             :                                 for (int i = 0; i < properties.Length - 1; i++)
     391             :                                 {
     392             :                                         PropertyInfo propertyToGet = parentProperty.GetType().GetProperty(properties[i]);
     393             :                                         object temp = propertyToGet.GetValue(parentProperty, null);
     394             :                                         Type type = propertyToGet.PropertyType;
     395             : 
     396             :                                         if (temp == null)
     397             :                                         {
     398             :                                                 temp = Activator.CreateInstance(type);
     399             :                                                 propertyToGet.SetValue(parentProperty, ChangeType(temp, propertyToGet.PropertyType), index: null);
     400             :                                         }
     401             : 
     402             :                                         if (valueTypeDetected || type.IsValueType)
     403             :                                         {
     404             :                                                 valueTypeDetected = true;
     405             :                                                 valueTypePropertyHierarchy.Push(new Tuple<object, object, PropertyInfo>(temp, parentProperty, propertyToGet));
     406             :                                         }
     407             : 
     408             :                                         parentProperty = temp;
     409             :                                 }
     410             : 
     411             :                                 PropertyInfo propertyToSet = parentProperty.GetType().GetProperty(properties.Last());
     412             : 
     413             :                                 string stringValue = propertyValue as string;
     414             :                                 // Support for unsupported data types, but only if the target type isn't a string... if the target type is a string, then this isn't unsupported data-type-ing
     415             :                                 if (stringValue != null && propertyToSet.PropertyType != typeof(string) && stringValue.StartsWith("_$¿="))
     416             :                                         propertyToSet.SetValue(parentProperty, Deserialise(stringValue.Substring(4), propertyToSet.PropertyType), index: null);
     417             :                                 else
     418             :                                         propertyToSet.SetValue(parentProperty, ChangeType(propertyValue, propertyToSet.PropertyType), index: null);
     419             : 
     420             :                                 object termValue = parentProperty;
     421             :                                 while (valueTypePropertyHierarchy.Count != 0)
     422             :                                 {
     423             :                                         Tuple<object, object, PropertyInfo> propertyTuple = valueTypePropertyHierarchy.Pop();
     424             :                                         propertyTuple.Item3.SetValue(propertyTuple.Item2, ChangeType(termValue, propertyTuple.Item3.PropertyType), index: null);
     425             :                                         termValue = propertyTuple.Item2;
     426             :                                 }
     427             : 
     428             :                                 return root;
     429             :                         }
     430             :                         catch (Exception ex)
     431             :                         {
     432             :                                 Trace.TraceError(SR.TraceSetPropertyError, propertyPath, propertyValue, ex.Message);
     433             :                                 throw;
     434             :                         }
     435             :                 }
     436             : 
     437             :                 static object Deserialise(string json, Type type)
     438             :                 {
     439             :                         using (var stringReader = new StringReader(json))
     440             :                         using (var jsonTextReader = new JsonTextReader(stringReader))
     441             :                                 return GetSerialiser().Deserialize(jsonTextReader, type);
     442             :                 }
     443             : 
     444             :                 /// <summary>
     445             :                 /// Creates a new <see cref="JsonSerializer"/> using the settings from <see cref="GetSerialisationSettings"/>.
     446             :                 /// </summary>
     447             :                 /// <returns>A new instance of <see cref="JsonSerializer"/>.</returns>
     448             :                 static JsonSerializer GetSerialiser()
     449             :                 {
     450             :                         JsonSerializerSettings settings = GetSerialisationSettings();
     451             :                         return JsonSerializer.Create(settings);
     452             :                 }
     453             : 
     454             :                 /// <summary>Creates an object of specified propertyType from propertyValue.</summary>
     455             :                 /// <param name="propertyValue">The property value.</param>
     456             :                 /// <param name="propertyType">The property type.</param>
     457             :                 /// <returns>The <see cref="object"/>.</returns>
     458             :                 private static object ChangeType(object propertyValue, Type propertyType)
     459             :                 {
     460             :                         Type underlyingType = Nullable.GetUnderlyingType(propertyType);
     461             :                         Type type = underlyingType ?? propertyType;
     462             : 
     463             :                         if (type.IsEnum)
     464             :                         {
     465             :                                 return Enum.Parse(type, propertyValue.ToString());
     466             :                         }
     467             : 
     468             :                         if (type == typeof(DateTimeOffset))
     469             :                         {
     470             :                                 return new DateTimeOffset((DateTime)propertyValue);
     471             :                         }
     472             : 
     473             :                         if (type == typeof(TimeSpan))
     474             :                         {
     475             :                                 return TimeSpan.Parse(propertyValue.ToString(), CultureInfo.InvariantCulture);
     476             :                         }
     477             : 
     478             :                         if (type == typeof(uint))
     479             :                         {
     480             :                                 return unchecked((uint)(int)propertyValue);
     481             :                         }
     482             : 
     483             :                         if (type == typeof(ulong))
     484             :                         {
     485             :                                 return unchecked((ulong)(long)propertyValue);
     486             :                         }
     487             : 
     488             :                         return Convert.ChangeType(propertyValue, type, CultureInfo.InvariantCulture);
     489             :                 }
     490             : 
     491             :                 /// <summary>
     492             :                 /// Indicates whether the object member should be skipped from being flattened
     493             :                 /// </summary>
     494             :                 /// <param name="propertyInfo">The property info.</param>
     495             :                 /// <param name="objectPath">The object path.</param>
     496             :                 /// <param name="operationContext">An <see cref="OperationContext"/> object that represents the context for the current operation.</param>
     497             :                 /// <returns>The <see cref="bool"/> to indicate whether the object member should be skipped from being flattened.</returns>
     498             :                 private static bool ShouldSkip(PropertyInfo propertyInfo, string objectPath, OperationContext operationContext)
     499             :                 {
     500             :                         if (!propertyInfo.CanWrite)
     501             :                         {
     502             :                                 Trace.TraceInformation(SR.TraceNonExistingSetter, propertyInfo.Name, objectPath);
     503             :                                 return true;
     504             :                         }
     505             : 
     506             :                         if (!propertyInfo.CanRead)
     507             :                         {
     508             :                                 Trace.TraceInformation(SR.TraceNonExistingGetter, propertyInfo.Name, objectPath);
     509             :                                 return true;
     510             :                         }
     511             : 
     512             :                         return Attribute.IsDefined(propertyInfo, typeof(IgnorePropertyAttribute));
     513             :                 }
     514             : 
     515             :                 /// <summary>
     516             :                 /// The object reference equality comparer.
     517             :                 /// </summary>
     518             :                 private class ObjectReferenceEqualityComparer : IEqualityComparer<object>
     519             :                 {
     520             :                         /// <summary>
     521             :                         /// Determines whether the specified object instances are considered equal.
     522             :                         /// </summary>
     523             :                         /// <param name="x">The first object to compare.</param>
     524             :                         /// <param name="y">The second object to compare.</param>
     525             :                         /// <returns>true if the objects are considered equal; otherwise, false. If both objA and objB are null, the method returns true.</returns>
     526           1 :                         public new bool Equals(object x, object y)
     527             :                         {
     528             :                                 return ReferenceEquals(x, y);
     529             :                         }
     530             : 
     531             :                         /// <summary>
     532             :                         /// Serves as a hash function for a particular type.
     533             :                         /// </summary>
     534             :                         /// <returns>A hash code for the current <see cref="object"/>.</returns>
     535           1 :                         public int GetHashCode(object obj)
     536             :                         {
     537             :                                 return RuntimeHelpers.GetHashCode(obj);
     538             :                         }
     539             :                 }
     540             :         }
     541             : 
     542             :         internal class SR
     543             :         {
     544             :                 public const string AbsoluteAddressNotPermitted = "Address '{0}' is an absolute address. Only relative addresses are permitted.";
     545             :                 public const string AccountNameMismatch = "Account names do not match.  First account name is {0}, second is {1}.";
     546             :                 public const string ArgumentEmptyError = "The argument must not be empty string.";
     547             :                 public const string ArgumentOutOfRangeError = "The argument is out of range. Value passed: {0}";
     548             :                 public const string ArgumentTooLargeError = "The argument '{0}' is larger than maximum of '{1}'";
     549             :                 public const string ArgumentTooSmallError = "The argument '{0}' is smaller than minimum of '{1}'";
     550             :                 public const string AttemptedEdmTypeForTheProperty = "Attempting to deserialize '{0}' as type '{1}'";
     551             :                 public const string BatchWithRetreiveContainsOtherOperations = "A batch transaction with a retrieve operation cannot contain any other operations.";
     552             :                 public const string BatchExceededMaximumNumberOfOperations = "The maximum number of operations allowed in one batch has been exceeded.";
     553             :                 public const string BatchOperationRequiresPartitionKeyRowKey = "A batch non-retrieve operation requires a non-null partition key and row key.";
     554             :                 public const string BatchErrorInOperation = "Element {0} in the batch returned an unexpected response code.";
     555             :                 public const string BinaryMessageShouldUseBase64Encoding = "EncodeMessage should be true for binary message.";
     556             :                 public const string Blob = "blob";
     557             :                 public const string BlobDataCorrupted = "Blob data corrupted (integrity check failed), Expected value is '{0}', retrieved '{1}'";
     558             :                 public const string BlobEndPointNotConfigured = "No blob endpoint configured.";
     559             :                 public const string BlobInvalidSequenceNumber = "The sequence number may not be specified for an increment operation.";
     560             :                 public const string BlobOverMaxBlockLimit = "The total blocks required for this upload exceeds the maximum block limit. Please increase the block size if applicable and ensure the Blob size is not greater than the maximum Blob size limit.";
     561             :                 public const string BlobStreamAlreadyCommitted = "Blob stream has already been committed once.";
     562             :                 public const string BlobStreamFlushPending = "Blob stream has a pending flush operation. Please call EndFlush first.";
     563             :                 public const string BlobStreamReadPending = "Blob stream has a pending read operation. Please call EndRead first.";
     564             :                 public const string BlobTypeMismatch = "Blob type of the blob reference doesn't match blob type of the blob.";
     565             :                 public const string BufferTooSmall = "The provided buffer is too small to fit in the blob data given the offset.";
     566             :                 public const string BufferManagerProvidedIncorrectLengthBuffer = "The IBufferManager provided an incorrect length buffer to the stream, Expected {0}, received {1}. Buffer length should equal the value returned by IBufferManager.GetDefaultBufferSize().";
     567             :                 public const string CannotCreateSASSignatureForGivenCred = "Cannot create Shared Access Signature as the credentials does not have account name information. Please check that the credentials used support creating Shared Access Signature.";
     568             :                 public const string CannotCreateSASWithoutAccountKey = "Cannot create Shared Access Signature unless Account Key credentials are used.";
     569             :                 public const string CannotModifySnapshot = "Cannot perform this operation on a blob representing a snapshot.";
     570             :                 public const string CannotModifyShareSnapshot = "Cannot perform this operation on a share representing a snapshot.";
     571             :                 public const string CannotTransformNonHttpsUriWithHttpsOnlyCredentials = "Cannot transform a Uri object using a StorageCredentials object that is marked HTTPS only.";
     572             :                 public const string CannotUpdateKeyWithoutAccountKeyCreds = "Cannot update key unless Account Key credentials are used.";
     573             :                 public const string CannotUpdateSasWithoutSasCreds = "Cannot update Shared Access Signature unless Sas credentials are used.";
     574             :                 public const string ConcurrentOperationsNotSupported = "Could not acquire exclusive use of the TableServiceContext, Concurrent operations are not supported.";
     575             :                 public const string Container = "container";
     576             :                 public const string ContentMD5NotCalculated = "The operation requires a response body but no data was copied to the destination buffer.";
     577             :                 public const string CopyAborted = "The copy operation has been aborted by the user.";
     578             :                 public const string CopyFailed = "The copy operation failed with the following error message: {0}";
     579             :                 public const string CryptoError = "Cryptographic error occurred. Please check the inner exception for more details.";
     580             :                 public const string CryptoFunctionFailed = "Crypto function failed with error code '{0}'";
     581             :                 public const string DecryptionLogicError = "Decryption logic threw error. Please check the inner exception for more details.";
     582             :                 public const string DeleteSnapshotsNotValidError = "The option '{0}' must be 'None' to delete a specific snapshot specified by '{1}'";
     583             :                 public const string Directory = "directory";
     584             :                 public const string EmptyBatchOperation = "Cannot execute an empty batch operation";
     585             :                 public const string EncryptedMessageTooLarge = "Encrypted Messages cannot be larger than {0} bytes. Please note that encrypting queue messages can increase their size.";
     586             :                 public const string EncryptionDataNotPresentError = "Encryption data does not exist. If you do not want to decrypt the data, please do not set the RequireEncryption flag on request options.";
     587             :                 public const string EncryptionLogicError = "Encryption logic threw error. Please check the inner exception for more details.";
     588             :                 public const string EncryptedMessageDeserializingError = "Error while de-serializing the encrypted queue message string from the wire. Please check inner exception for more details.";
     589             :                 public const string EncryptionNotSupportedForOperation = "Encryption is not supported for the current operation. Please ensure that EncryptionPolicy is not set on RequestOptions.";
     590             :                 public const string EncryptingNullPropertiesNotAllowed = "Null properties cannot be encrypted. Please assign a default value to the property if you wish to encrypt it.";
     591             :                 public const string EncryptionMetadataError = "Error while de-serializing the encryption metadata string from the wire.";
     592             :                 public const string EncryptionNotSupportedForExistingBlobs = "Encryption is not supported for a blob that already exists. Please do not specify an encryption policy.";
     593             :                 public const string EncryptionNotSupportedForFiles = "Encryption is not supported for files.";
     594             :                 public const string EncryptionNotSupportedForPageBlobsOnPhone = "Encryption is not supported for PageBlobs on Windows Phone.";
     595             :                 public const string EncryptionPolicyMissingInStrictMode = "Encryption Policy is mandatory when RequireEncryption is set to true. If you do not want to encrypt/decrypt data, please set RequireEncryption to false in request options.";
     596             :                 public const string EncryptionProtocolVersionInvalid = "Invalid Encryption Agent. This version of the client library does not understand the Encryption Agent set on the blob.";
     597             :                 public const string ETagMissingForDelete = "Delete requires an ETag (which may be the '*' wildcard).";
     598             :                 public const string ETagMissingForMerge = "Merge requires an ETag (which may be the '*' wildcard).";
     599             :                 public const string ETagMissingForReplace = "Replace requires an ETag (which may be the '*' wildcard).";
     600             :                 public const string ExceptionOccurred = "An exception has occurred. For more information please deserialize this message via RequestResult.TranslateFromExceptionMessage.";
     601             :                 public const string ExtendedErrorUnavailable = "An unknown error has occurred, extended error information not available.";
     602             :                 public const string File = "file";
     603             :                 public const string FileDataCorrupted = "File data corrupted (integrity check failed), Expected value is '{0}', retrieved '{1}'";
     604             :                 public const string FileEndPointNotConfigured = "No file endpoint configured.";
     605             :                 public const string FileStreamAlreadyCommitted = "File stream has already been committed once.";
     606             :                 public const string FileStreamFlushPending = "File stream has a pending flush operation. Please call EndFlush first.";
     607             :                 public const string FileStreamReadPending = "File stream has a pending read operation. Please call EndRead first.";
     608             :                 public const string FailParseProperty = "Failed to parse property '{0}' with value '{1}' as type '{2}'";
     609             :                 public const string GetServiceStatsInvalidOperation = "GetServiceStats cannot be run with a 'PrimaryOnly' location mode.";
     610             :                 public const string IncorrectNumberOfBytes = "Incorrect number of bytes received. Expected '{0}', received '{1}'";
     611             :                 public const string InternalStorageError = "Unexpected internal storage client error.";
     612             :                 public const string InvalidAclType = "Invalid acl public access type returned '{0}'. Expected blob or container.";
     613             :                 public const string InvalidBlobListItem = "Invalid blob list item returned";
     614             :                 public const string InvalidCorsRule = "A CORS rule must contain at least one allowed origin and allowed method, and MaxAgeInSeconds cannot have a value less than zero.";
     615             :                 public const string InvalidDelimiter = "\\ is an invalid delimiter.";
     616             :                 public const string InvalidFileAclType = "Invalid acl public access type returned '{0}'. Expected file or share.";
     617             :                 public const string InvalidEncryptionAlgorithm = "Invalid Encryption Algorithm found on the resource. This version of the client library does not support the specified encryption algorithm.";
     618             :                 public const string InvalidEncryptionMode = "Invalid BlobEncryptionMode set on the policy. Please set it to FullBlob when the policy is used with UploadFromStream.";
     619             :                 public const string InvalidFileListItem = "Invalid file list item returned";
     620             :                 public const string InvalidGeoReplicationStatus = "Invalid geo-replication status in response: '{0}'";
     621             :                 public const string InvalidHeaders = "Headers are not supported in the 2012-02-12 version.";
     622             :                 public const string InvalidIPAddress = "Error when parsing IP address: IP address is invalid.";
     623             :                 public const string InvalidLeaseStatus = "Invalid lease status in response: '{0}'";
     624             :                 public const string InvalidLeaseState = "Invalid lease state in response: '{0}'";
     625             :                 public const string InvalidLeaseDuration = "Invalid lease duration in response: '{0}'";
     626             :                 public const string InvalidListingDetails = "Invalid blob listing details specified.";
     627             :                 public const string InvalidLoggingLevel = "Invalid logging operations specified.";
     628             :                 public const string InvalidMetricsLevel = "Invalid metrics level specified.";
     629             :                 public const string InvalidBlockSize = "Append block data should not exceed the maximum blob size condition value.";
     630             :                 public const string InvalidPageSize = "Page data must be a multiple of 512 bytes.";
     631             :                 public const string InvalidProtocolsInSAS = "Invalid value {0} for the SharedAccessProtocol parameter when creating a SharedAccessSignature.  Use 'null' if you do not wish to include a SharedAccessProtocol.";
     632             :                 public const string InvalidResourceName = "Invalid {0} name. Check MSDN for more information about valid {0} naming.";
     633             :                 public const string InvalidResourceNameLength = "Invalid {0} name length. The {0} name must be between {1} and {2} characters long.";
     634             :                 public const string InvalidResourceReservedName = "Invalid {0} name. This {0} name is reserved.";
     635             :                 public const string InvalidSASVersion = "SAS Version invalid. Valid versions include 2012-02-12 and 2013-08-15.";
     636             :                 public const string InvalidStorageService = "Invalid storage service specified.";
     637             :                 public const string IPAddressOrRangeMustBeNullInOldVersion = "IPAddressOrRange must be null when creating a SAS token with an older service version parameter.";
     638             :                 public const string IPMustBeIPV4InSAS = "When specifying an IP Address in a SAS token, it must be an IPv4 address. Input address was {0}.";
     639             :                 public const string IQueryableExtensionObjectMustBeTableQuery = "Query must be a TableQuery<T>";
     640             :                 public const string JsonNotSupportedOnRT = "JSON payloads are not supported in Windows Runtime.";
     641             :                 public const string JsonReaderNotInCompletedState = "The JSON reader has not yet reached the completed state.";
     642             :                 public const string KeyAndResolverMissingError = "Key and Resolver are not initialized. Decryption requires either of them to be initialized.";
     643             :                 public const string KeyMismatch = "Key mismatch. The key id stored on the service does not match the specified key.";
     644             :                 public const string KeyMissingError = "Key is not initialized. Encryption requires it to be initialized.";
     645             :                 public const string KeyResolverCannotResolveExistingKey = "KeyResolver is not able to resolve the existing encryption key used to encrypt this blob.";
     646             :                 public const string KeyRotationInvalidAccessCondition = @"Cannot supply an AccessCondition with an ETag or Modified-Since condition for key rotation.  An If-Match condition will be automatically applied.";
     647             :                 public const string KeyRotationNoEncryptionKey = "Must supply a new encryption key as the Encryption Policy's \"Key\" parameter when rotating encryption keys.";
     648             :                 public const string KeyRotationNoEncryptionKeyResolver = "Must supply a key resolver on the encryption policy when rotating encryption keys.";
     649             :                 public const string KeyRotationNoEncryptionMetadata = "Cannot rotate the encryption key when encryption metadata is not available on the blob.  Either the blob is not encrypted, or you need to call FetchAttributes before calling this method.";
     650             :                 public const string KeyRotationNoEncryptionPolicy = "Encryption Policy on the Request Options cannot be null for an encryption key rotation call.";
     651             :                 public const string KeyRotationNoEtag = "Cannot rotate the encryption key when the ETag is not available on the blob.  You need to call FetchAttributes before calling this method.";
     652             :                 public const string KeyRotationNoKeyID = "Cannot rotate encryption key when the encryption metadata does not contain a KeyID.";
     653             :                 public const string KeyRotationPreconditionFailed = "Precondition failed.  If this is due to an incorrect ETag value, call FetchAttributes on the local blob object and retry rotating the encryption key.";
     654             :                 public const string LeaseConditionOnSource = "A lease condition cannot be specified on the source of a copy.";
     655             :                 public const string LeaseTimeNotReceived = "Valid lease time expected but not received from the service.";
     656             :                 public const string LengthNotInRange = "The length provided is out of range. The range must be between 0 and the length of the byte array.";
     657             :                 public const string ListSnapshotsWithDelimiterError = "Listing snapshots is only supported in flat mode (no delimiter). Consider setting the useFlatBlobListing parameter to true.";
     658             :                 public const string LogStreamEndError = "Error parsing log record: unexpected end of stream at position '{0}'.";
     659             :                 public const string LogStreamDelimiterError = "Error parsing log record: expected the delimiter '{0}', but read '{1}' at position '{2}'.";
     660             :                 public const string LogStreamParseError = "Error parsing log record: could not parse '{0}' using format: {1}";
     661             :                 public const string LogStreamQuoteError = "Error parsing log record: unexpected quote character found. String so far: '{0}'. Character read: '{1}'";
     662             :                 public const string LogVersionUnsupported = "A storage log version of {0} is unsupported.";
     663             :                 public const string LoggingVersionNull = "The logging version is null or empty.";
     664             :                 public const string MD5MismatchError = "Calculated MD5 does not match existing property";
     665             :                 public const string MD5NotPossible = "MD5 cannot be calculated for an existing blob because it would require reading the existing data. Please disable StoreBlobContentMD5.";
     666             :                 public const string MD5NotPresentError = "MD5 does not exist. If you do not want to force validation, please disable UseTransactionalMD5.";
     667             :                 public const string MessageTooLarge = "Messages cannot be larger than {0} bytes.";
     668             :                 public const string MetricVersionNull = "The metrics version is null or empty.";
     669             :                 public const string MissingAccountInformationInUri = "Cannot find account information inside Uri '{0}'";
     670             :                 public const string MissingContainerInformation = "Invalid blob address '{0}', missing container information";
     671             :                 public const string MissingCredentials = "No credentials provided.";
     672             :                 public const string MissingLeaseIDChanging = "A lease ID must be specified when changing a lease.";
     673             :                 public const string MissingLeaseIDReleasing = "A lease ID must be specified when releasing a lease.";
     674             :                 public const string MissingLeaseIDRenewing = "A lease ID must be specified when renewing a lease.";
     675             :                 public const string MissingMandatoryParametersForSAS = "Missing mandatory parameters for valid Shared Access Signature";
     676             :                 public const string MissingShareInformation = "Invalid file address '{0}', missing share information";
     677             :                 public const string MissingWrappingIV = "A key wrapping IV must be present in the encryption metadata while decrypting.";
     678             :                 public const string StorageUriMustMatch = "Primary and secondary location URIs in a StorageUri must point to the same resource.";
     679             :                 public const string MultipleCredentialsProvided = "Cannot provide credentials as part of the address and as constructor parameter. Either pass in the address or use a different constructor.";
     680             :                 public const string MultipleSnapshotTimesProvided = "Multiple different snapshot times provided as part of query '{0}' and as constructor parameter '{1}'.";
     681             :                 public const string NegativeBytesRequestedInCopy = "Internal Error - negative copyLength requested when attempting to copy a stream.  CopyLength = {0}, totalBytes = {1}, total bytes recorded so far = {2}.";
     682             :                 public const string NoPropertyResolverAvailable = "No property resolver available. Deserializing the entity properties as strings.";
     683             :                 public const string OffsetNotInRange = "The offset provided is out of range. The range must be between 0 and the length of the byte array.";
     684             :                 public const string ODataReaderNotInCompletedState = "OData Reader state expected to be Completed state. Actual state: {0}.";
     685             :                 public const string OperationCanceled = "Operation was canceled by user.";
     686             :                 public const string ParseError = "Error parsing value";
     687             :                 public const string PartitionKey = "All entities in a given batch must have the same partition key.";
     688             :                 public const string PathStyleUriMissingAccountNameInformation = "Missing account name information inside path style uri. Path style uris should be of the form http://<IPAddressPlusPort>/<accountName>";
     689             :                 public const string PayloadFormat = "Setting payload format for the request to '{0}'.";
     690             :                 public const string PreconditionFailed = "The condition specified using HTTP conditional header(s) is not met.";
     691             :                 public const string PreconditionFailureIgnored = "Pre-condition failure on a retry is being ignored since the request should have succeeded in the first attempt.";
     692             :                 public const string PrimaryOnlyCommand = "This operation can only be executed against the primary storage location.";
     693             :                 public const string PropertyDelimiterExistsInPropertyName = "Property delimiter: {0} exists in property name: {1}. Object Path: {2}";
     694             :                 public const string PropertyResolverCacheDisabled = "Property resolver cache is disabled.";
     695             :                 public const string PropertyResolverThrewError = "The custom property resolver delegate threw an exception. Check the inner exception for more details.";
     696             :                 public const string ProtocolsMustBeNullInOldVersion = "SharedAccessProtocol must be null when creating a SAS token with an older service version parameter.";
     697             :                 public const string PutBlobNeedsStoreBlobContentMD5 = "When uploading a blob in a single request, StoreBlobContentMD5 must be set to true if UseTransactionalMD5 is true, because the MD5 calculated for the transaction will be stored in the blob.";
     698             :                 public const string QueryBuilderKeyNotFound = "'{0}' key not found in the query builder.";
     699             :                 public const string Queue = "queue";
     700             :                 public const string QueueEndPointNotConfigured = "No queue endpoint configured.";
     701             :                 public const string RangeDownloadNotPermittedOnPhone = "Windows Phone does not support downloading closed ranges from an encrypted blob. Please download the full blob or an open range (by specifying length as null)";
     702             :                 public const string RecursiveReferencedObject = "Recursive reference detected. Object Path: {0} Property Type: {1}.";
     703             :                 public const string RelativeAddressNotPermitted = "Address '{0}' is a relative address. Only absolute addresses are permitted.";
     704             :                 public const string ResourceConsumed = "Resource consumed";
     705             :                 public const string ResourceNameEmpty = "Invalid {0} name. The {0} name may not be null, empty, or whitespace only.";
     706             :                 public const string RetrieveWithContinuationToken = "Retrieved '{0}' results with continuation token '{1}'.";
     707             :                 public const string SecondaryOnlyCommand = "This operation can only be executed against the secondary storage location.";
     708             :                 public const string SetServicePropertiesRequiresNonNullSettings = "At least one service property needs to be non-null for SetServiceProperties API.";
     709             :                 public const string Share = "share";
     710             :                 public const string StartTimeExceedsEndTime = "StartTime invalid. The start time '{0}' occurs after the end time '{1}'.";
     711             :                 public const string StorageUriMissingLocation = "The Uri for the target storage location is not specified. Please consider changing the request's location mode.";
     712             :                 public const string StreamLengthError = "The length of the stream exceeds the permitted length.";
     713             :                 public const string StreamLengthMismatch = "Cannot specify both copyLength and maxLength.";
     714             :                 public const string StreamLengthShortError = "The requested number of bytes exceeds the length of the stream remaining from the specified position.";
     715             :                 public const string Table = "table";
     716             :                 public const string TableEndPointNotConfigured = "No table endpoint configured.";
     717             :                 public const string TableQueryDynamicPropertyAccess = "Accessing property dictionary of DynamicTableEntity requires a string constant for property name.";
     718             :                 public const string TableQueryEntityPropertyInQueryNotSupported = "Referencing {0} on EntityProperty only supported with properties dictionary exposed via DynamicTableEntity.";
     719             :                 public const string TableQueryFluentMethodNotAllowed = "Fluent methods may not be invoked on a Query created via CloudTable.CreateQuery<T>()";
     720             :                 public const string TableQueryMustHaveQueryProvider = "Unknown Table. The TableQuery does not have an associated CloudTable Reference. Please execute the query via the CloudTable ExecuteQuery APIs.";
     721             :                 public const string TableQueryTypeMustImplementITableEnitty = "TableQuery Generic Type must implement the ITableEntity Interface";
     722             :                 public const string TableQueryTypeMustHaveDefaultParameterlessCtor = "TableQuery Generic Type must provide a default parameterless constructor.";
     723             :                 public const string TakeCountNotPositive = "Take count must be positive and greater than 0.";
     724             :                 public const string TimeoutExceptionMessage = "The client could not finish the operation within specified timeout.";
     725             :                 public const string TooManyPolicyIdentifiers = "Too many '{0}' shared access policy identifiers provided. Server does not support setting more than '{1}' on a single container, queue, table, or share.";
     726             :                 public const string TooManyPathSegments = "The count of URL path segments (strings between '/' characters) as part of the blob name cannot exceed 254.";
     727             :                 public const string TraceAbort = "Aborting pending request due to timeout.";
     728             :                 public const string TraceAbortError = "Could not abort pending request because of {0}.";
     729             :                 public const string TraceAbortRetry = "Aborting pending retry due to user request.";
     730             :                 public const string TraceDispose = "Disposing action invoked.";
     731             :                 public const string TraceDisposeError = "Disposing action threw an exception : {0}.";
     732             :                 public const string TraceDownload = "Downloading response body.";
     733             :                 public const string TraceDownloadError = "Downloading error response body.";
     734             :                 public const string TraceRetryInfo = "The extended retry policy set the next location to {0} and updated the location mode to {1}.";
     735             :                 public const string TraceGenericError = "Exception thrown during the operation: {0}.";
     736             :                 public const string TraceGetResponse = "Waiting for response.";
     737             :                 public const string TraceGetResponseError = "Exception thrown while waiting for response: {0}.";
     738             :                 public const string TraceIgnoreAttribute = "Omitting property '{0}' from serialization/de-serialization because IgnoreAttribute has been set on that property.";
     739             :                 public const string TraceInitLocation = "Starting operation with location {0} per location mode {1}.";
     740             :                 public const string TraceInitRequestError = "Exception thrown while initializing request: {0}.";
     741             :                 public const string TraceMissingDictionaryEntry = "Omitting property '{0}' from de-serialization because there is no corresponding entry in the dictionary provided.";
     742             :                 public const string TraceNextLocation = "The next location has been set to {0}, based on the location mode.";
     743             :                 public const string TraceNonPublicGetSet = "Omitting property '{0}' from serialization/de-serialization because the property's getter/setter are not public.";
     744             :                 public const string TraceNonExistingGetter = "Omitting property: {0} from serialization/de-serialization because the property does not have a getter. Object path: {1}";
     745             :                 public const string TraceNonExistingSetter = "Omitting property: {0} from serialization/de-serialization because the property does not have a setter."
     746             :                         + " The property needs to have at least a private setter. Object Path: {1}";
     747             :                 public const string TracePrepareUpload = "Preparing to write request data.";
     748             :                 public const string TracePrepareUploadError = "Exception thrown while preparing to write request data: {0}.";
     749             :                 public const string TracePreProcessDone = "Response headers were processed successfully, proceeding with the rest of the operation.";
     750             :                 public const string TracePreProcessError = "Exception thrown while processing response: {0}.";
     751             :                 public const string TracePostProcess = "Processing response body.";
     752             :                 public const string TracePostProcessError = "Exception thrown while ending operation: {0}.";
     753             :                 public const string TraceResponse = "Response received. Status code = {0}, Request ID = {1}, Content-MD5 = {2}, ETag = {3}.";
     754             :                 public const string TraceRetry = "Retrying failed operation.";
     755             :                 public const string TraceRetryCheck = "Checking if the operation should be retried. Retry count = {0}, HTTP status code = {1}, Retryable exception = {2}, Exception = {3}.";
     756             :                 public const string TraceRetryDecisionPolicy = "Retry policy did not allow for a retry. Failing with {0}.";
     757             :                 public const string TraceRetryDecisionTimeout = "Operation cannot be retried because the maximum execution time has been reached. Failing with {0}.";
     758             :                 public const string TraceRetryDelay = "Operation will be retried after {0}ms.";
     759             :                 public const string TraceRetryError = "Exception thrown while retrying operation: {0}.";
     760             :                 public const string TraceSetPropertyError = "Exception thrown while trying to set property value. Property Path: {0} Property Value: {1}. Exception Message: {2}";
     761             :                 public const string TraceStartRequestAsync = "Starting asynchronous request to {0}.";
     762             :                 public const string TraceStartRequestSync = "Starting synchronous request to {0}.";
     763             :                 public const string TraceStringToSign = "StringToSign = {0}.";
     764             :                 public const string TraceSuccess = "Operation completed successfully.";
     765             :                 public const string TraceUpload = "Writing request data.";
     766             :                 public const string TraceUploadError = "Exception thrown while writing request data: {0}.";
     767             :                 public const string UndefinedBlobType = "The blob type cannot be undefined.";
     768             :                 public const string UnexpectedElement = "Unexpected Element '{0}'";
     769             :                 public const string UnexpectedEmptyElement = "Unexpected Empty Element '{0}'";
     770             :                 public const string UnexpectedParameterInSAS = "The parameter `api-version` should not be included in the SAS token. Please allow the library to set the  `api-version` parameter.";
     771             :                 public const string UnexpectedContinuationType = "Unexpected Continuation Type";
     772             :                 public const string UnexpectedLocation = "Unexpected Location '{0}'";
     773             :                 public const string UnexpectedResponseCode = "Unexpected response code, Expected:{0}, Received:{1}";
     774             :                 public const string UnsupportedPropertyTypeForEncryption = "Unsupported type : {0} encountered during encryption. Only string properties can be encrypted on the client side.";
     775             :                 public const string UnsupportedPropertyTypeForEntityPropertyConversion = "Unsupported type : {0} encountered during conversion to EntityProperty. Object Path: {1}";
     776             :                 public const string UpdateMessageVisibilityRequired = "Calls to UpdateMessage must include the Visibility flag.";
     777             :                 public const string UsingDefaultPropertyResolver = "Using the default property resolver to deserialize the entity.";
     778             :                 public const string UsingUserProvidedPropertyResolver = "Using the property resolver provided via TableRequestOptions to deserialize the entity.";
     779             : 
     780             : #if WINDOWS_PHONE && WINDOWS_DESKTOP
     781             :                 public const string WindowsPhoneDoesNotSupportMD5 = "MD5 is not supported on Windows Phone";
     782             : #endif
     783             :                 // Table IQueryable Exception messages
     784             :                 public const string ALinqCouldNotConvert = "Could not convert constant {0} expression to string.";
     785             :                 public const string ALinqMethodNotSupported = "The method '{0}' is not supported.";
     786             :                 public const string ALinqUnaryNotSupported = "The unary operator '{0}' is not supported.";
     787             :                 public const string ALinqBinaryNotSupported = "The binary operator '{0}' is not supported.";
     788             :                 public const string ALinqConstantNotSupported = "The constant for '{0}' is not supported.";
     789             :                 public const string ALinqTypeBinaryNotSupported = "An operation between an expression and a type is not supported.";
     790             :                 public const string ALinqConditionalNotSupported = "The conditional expression is not supported.";
     791             :                 public const string ALinqParameterNotSupported = "The parameter expression is not supported.";
     792             :                 public const string ALinqMemberAccessNotSupported = "The member access of '{0}' is not supported.";
     793             :                 public const string ALinqLambdaNotSupported = "Lambda Expressions not supported.";
     794             :                 public const string ALinqNewNotSupported = "New Expressions not supported.";
     795             :                 public const string ALinqMemberInitNotSupported = "Member Init Expressions not supported.";
     796             :                 public const string ALinqListInitNotSupported = "List Init Expressions not supported.";
     797             :                 public const string ALinqNewArrayNotSupported = "New Array Expressions not supported.";
     798             :                 public const string ALinqInvocationNotSupported = "Invocation Expressions not supported.";
     799             :                 public const string ALinqUnsupportedExpression = "The expression type {0} is not supported.";
     800             :                 public const string ALinqCanOnlyProjectTheLeaf = "Can only project the last entity type in the query being translated.";
     801             :                 public const string ALinqCantCastToUnsupportedPrimitive = "Can't cast to unsupported type '{0}'";
     802             :                 public const string ALinqCantTranslateExpression = "The expression {0} is not supported.";
     803             :                 public const string ALinqCantNavigateWithoutKeyPredicate = "Navigation properties can only be selected from a single resource. Specify a key predicate to restrict the entity set to a single instance.";
     804             :                 public const string ALinqCantReferToPublicField = "Referencing public field '{0}' not supported in query option expression.  Use public property instead.";
     805             :                 public const string ALinqCannotConstructKnownEntityTypes = "Construction of entity type instances must use object initializer with default constructor.";
     806             :                 public const string ALinqCannotCreateConstantEntity = "Referencing of local entity type instances not supported when projecting results.";
     807             :                 public const string ALinqExpressionNotSupportedInProjectionToEntity = "Initializing instances of the entity type {0} with the expression {1} is not supported.";
     808             :                 public const string ALinqExpressionNotSupportedInProjection = "Constructing or initializing instances of the type {0} with the expression {1} is not supported.";
     809             :                 public const string ALinqProjectionMemberAssignmentMismatch = "Cannot initialize an instance of entity type '{0}' because '{1}' and '{2}' do not refer to the same source entity.";
     810             :                 public const string ALinqPropertyNamesMustMatchInProjections = "Cannot assign the value from the {0} property to the {1} property.  When projecting results into a entity type, the property names of the source type and the target type must match for the properties being projected.";
     811             :                 public const string ALinqQueryOptionOutOfOrder = "The {0} query option cannot be specified after the {1} query option.";
     812             :                 public const string ALinqQueryOptionsOnlyAllowedOnLeafNodes = "Can only specify query options (orderby, where, take, skip) after last navigation.";
     813             :         }
     814             : }

Generated by: LCOV version 1.12