/// <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); } }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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) { }