Files
Masterarbeit/QuellCode/CentronERP/docs/reference/architecture/results-and-responses.md
T
Christoph Schwörer f045b99a25 Codebasis als Dateien ins Arbeitsrepo statt als Gitlink
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
2026-08-26 07:43:51 +02:00

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:

  1. Result - Internal class used within the business logic layer to indicate operation success/failure
  2. Response - Web service API class that translates Result objects 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

  1. Result.Status is mapped to Response.Status:

    • ResultStatus.Success → StatusCode.Success
    • ResultStatus.Warning → StatusCode.Success (warnings are treated as success at API level)
    • ResultStatus.Error → StatusCode.Failed
  2. Result.Message is directly copied to Response.Message

  3. Result.MessageCode is copied to Response.MessageCode (with a default if not provided)

  4. For Result<T>, the data is added to the Response<T>.Result collection

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

  1. Always use factory methods instead of constructors for creating Result objects

    // Good
    return Result.AsSuccess("Operation succeeded");
    
    // Avoid
    return new Result(ResultStatus.Success, "Operation succeeded");
    
  2. Include meaningful error messages to help diagnose issues

    // Good
    return Result.AsError($"Customer with ID {id} not found");
    
    // Avoid
    return Result.AsError("Not found");
    
  3. Propagate exceptions appropriately using FromException

    try
    {
        // Operation code
    }
    catch (Exception ex)
    {
        return Result.FromException("Failed to complete operation", ex);
    }
    
  4. Use ThrowIfError extension method when chaining operations

    var result = await someOperation().ThrowIfError();
    
  5. Convert between Result and Response only 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.