diff --git a/.vs/DigitalData.Core/DesignTimeBuild/.dtbcache.v2 b/.vs/DigitalData.Core/DesignTimeBuild/.dtbcache.v2 index fa77479..eded374 100644 Binary files a/.vs/DigitalData.Core/DesignTimeBuild/.dtbcache.v2 and b/.vs/DigitalData.Core/DesignTimeBuild/.dtbcache.v2 differ diff --git a/.vs/DigitalData.Core/v17/.futdcache.v2 b/.vs/DigitalData.Core/v17/.futdcache.v2 index 6c71737..08a29a1 100644 Binary files a/.vs/DigitalData.Core/v17/.futdcache.v2 and b/.vs/DigitalData.Core/v17/.futdcache.v2 differ diff --git a/.vs/DigitalData.Core/v17/.suo b/.vs/DigitalData.Core/v17/.suo index 52a5dbc..fffeb3a 100644 Binary files a/.vs/DigitalData.Core/v17/.suo and b/.vs/DigitalData.Core/v17/.suo differ diff --git a/.vs/ProjectEvaluation/digitaldata.core.metadata.v6.1 b/.vs/ProjectEvaluation/digitaldata.core.metadata.v6.1 index 9265a88..8a6ec67 100644 Binary files a/.vs/ProjectEvaluation/digitaldata.core.metadata.v6.1 and b/.vs/ProjectEvaluation/digitaldata.core.metadata.v6.1 differ diff --git a/.vs/ProjectEvaluation/digitaldata.core.projects.v6.1 b/.vs/ProjectEvaluation/digitaldata.core.projects.v6.1 index 51932b4..fb6b85d 100644 Binary files a/.vs/ProjectEvaluation/digitaldata.core.projects.v6.1 and b/.vs/ProjectEvaluation/digitaldata.core.projects.v6.1 differ diff --git a/DigitalData.Core.API/ControllerExtensions.cs b/DigitalData.Core.API/ControllerExtensions.cs index fba7cfc..7e02ea3 100644 --- a/DigitalData.Core.API/ControllerExtensions.cs +++ b/DigitalData.Core.API/ControllerExtensions.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Mvc; +using DigitalData.Core.Contracts.Application; +using Microsoft.AspNetCore.Mvc; using System.Text; namespace DigitalData.Core.API @@ -44,5 +45,15 @@ namespace DigitalData.Core.API return controllerBase.StatusCode(500, sb.Length > 0 ? sb.ToString() : null); } + + /// + /// Returns an ObjectResult representing an internal server error (status code 500) with optional exception and message details. + /// + /// The ControllerBase instance representing the controller. + /// Optional. The exception that occurred, if any. + /// Optional. A custom error message to include in the response. + /// /// Optional. A custom error message key to include in the response. + /// An ObjectResult representing an internal server error (status code 500). + public static ObjectResult InnerServiceError(this ControllerBase controllerBase, IServiceMessage? serviceMessage = null) => controllerBase.StatusCode(500, serviceMessage); } } \ No newline at end of file diff --git a/DigitalData.Core.Application/LoggerExtensions.cs b/DigitalData.Core.Application/LoggerExtensions.cs new file mode 100644 index 0000000..d18a435 --- /dev/null +++ b/DigitalData.Core.Application/LoggerExtensions.cs @@ -0,0 +1,41 @@ +using DigitalData.Core.Contracts.Application; +using Microsoft.Extensions.Logging; + +namespace DigitalData.Core.Application +{ + /// + /// Provides extension methods for ILogger to handle logging of message collections and service messages more effectively. + /// + public static class LoggerExtensions + { + /// + /// Logs a list of messages at the specified log level. + /// + /// The extended ILogger instance. + /// The severity level of the log entry. + /// The collection of messages to log. + /// The separator used to join messages. Default is newline. + /// Additional arguments used for formatting the log message. + public static void LogMessageList(this ILogger logger, LogLevel logLevel, IEnumerable messages, string separator = "\n", params object?[] args) + { + if (messages.Any()) + logger.Log(logLevel: logLevel, message: string.Join(separator, messages), args); + } + + /// + /// Logs all messages from a service message instance, categorized by message type to appropriate log levels. + /// + /// The extended ILogger instance. + /// The service message instance containing categorized messages. + /// The separator used to join messages within each category. Default is newline. + public static void LogServiceMessage(this ILogger logger, IServiceMessage serviceMessage, string separator = "\n") + { + logger.LogMessageList(LogLevel.Trace, serviceMessage.TraceMessages, separator); + logger.LogMessageList(LogLevel.Debug, serviceMessage.DebugMessages, separator); + logger.LogMessageList(LogLevel.Information, serviceMessage.InformationMessages, separator); + logger.LogMessageList(LogLevel.Warning, serviceMessage.WarningMessages, separator); + logger.LogMessageList(LogLevel.Error, serviceMessage.ErrorMessages, separator); + logger.LogMessageList(LogLevel.Critical, serviceMessage.CriticalMessages, separator); + } + } +} \ No newline at end of file diff --git a/DigitalData.Core.Contracts/Application/IServiceMessage.cs b/DigitalData.Core.Contracts/Application/IServiceMessage.cs index 7f55279..6a6af1d 100644 --- a/DigitalData.Core.Contracts/Application/IServiceMessage.cs +++ b/DigitalData.Core.Contracts/Application/IServiceMessage.cs @@ -1,33 +1,76 @@ -namespace DigitalData.Core.Contracts.Application +using System.Text.Json.Serialization; + +namespace DigitalData.Core.Contracts.Application { /// - /// Defines a basic structure for service messages, including a success flag and a collection of messages. - /// This interface is intended to be a base for more specific service result types, offering a way to communicate - /// operation outcomes (success or failure) along with relevant messages. + /// Defines a structured format for service messages, categorizing them into success indicators and various types of messages. + /// This interface segregates messages into client-facing messages and different levels of logging messages, facilitating targeted communications and diagnostics. /// public interface IServiceMessage { /// - /// Gets or sets a value indicating whether the service operation was successful. + /// Gets or sets a flag indicating whether the service operation was successful. /// bool IsSuccess { get; set; } /// + /// Gets or sets a collection of messages intended for client display. This is intended to replace the deprecated 'Messages' property. + /// + List ClientMessages { get; set; } + + /// + /// [Obsolete("Deprecated: Use ClientMessages instead.")] /// Gets or sets a collection of messages associated with the service operation. These messages can be error descriptions, /// success notifications, or other relevant information related to the operation's outcome. /// + [Obsolete("Deprecated: Use ClientMessages instead.")] List Messages { get; set; } /// - /// Adds a new message to the collection of service messages. + /// Gets or sets a collection of messages used for tracing program execution at a fine-grained level. These are typically voluminous and detailed. + /// + [JsonIgnore] + List TraceMessages { get; set; } + + /// + /// Gets or sets a collection of messages helpful for debugging during development. These messages are often diagnostic. + /// + [JsonIgnore] + List DebugMessages { get; set; } + + /// + /// Gets or sets a collection of informational messages, less critical than warnings, generally used for non-critical notifications. + /// + [JsonIgnore] + List InformationMessages { get; set; } + + /// + /// Gets or sets a collection of messages indicating potential issues that are not necessarily errors, but which may require attention. + /// + [JsonIgnore] + List WarningMessages { get; set; } + + /// + /// Gets or sets a collection of error messages indicating failures or problems within the service. + /// + [JsonIgnore] + List ErrorMessages { get; set; } + + /// + /// Gets or sets a collection of messages indicating critical issues that require immediate attention. + /// + [JsonIgnore] + List CriticalMessages { get; set; } + + /// + /// Adds a new message to the appropriate collection based on the message type. /// /// The message to add. /// The current instance of IServiceMessage, allowing for method chaining. IServiceMessage WithMessage(string message); /// - /// Adds a message corresponding to the specified message key to the collection of service messages. - /// This method uses the string representation of the enum value as the message. + /// Adds a message corresponding to a specified message key to the appropriate collection, facilitating localization and standardization. /// /// The enum value representing the message key. /// The current instance of IServiceMessage, allowing for method chaining.