/// <inheritdoc />
        public async Task <TElement> UpdateAsync(
            TElement entity,
            TableStorageStrategy strategy = TableStorageStrategy.InsertOrReplace)
        {
            if (entity == null)
            {
                throw new ArgumentNullException(nameof(entity));
            }
            if (entity.PartitionKey == null)
            {
                throw new PropNullException(nameof(entity.PartitionKey));
            }
            if (entity.RowKey == null)
            {
                throw new PropNullException(nameof(entity.RowKey));
            }

            try
            {
                await CreateTableIfNotExistsAsync();

                if (strategy == TableStorageStrategy.Merge ||
                    strategy == TableStorageStrategy.Replace)
                {
                    var any = await AnyAsync(entity.PartitionKey, entity.RowKey);

                    if (!any)
                    {
                        throw new InvalidOperationException(
                                  UtilResources.Get("TableStorageEntityNotExists",
                                                    entity.PartitionKey, entity.RowKey));
                    }

                    entity.ETag ??= "*";
                }

                var operation = strategy switch
                {
                    TableStorageStrategy.InsertOrMerge
                    => TableOperation.InsertOrMerge(entity),
                    TableStorageStrategy.Merge
                    => TableOperation.Merge(entity),
                    TableStorageStrategy.Replace
                    => TableOperation.Replace(entity),
                    _
                    => TableOperation.InsertOrReplace(entity),
                };

                var result = await ExecuteAsync(operation);

                ExceptionChecker.AssertHttp200Code(result.HttpStatusCode);

                entity = (TElement)(dynamic)result.Result;
                return(entity);
            }
            catch (Exception ex)
            {
                throw new TableStorageException(nameof(UpdateAsync), ex);
            }
        }
        /// <summary>
        /// Reads the content of an embedded JSON file into the specified
        /// output type.
        /// </summary>
        /// <typeparam name="TOutputType">The type to which the JSON file will be
        /// loaded.</typeparam>
        /// <param name="fileName">The case-sensitive name of the manifest resource
        /// being requested without including the assembly namespace.
        /// E.g.: "FolderName.FileName.json".</param>
        /// <param name="assembly">The assembly where we get the resource. If
        /// null, we search the resource into the calling assembly.</param>
        /// <param name="serializeAll">Indicates whether all props should be
        /// serialized without taking into account the JsonIgnore attribute.</param>
        /// <returns>Content of the embedded JSON file loaded into the
        /// specified Type.</returns>
        /// <exception cref="FileNotFoundException">The embedded JSON file could not
        /// be found.</exception>
        /// <exception cref="FileLoadException">There was an error when trying to
        /// load the content of the JSON file into the specified output type.
        /// </exception>
        public static TOutputType ReadJson <TOutputType>(
            string fileName, Assembly assembly = null, bool serializeAll = true)
        {
            if (assembly == null)
            {
                assembly = Assembly.GetCallingAssembly();
            }

            var content = ReadFile(fileName, assembly);

            try
            {
                if (serializeAll)
                {
                    var settings = new JsonSerializerSettings
                    {
                        ContractResolver = new SerializeAllContractResolver()
                    };

                    var obj = JsonConvert.DeserializeObject <TOutputType>(content, settings);
                    return(obj);
                }
                else
                {
                    var obj = JsonConvert.DeserializeObject <TOutputType>(content);
                    return(obj);
                }
            }
            catch
            {
                var msg = UtilResources.Get("ErrorDeserializingJson", typeof(TOutputType));
                throw new FileLoadException(msg, fileName);
            }
        }
Example #3
0
        /// <summary>
        /// Converts an enum to a list of strings. Description of each enum
        /// item is based on the DescriptionAttribute, if the enum item does not
        /// have a DescriptionAttribute, the enum name is took.
        /// </summary>
        /// <typeparam name="TEnum">Enum type.</typeparam>
        /// <returns>Enumeration converted to a list of strings.</returns>
        /// <exception cref="InvalidCastException">TEnum is not an enum.</exception>
        public static List <string> ToList <TEnum>() where TEnum : struct, IConvertible
        {
            var type = typeof(TEnum);

            if (!type.IsEnum)
            {
                throw new InvalidCastException(
                          UtilResources.Get("TypeIsNotAnEnum", type));
            }

            var list   = new List <string>();
            var fields = type.GetFields().OrderBy(field => field.MetadataToken);

            foreach (var field in fields)
            {
                if (field.IsStatic)
                {
                    var description = Attribute.GetCustomAttribute(
                        field, typeof(DescriptionAttribute)
                        ) is DescriptionAttribute descAttribute
                        ? descAttribute.Description
                        : field.Name;

                    list.Add(description);
                }
            }

            return(list);
        }
Example #4
0
        /// <summary>
        /// Gets an enum value from its DescriptionAttribute.
        /// </summary>
        /// <typeparam name="TEnum">Enum type.</typeparam>
        /// <param name="description">Description of the enum value to search.</param>
        /// <returns>Enum value for the given DescriptionAttribute.</returns>
        /// <param name="defaultVal">Value to return by default in case the description
        /// doesn't exist in the enum.</param>
        /// <exception cref="InvalidCastException">TEnum is not an enum.</exception>
        public static TEnum GetValueFromDescription <TEnum>(string description, TEnum defaultVal = default)
            where TEnum : struct, IConvertible
        {
            var type = typeof(TEnum);

            if (!type.IsEnum)
            {
                throw new InvalidCastException(
                          UtilResources.Get("TypeIsNotAnEnum", type));
            }

            foreach (var field in type.GetFields())
            {
                if (Attribute.GetCustomAttribute(
                        field, typeof(DescriptionAttribute)
                        ) is DescriptionAttribute attribute)
                {
                    if (attribute.Description == description)
                    {
                        return((TEnum)field.GetValue(null));
                    }
                }

                if (field.Name == description)
                {
                    return((TEnum)field.GetValue(null));
                }
            }

            return(defaultVal);
        }
Example #5
0
        /// <summary>
        /// Converts an enum to a list of objects.
        /// </summary>
        /// <typeparam name="TEnum">Enum type.</typeparam>
        /// <typeparam name="TList">List type.</typeparam>
        /// <param name="valueProp">Property name for the vale in the list.</param>
        /// <param name="descriptionProp">Property name for the description in the list.</param>
        /// <param name="codeProp">Property name for the code in the list.</param>
        /// <returns>Enumeration converted to a list of objects.</returns>
        /// <exception cref="InvalidCastException">TEnum is not an enum.</exception>
        public static List <TList> ToList <TEnum, TList>(
            string valueProp,
            string descriptionProp,
            string codeProp = null)
            where TEnum : struct, IConvertible
            where TList : class
        {
            var type = typeof(TEnum);

            if (!type.IsEnum)
            {
                throw new InvalidCastException(
                          UtilResources.Get("TypeIsNotAnEnum", type));
            }

            var list   = new List <TList>();
            var fields = type.GetFields().OrderBy(field => field.MetadataToken);

            foreach (var field in fields)
            {
                if (field.IsStatic)
                {
                    dynamic expando    = new ExpandoObject();
                    var     dictionary = expando as IDictionary <string, object>;

                    dictionary[valueProp] = (int)field.GetValue(null);

                    dictionary[descriptionProp] = Attribute.GetCustomAttribute(
                        field, typeof(DescriptionAttribute)
                        ) is DescriptionAttribute descAttribute
                            ? descAttribute.Description
                            : field.Name;

                    if (codeProp != null)
                    {
                        dictionary[codeProp] = Attribute.GetCustomAttribute(
                            field, typeof(CodeAttribute)
                            ) is CodeAttribute codeAttribute
                            ? codeAttribute.Code
                            : null;
                    }

                    var json = JsonConvert.SerializeObject(expando);
                    var obj  = JsonConvert.DeserializeObject <TList>(json);

                    list.Add(obj);
                }
            }

            return(list);
        }
Example #6
0
        /// <summary>
        /// Initializes a new instance of the class.
        /// </summary>
        /// <param name="assembly">The assembly where we get the resource files.
        /// </param>
        /// <param name="baseFileName">The base file name of the resource files.
        /// It includes the ResourcesPath and the TypeName. E.g.:
        /// "Resources.UtilResources".</param>
        /// <param name="culture">Culture for which the resource strings
        /// will be loaded.</param>
        /// <exception cref="ArgumentNullException">If assembly is null, or
        /// baseFileName is null or empty, or culture is null.</exception>
        public JsonStringLocalizer(
            Assembly assembly, string baseFileName, CultureInfo culture)
        {
            if (baseFileName != null && baseFileName.Length == 0)
            {
                throw new ArgumentException(
                          UtilResources.Get("ArgumentCanNotBeEmpty", nameof(baseFileName)));
            }

            _assembly     = assembly ?? throw new ArgumentNullException(nameof(assembly));
            _baseFileName = baseFileName ?? throw new ArgumentNullException(nameof(baseFileName));;
            _culture      = culture ?? throw new ArgumentNullException(nameof(culture));
            _allStrings   = GetAllStrings(includeParentCultures: true);
        }
Example #7
0
        /// <summary>
        /// Gets the maximun value of an enum.
        /// </summary>
        /// <typeparam name="TEnum">Enum type.</typeparam>
        /// <returns>Maximun value of the enum.</returns>
        /// <exception cref="InvalidCastException">TEnum is not an enum.</exception>
        public static int GetMax <TEnum>()
            where TEnum : struct, IConvertible
        {
            var type = typeof(TEnum);

            if (!type.IsEnum)
            {
                throw new InvalidCastException(
                          UtilResources.Get("TypeIsNotAnEnum", type));
            }

            var max = Enum.GetValues(typeof(TEnum)).Cast <int>().Max();

            return(max);
        }
Example #8
0
        /// <summary>
        /// Gets the CodeAttribute value of an enumeration matching the
        /// passed-in value.
        /// </summary>
        /// <typeparam name="TEnum">Enum type.</typeparam>
        /// <param name="value">Enum value.</param>
        /// <param name="defaultVal">Value to return by default in case the value doesn't
        /// exist in the enum.</param>
        /// <returns>Code of the enumeration.</returns>
        /// <exception cref="InvalidCastException">TEnum is not an enum.</exception>
        public static string GetCode <TEnum>(int value, string defaultVal = null)
            where TEnum : struct, IConvertible
        {
            var type = typeof(TEnum);

            if (!type.IsEnum)
            {
                throw new InvalidCastException(
                          UtilResources.Get("TypeIsNotAnEnum", type));
            }
            if (!Enum.IsDefined(typeof(TEnum), value))
            {
                return(defaultVal);
            }

            var code = ((Enum)Enum.ToObject(type, value)).GetCode(defaultVal);

            return(code);
        }
        /// <inheritdoc />
        public async Task <TElement> InsertAsync(TElement entity)
        {
            if (entity == null)
            {
                throw new ArgumentNullException(nameof(entity));
            }
            if (entity.PartitionKey == null)
            {
                throw new PropNullException(nameof(entity.PartitionKey));
            }
            if (entity.RowKey == null)
            {
                throw new PropNullException(nameof(entity.RowKey));
            }

            try
            {
                await CreateTableIfNotExistsAsync();

                var entityExists = await AnyAsync(entity.PartitionKey, entity.RowKey);

                if (entityExists)
                {
                    throw new InvalidOperationException(
                              UtilResources.Get("TableStorageEntityExists", entity.PartitionKey, entity.RowKey));
                }

                var operation = TableOperation.Insert(entity);
                var result    = await ExecuteAsync(operation);

                ExceptionChecker.AssertHttp200Code(result.HttpStatusCode);

                entity = (TElement)(dynamic)result.Result;
                return(entity);
            }
            catch (Exception ex)
            {
                throw new TableStorageException(nameof(InsertAsync), ex);
            }
        }
        /// <inheritdoc />
        public async Task <TElement> DeleteAsync(string partitionKey, string rowKey)
        {
            if (partitionKey == null)
            {
                throw new ArgumentNullException(nameof(partitionKey));
            }
            if (rowKey == null)
            {
                throw new ArgumentNullException(nameof(rowKey));
            }

            try
            {
                await CreateTableIfNotExistsAsync();

                var entity = await GetAsync(partitionKey, rowKey);

                if (entity == null)
                {
                    throw new InvalidOperationException(
                              UtilResources.Get("TableStorageEntityNotExists",
                                                partitionKey, rowKey));
                }

                var operation = TableOperation.Delete(entity);
                var result    = await ExecuteAsync(operation);

                ExceptionChecker.AssertHttp200Code(result.HttpStatusCode);

                entity = (TElement)(dynamic)result.Result;
                return(entity);
            }
            catch (Exception ex)
            {
                throw new TableStorageException(nameof(DeleteAsync), ex);
            }
        }
        /// <summary>
        /// Initializes a new instance of the class.
        /// </summary>
        /// <param name="config">Configuration to access the Table Storage.
        /// </param>
        /// <exception cref="ArgumentNullException">If config is null.
        /// </exception>
        /// <exception cref="PropNullOrEmptyException">If ConnectionString or
        /// TableName are null or empty.</exception>
        /// <exception cref="FormatException">If ConnectionString or TableName
        /// have an invalid format.</exception>
        /// <exception cref="ArgumentException">If TableName is a reserved
        /// table name.</exception>
        public TableStorageClient(TableStorageConfig config)
        {
            if (config == null)
            {
                throw new ArgumentNullException(nameof(config));
            }
            if (string.IsNullOrEmpty(config.ConnectionString))
            {
                throw new PropNullOrEmptyException(nameof(config.ConnectionString));
            }
            if (string.IsNullOrEmpty(config.TableName))
            {
                throw new PropNullOrEmptyException(nameof(config.TableName));
            }

            var isValidConnectionString = CloudStorageAccount.TryParse(
                config.ConnectionString, out _);

            if (!isValidConnectionString)
            {
                throw new FormatException(
                          UtilResources.Get("InvalidConnectionString"));
            }
            if (!config.TableName.IsValidTableName())
            {
                throw new FormatException(
                          UtilResources.Get("InvalidTableName", config.TableName));
            }
            if (ReservedTableNames.Contains(config.TableName))
            {
                throw new ArgumentException(
                          UtilResources.Get("TableStorageReservedName", config.TableName));
            }

            Config = config;
        }
        /// <summary>
        /// Reads the content of an embedded file existing into the
        /// specified assembly.
        /// </summary>
        /// <param name="fileName">The case-sensitive name of the manifest resource
        /// being requested without including the assembly namespace.
        /// E.g.: "FolderName.FileName.extension".</param>
        /// <param name="assembly">The assembly where we get the resource. If
        /// null, we search the resource into the calling assembly.</param>
        /// <returns>Content of the embedded file existing into the
        /// specified assembly.</returns>
        /// <exception cref="FileNotFoundException">The embedded file could not
        /// be found.</exception>
        public static string ReadFile(string fileName, Assembly assembly = null)
        {
            try
            {
                if (assembly == null)
                {
                    assembly = Assembly.GetCallingAssembly();
                }

                var namespce = assembly.FullName.Split(',')[0];
                fileName = $"{namespce}.{fileName}";

                using var stream = assembly.GetManifestResourceStream(fileName);
                using var reader = new StreamReader(stream);

                var content = reader.ReadToEnd();
                return(content);
            }
            catch
            {
                var msg = UtilResources.Get("ErrorReadingEmbeddedFile");
                throw new FileNotFoundException(msg, fileName);
            }
        }
 /// <summary>
 /// Initializes a new instance of the class.
 /// </summary>
 /// <param name="paramName">The name of the parameter that
 /// caused the current exception.</param>
 /// <param name="innerException">The exception that is the cause of
 /// the current exception, or a null reference if no inner exception
 /// is specified.</param>
 public ArgumentNullOrEmptyException(string paramName, Exception innerException)
     : base(UtilResources.Get("ArgumentNullOrEmptyException", paramName), innerException)
 {
 }
 /// <summary>
 /// Initializes a new instance of the class.
 /// </summary>
 /// <param name="operationName">The name of the operation that failed.
 /// </param>
 /// <param name="innerException">The exception that is the cause of
 /// the current exception.</param>
 public TableStorageException(string operationName, Exception innerException)
     : base(UtilResources.Get("TableStorageException", operationName, innerException.Message), innerException)
 {
 }