QuellCode/CentronERP war nur als Gitlink (Submodul-Referenz auf 79c1142) getrackt, ohne .gitmodules und ohne erreichbares Remote. Der Untersuchungsgegenstand der Versuchsreihe war damit nicht reproduzierbar gesichert: Ein Klon haette ein leeres Verzeichnis erhalten, und die Belege der 3.287 Anforderungen waeren nicht ueberpruefbar gewesen. Umstellung: - Historie nach c:\DEV\CentronERP_git_snapshot_79c1142 ausgelagert (vollstaendig lesbar, enthaelt 79c1142 und Vorgaenger 89ccfd6) - Gitlink aus dem Index entfernt - Dateiinhalt aufgenommen: 24.557 Dateien, rund 333 MB Die verschachtelte .gitignore der Codebasis gilt weiter, Build-Artefakte bleiben ausgeschlossen. Details in Versuche/Versuch_01/_Codebasis-Nachweis.md
6.3 KiB
Results and Responses in c-entron.NET
This document explains the Result and Response classes in c-entron.NET, their purpose, and how they interact across the system layers. These classes form a critical part of the error handling and communication pattern throughout the application.
Overview
In c-entron.NET, we use a standardized approach for operation results and API responses:
Result- Internal class used within the business logic layer to indicate operation success/failureResponse- Web service API class that translatesResultobjects to client-friendly responses
This pattern provides:
- Consistent error handling across all application layers
- Type-safe return values with status information
- Clean separation between internal logic and API responses
- Standardized way to include error messages and codes
Result Class
Location
src/backend/Centron.Interfaces/Results/Result.cs
Purpose
The Result class represents the outcome of an operation in the business logic layer. It includes not just the success/failure status, but also contextual information like error messages and exception details.
Structure
public class Result
{
public string Message { get; protected set; }
public int? MessageCode { get; protected set; }
public Exception Error { get; protected set; }
public ResultStatus Status { get; protected set; }
// Factory methods and constructors...
}
Status Values
The Result object can have one of the following statuses:
- Success - The operation completed successfully
- Error - The operation failed due to an error
- Warning - The operation completed but with warnings
Factory Methods
The Result class uses factory methods (instead of constructors) for creating result objects:
// Success results
Result.AsSuccess();
Result.AsSuccess("Operation completed successfully");
// Error results
Result.AsError("The operation failed", messageCode: 100);
Result.AsError("Invalid input", error: exception);
// Warning results
Result.AsWarning("Some fields could not be processed");
// From exceptions
Result.FromException("Failed to process request", exception);
Result.FromException(exception);
Generic Version
There is also a generic version Result<T> that carries data along with the status:
// Success with data
Result<Customer> customerResult = Result<Customer>.AsSuccess(customer);
// Error with no data
Result<Customer> errorResult = Result<Customer>.AsError("Customer not found");
Response Class
Location
src/webservice/Centron.WebServices.Core/Messages/Response.cs
Purpose
The Response class serves as the API response format returned by web services to clients. It translates the internal Result objects into standardized API responses.
Structure
[DataContract]
public class Response
{
[DataMember]
public StatusCode Status { get; set; }
[DataMember]
public string Message { get; set; }
[DataMember]
public int MessageCode { get; set; }
// Factory methods...
}
[DataContract]
public class Response<T> : Response
{
[DataMember]
public List<T> Result { get; set; }
// Additional factory methods...
}
Status Values
The Response object can have one of the following statuses:
- Success - The operation completed successfully
- Failed - The operation failed due to an error
Note that unlike Result, Response maps both ResultStatus.Success and ResultStatus.Warning to StatusCode.Success.
Interaction Between Result and Response
The key interaction occurs through the FromBLResult methods in the Response class:
// Converting a Result to Response
Response response = Response.FromResult(result);
// Converting a Result<T> to Response<T>
Response<Customer> response = Response<Customer>.FromBLResult(customerResult);
Mapping Logic
-
Result.Statusis mapped toResponse.Status:ResultStatus.Success→StatusCode.SuccessResultStatus.Warning→StatusCode.Success(warnings are treated as success at API level)ResultStatus.Error→StatusCode.Failed
-
Result.Messageis directly copied toResponse.Message -
Result.MessageCodeis copied toResponse.MessageCode(with a default if not provided) -
For
Result<T>, the data is added to theResponse<T>.Resultcollection
Usage Examples
Business Logic Layer (BL)
public Result<CustomerDTO> GetCustomerById(int customerId)
{
try
{
var customer = this._repository.GetCustomerById(customerId);
if (customer == null)
return Result<CustomerDTO>.AsError("Customer not found");
var dto = this.ConvertToDTO(customer);
return Result<CustomerDTO>.AsSuccess(dto);
}
catch (Exception ex)
{
return Result<CustomerDTO>.FromException(ex);
}
}
Web Service Layer
public Response<CustomerDTO> GetCustomerById(int customerId)
{
var result = this._customerBL.GetCustomerById(customerId);
return Response<CustomerDTO>.FromBLResult(result);
}
Best Practices
-
Always use factory methods instead of constructors for creating
Resultobjects// Good return Result.AsSuccess("Operation succeeded"); // Avoid return new Result(ResultStatus.Success, "Operation succeeded"); -
Include meaningful error messages to help diagnose issues
// Good return Result.AsError($"Customer with ID {id} not found"); // Avoid return Result.AsError("Not found"); -
Propagate exceptions appropriately using
FromExceptiontry { // Operation code } catch (Exception ex) { return Result.FromException("Failed to complete operation", ex); } -
Use
ThrowIfErrorextension method when chaining operationsvar result = await someOperation().ThrowIfError(); -
Convert between
ResultandResponseonly at service boundaries to maintain clean separation of concerns
Conclusion
The Result and Response classes provide a robust pattern for error handling and operation results throughout the c-entron.NET application. Understanding how they work together is essential for maintaining consistency in API responses and proper error handling across all application layers.