Introduction
Welcome to the documentation for the OCPI.Net package! This documentation is organized into several sections, each covering a different aspect of the package. In this section, we'll provide an overview of the package and its benefits, as well as a guide to getting started with OCPI.Net.
Once you're familiar with the basics, you can move on to Getting started with OCPI.Net to learn how to install the package and start using it in your project.
You can refer to the Architecture section for an overview of the package's architecture and how it works under the hood. This section also covers how the package integrates with Asp.Net Core.
We hope you find this documentation helpful, and we welcome your feedback and contributions to the project!
Overview of the OCPI.Net package
The OCPI.Net package is a .NET implementation for the the Open Charge Point Interface (OCPI) protocol, which is used for communication between Charge Point Operators and e-Mobility Service Providers.
Make sure to check out this Sample application for a working example of how to use the package.
Benefits of using OCPI.Net
-
Seamless OCPI Protocol Implementation The package provides a comprehensive collection of contract models and validation tools that allow you to implement the OCPI protocol with ease. The package contains all necessary functionality to easily implement OCPI using Asp.Net Core.
-
Easy to Use The package is designed to be easy to use, with a simple and intuitive API that allows you to quickly get up and running with OCPI. The package also contains a collection of examples that demonstrate how to use the package in different scenarios.
-
Unrestricted Domain Flexibility The package allows you to integrate your specific requirements without limitations. This adaptable approach ensures your implementation perfectly aligns with your business needs and unique use cases, while still maintaining compliance with the OCPI protocol.
Getting started with OCPI.Net
-
To get started with OCPI.Net, you'll need to install the package using NuGet. You can do this by running the following command:
dotnet add package OCPI.Net
-
In order to start using the package in your project, you would have to add all required OCPI services in your
Program.cs
:builder.AddOcpi();
-
Enjoy the power of OCPI.Net!
You will find more info on how to use the package's functionality in the later sections of this documentation. See Implementation for more information on how to implement OCPI modules using OCPI.Net.
Architecture
The OCPI.Net package is designed to be as flexible as possible, allowing you to implement OCPI modules in any way you see fit. The package uses Asp.Net Core Controllers for handling incoming OCPI requests and returning OCPI responses. The package also contains a number of services which are used to perform various tasks such as validating incoming requests, generating responses, and handling errors.
The package follows a modular design, allowing you to use only the functionality you need. The package also allows you to implement multiple versions of the same module, allowing you to support multiple OCPI versions at the same time.
How the package works under the hood
The package uses the default Asp.Net Core dependency injection container to inject services into your controllers. The package also uses the default Asp.Net Core routing system to route incoming requests to the appropriate controllers.
The package uses the OcpiEndpoint
attribute to determine which controllers are used to handle incoming OCPI requests. The package will perform an automated scan of your controllers and generate a list of supported OCPI versions for each module. See more in Implementation.
The package uses Exceptions as a way to handle errors. The exceptions can be thrown from anywhere in your code, and the package will automatically handle them and generate the appropriate OCPI response. Exception handling is done by the OcpiExceptionFilter
attribute, which is automatically applied to all controllers that inherit from the OcpiController
base class. Exceptions can be populated with a custom data payload, which will be included in the OCPI response. See more in Error Handling.
Integration with Asp.Net Core
The OCPI.Net package is designed to be used with Asp.Net Core. The package contains a OcpiController
base class which you can use to implement your own OCPI controllers. This class contains a number of methods which you can use to handle incoming OCPI requests and generate OCPI responses.
Implementation
You can always refer to the Sample application for a working example of how to use the package.
How to implement OCPI modules using OCPI.Net
Apply OcpiEndpoint
attribute to your module controllers to specify their OCPI versions. The package will perform an automated scan of your controllers and generate a list of supported OCPI versions for each module.
[OcpiEndpoint(OcpiModule.Credentials, "Receiver", "2.2.1")]
[Route("2.2.1/credentials")]
public class OcpiCredentialsController : OcpiController
{
// Implement your module methods here
}
⚠️ The OCPI.Net Versioning implementation requires your OCPI endpoint routes to contain the ocpi version this route is used for.
For example, if your OCPI version is
2.2.1
, the controller implementing this OCPI Module should have at least 1 route with2.2.1
in it. This allows the package to determine which routes are intended for which OCPI version.
Refer to the Versioning section for more information on OCPI module versioning.
Use the OcpiOk
method of the OcpiController
class to generate OCPI-compliant responses:
[HttpGet]
public IActionResult Get()
{
var result = new OcpiCredentials()
{
Token = "Requesting-Platform's-Credentials-Token",
Url = "Your-Service's-Versions-Endpoint-Url"
};
return OcpiOk(result);
}
Use OcpiOk
with a PageResult<T>
to generate an OCPI-compliant paginated response. See more: Pagination
Customizing the package to meet specific business needs
The package is designed to be as flexible as possible, allowing you to implement OCPI modules in any way you see fit. The package contains a number of services which are used to perform various tasks such as validating incoming requests, generating responses, and handling errors.
You are not forced to use any of these services, and you can implement your own services if you wish. The package also allows you to override some of the default services with your own custom implementations.
Refer to the Architecture section for more information on the package's internal architecture.
OCPI Contracts
The package contains a number of classes which are used to represent OCPI objects. You can see the full list of contract models here.
Validation
The package contains a collection of validators which you can use to validate incoming OCPI requests. To use a validator, call the OcpiValidate
method of the OcpiController
class. The method only allows validating OCPI models from the OCPI.Contracts
namespace. In case of invalid request, further request handling will be aborted, and the error response will be returned to the client.
[OcpiEndpoint(OcpiModule.Locations, "Receiver", "2.2.1")]
[Route("2.2.1/locations")]
[OcpiAuthorize]
public class OcpiLocationsReceiverController : OcpiController
{
[HttpPut("{countryCode}/{partyId}/{locationId}")]
public IActionResult Put(
[FromRoute] string countryCode,
[FromRoute] string partyId,
[FromRoute] string locationId,
[FromBody] OcpiLocation location)
{
// Use a built-in OCPI validator
OcpiValidate(location);
// Your Location PUT logic
Return OcpiOk(result);
}
// Other endpoint methods...
}
Validation functionality is built on top of FluentValidation nuget package.
Error Handling
The package uses Exceptions as a way to handle errors. The exceptions can be thrown from anywhere in your code, and the package will automatically handle them and generate the appropriate OCPI response. Exception handling is done by the OcpiExceptionFilter
attribute, which is automatically applied to all controllers that inherit from the OcpiController
base class. Exceptions can be populated with a custom data payload, which will be included in the OCPI response.
You can use the OcpiControllerBase
class if you want to avoid the default exception handling. The only difference between the OcpiController
and OcpiControllerBase
classes is that the OcpiController
class has the OcpiExceptionFilter
attribute applied to it.
Overview of the package's error handling capabilities
When an exception gets thrown within a method that was called by an OCPI controller, this exception will bubble up to the controller and get handled by the OcpiExceptionFilter
attribute. The attribute will then generate an appropriate OCPI response based on the exception type and the exception data payload. Further request handling will be aborted, and the response will be returned to the client.
The package contains a number of predefined exceptions which you can use to handle common error scenarios. You can also create your own custom exceptions if you need to handle more specific error scenarios.
These exception functionality is based on the BitzArt.ApiExceptions nuget package. Refer to that package's documentation for more information on how to interact with the exception payloads.
Predefined OCPI exceptions and how to use them
The package contains a number of predefined exceptions which you can use to handle common error scenarios. You can create these exceptions using the OcpiException
static class:
throw OcpiException.ClientApiError();
// will return a ClientApiError OCPI status code and a default message for this type of error.
throw OcpiException.ClientApiError("Custom error message");
// will return a ClientApiError OCPI status code and a custom message.
throw OcpiException.ClientApiError("Custom error message", innerException);
// will return a ClientApiError OCPI status code, a custom message, and an inner exception.
Returning a custom OCPI status code
Return a custom OCPI status code by calling the Custom
method from the OcpiException
static class:
int customStatusCode = 1;
throw OcpiException.Custom("custom error message", customStatusCode);
Creating custom OCPI exceptions
You can create your own custom exceptions by inheriting from the OcpiExceptionBase
class:
public class MyCustomOcpiException : OcpiExceptionBase
{
public MyCustomOcpiException() : base("custom message", OcpiStatusCodes.ClientApiError)
{
}
}
Pagination
The OCPI.Net package uses some classes from the BitzArt.Pagination nuget package to handle paginated endpoints. Refer to it for guidance on how to use the pagination functionality.
There is an example controller with a paginated OCPI method in this reposiory. Refer to it if you are having trouble implementing OCPI paginated requests.
Make sure you call the SetMaxLimit(pageRequest, maxLimit);
method in your paginated request implementations. This will ensure that the client cannot request more than the maximum allowed number of items per page. This is required by OCPI in order to set the X-Limit
response header.
Example implementation
[OcpiEndpoint(OcpiModule.Locations, "Sender", "2.2.1")]
[Route("2.2.1/locations")]
[OcpiAuthorize]
public class OcpiLocationsSenderController : OcpiController
{
[HttpGet]
public IActionResult GetPage([FromQuery] OcpiPageRequest pageRequest)
{
// Set maximum Limit value
// Required for OCPI.Net PageResult handling
SetMaxLimit(pageRequest, 100);
// Process GetPage using Offset, Limit, DateFrom, DateTo from pageRequest
// You can use BitzArt.Pagination nuget package
// https://github.com/BitzArt/Pagination
// to handle Offset and Limit (does not handle DateFrom/DateTo),
// or implement your own OcpiPageRequest handling logic.
// Example:
var databaseLocations = Enumerable.Range(1, 100).Select(x =>
{
var location = SampleLocation;
location.Id = $"SampleLocation-{x}";
return location;
});
// This will handle Offset and Limit but not DateFrom or DateTo:
var result = databaseLocations.ToPage(pageRequest);
// Returning a PageResult in OcpiOk will process the paginated response
// and add appropriate page response headers.
return OcpiOk(result);
}
private static OcpiLocation SampleLocation => new()
{
CountryCode = CountryCode.Belgium,
PartyId = "BEC",
Publish = true,
Name = "Gent Zuid",
Address = "F.Rooseveltlaan 3A",
City = "Gent",
PostalCode = "9000",
Country = "BEL",
Coordinates = new OcpiGeolocation
{
Latitude = "51.047599",
Longitude = "3.729944"
},
ParkingType = ParkingType.OnStreet,
TimeZone = "Europe/Brussels",
LastUpdated = DateTime.UtcNow
};
}
Versioning
The OCPI.Net package supports multiple OCPI versions at the same time. The package uses the OcpiEndpoint
attribute to determine which OCPI versions are supported by a given controller.
Refer to the Implementation section for more information on how to implement OCPI modules using OCPI.Net.
How to implement OCPI Versions Module
After you have marked your OCPI controllers with the OcpiEndpoint
attribute, the package becomes aware of the OCPI versions supported by each controller. The package will automatically generate a list of supported OCPI versions for each module.
An example of how to implement the OCPI Versions module is provided in the Sample application.
In your Versions Module controller, inject the IOcpiVersionsService
service and use it to retrieve the list of supported OCPI versions for each module:
var versionService = serviceProvider.GetRequiredService<IOcpiVersionService>();
Use the GetVersions
method to get a list of all supported OCPI versions:
var versionInfo = versionService.GetVersions();
Use the GetVersionDetails
method to get a list of all supported OCPI endpoints for a given version:
var details = versionService.GetVersionDetails(request);
Example Versions Module implementation
[Route("versions")]
public class OcpiVersionsController : OcpiController
{
// This service scans your codebase and maps all OCPI paths from
// controllers marked with OcpiEndpoint attribute on startup.
private readonly IOcpiVersionService _versionService;
public OcpiVersionsController(IOcpiVersionService versionService)
{
_versionService = versionService;
}
[HttpGet]
public IActionResult GetVersionsAsync()
{
var versionInfo = _versionService.GetVersions();
return OcpiOk(versionInfo);
}
[HttpGet("{request}")]
public IActionResult GetVersionDetailsAsync([FromRoute] string request)
{
var details = _versionService.GetVersionDetails(request);
return OcpiOk(details);
}
}
How to support multiple OCPI versions at the same time
The package allows you to support multiple OCPI versions at the same time. You can do this by marking your controllers with the OcpiEndpoint
attribute and specifying the OCPI versions supported by each controller.
[OcpiEndpoint(OcpiModule.Credentials, "Receiver", "2.2, 2.2.1")]
[Route("2.2/credentials")]
[Route("2.2.1/credentials")]
public class OcpiCredentialsController : OcpiController
{
// Implement your module methods here
}
How to handle version-specific differences in OCPI modules
You can implement version-specific controllers for different versions of the same OCPI Module.
[OcpiEndpoint(OcpiModule.Credentials, "Receiver", "2.1.1")]
[Route("2.1.1/credentials")]
public class OcpiCredentialsV1Controller : OcpiController
{
// Code specific to OCPI 2.1.1
}
[OcpiEndpoint(OcpiModule.Credentials, "Receiver", "2.2.1")]
[Route("2.2.1/credentials")]
public class OcpiCredentialsV2Controller : OcpiController
{
// Code specific to OCPI 2.2.1
}