Creatio Config Webservice
Overview
Create deterministic steps for implementing a Creatio custom web service in a package and testing it before delivery. Follow this skill when requests involve "create endpoint", "add web service method", "test service", "mock user/session", or "verify HTTP contract" in Creatio.
Required Location And Namespaces
Place service classes in:
- •
packages/<PACKAGE_NAME>/src/cs/EntryPoints/WebService
If the repository stores C# files under Files/src, map the same logical location as:
- •
packages/<PACKAGE_NAME>/Files/src/cs/EntryPoints/WebService
Use namespace pattern:
- •
<PackageNamespace>.EntryPoints.WebService
Place tests in:
- •
tests/<PACKAGE_NAME>/EntryPoints/WebService
Workflow Decision Tree
- •If the user needs a new endpoint, implement the full flow: contract, service implementation, registration/build, and tests.
- •If the endpoint exists but behavior changes, update only contract/implementation parts impacted, then update tests first.
- •If the request is only about testing, locate existing service and focus on test harness and assertions.
- •If deployment details are unclear (package, auth model, URL), inspect project/package structure first, then continue.
Implement Service
- •Identify target package and source location.
- •Create or update DTOs and response contracts first.
- •Implement service method with explicit input validation.
- •Return errors as values, not exceptions, following repository rule: use
ErrorOr. - •Keep endpoint behavior deterministic: validate, execute core logic, map result to response.
- •Keep transport concerns (request/response models) separate from business logic when possible.
Use references/creatio-webservice-template.md for a concrete structure and checklist.
Response Status And Serialization Rules (Creatio-Specific)
When method signature is:
- •
public <ResponseDto> <MethodName>(<RequestDto> request)
Creatio uses default serializer/deserializer for request/response binding (JSON/XML to DTO and DTO to response) and commonly returns 200 OK for the operation result flow.
If custom HTTP status behavior is required:
- •Set status code explicitly via
HttpContextAccessor.GetInstance().Response.StatusCode(NETSTANDARD2_0) or legacy response context. - •Prefer
voidmethod and write payload directly toResponse.OutputStreamwhen you need full control over status + body format. - •Use custom serialization (manual JSON writing) for strict response contracts.
Self-contained example (DemoService-style pattern, no repository dependency):
[OperationContract]
[WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare,
ResponseFormat = WebMessageFormat.Json)]
public void GetExample() {
HttpRequest request = HttpContextAccessor.GetInstance().Request;
#if NETSTANDARD2_0
HttpResponse response = HttpContextAccessor.GetInstance().Response;
response.StatusCode = 200;
#endif
var payload = new { text = "Hello World" };
string json = System.Text.Json.JsonSerializer.Serialize(payload);
byte[] bytes = Encoding.UTF8.GetBytes(json);
response.OutputStream.Write(bytes, 0, bytes.Length);
response.OutputStream.Flush();
}
Service Class Skeleton
Use this structure for configuration web services:
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class <ServiceName> : BaseService, IReadOnlySessionState {
[OperationContract]
[WebInvoke(
Method = "POST",
RequestFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare,
ResponseFormat = WebMessageFormat.Json)]
public <ResponseDto> <MethodName>(<RequestDto> request) {
HttpRequest requestInstance = HttpContextAccessor.GetInstance().Request;
#if NETSTANDARD2_0
HttpResponse response = HttpContextAccessor.GetInstance().Response;
#endif
// Validate and execute via app layer; do not throw expected errors.
// Return ErrorOr-driven result mapped to status code and response DTO.
}
}
Endpoint format:
- •
https://<creatio-host>/rest/<ServiceName>/<MethodName>
Configure and Register
- •Ensure service class visibility and attributes follow Creatio conventions used in the solution.
- •Confirm package dependencies include required assemblies.
- •Build solution/package and verify service compiles in target framework.
- •Record expected route and method names in tests and task notes.
Test Strategy
Create or update tests for every production change.
- •Unit test service logic:
- •Validate request validation paths.
- •Validate success mapping.
- •Validate error mapping (
ErrorOr) without throwing.
- •Entry point test (no network) for endpoint contract:
- •Execute service entry point with representative payload.
- •Assert HTTP/result envelope fields and payload shape.
- •Cover at least one negative case.
- •Manual HTTP endpoint test (runtime):
- •Call
POST/GET https://<creatio-host>/rest/<ServiceName>/<MethodName>with authenticated Creatio session. - •Assert status code, JSON schema, and error payload structure.
- •Validate at least one success and one failure request.
- •Regression test changed behavior:
- •Add focused test for new branch/condition.
- •Keep existing behavior covered.
Endpoint Test Fixture Pattern
Test fixture location and naming:
- •Path:
tests/<PACKAGE_NAME>/EntryPoints/WebService - •File name:
<ServiceName>TestFixture.cs - •Namespace:
<PackageNamespace>.Tests.EntryPoints.WebService
Create test class in this order:
- •Inherit from
BaseMarketplaceTestFixture. - •Add
[MockSettings(RequireMock.All)]. - •Add
[TestFixture(Category = "PreCommit")]. - •Create
IHttpContextAccessorwith mockedHttpContextinSetUp.
Self-contained fixture template (DemoServiceTestFixture-style, no repository dependency):
using FluentAssertions;
using NSubstitute;
using NUnit.Framework;
using Terrasoft.Configuration.Tests;
using Terrasoft.Web.Http.Abstractions;
namespace <PackageNamespace>.Tests.EntryPoints.WebService {
[MockSettings(RequireMock.All)]
[TestFixture(Category = "PreCommit")]
public class <ServiceName>TestFixture : BaseMarketplaceTestFixture {
private readonly HttpContext _context = Substitute.For<HttpContext>();
private IHttpContextAccessor _httpContextAccessor;
private System.IO.MemoryStream _outputStream;
protected override void SetUp() {
base.SetUp();
_outputStream = new System.IO.MemoryStream();
_context.Response.OutputStream.Returns(_outputStream);
_httpContextAccessor = CustomSetupHttpContextAccessor(_context, UserConnection);
}
protected override void TearDown() {
base.TearDown();
_outputStream.Dispose();
}
}
}
Test method requirements:
- •Add
[Test]and[Description("...")]for every test. - •Arrange service under test and inject
HttpContextAccessor. - •Act by calling service method directly (no network).
- •Assert status code.
- •Assert payload or DTO return.
- •Add at least one negative-path assertion.
Required assertions per endpoint method:
- •Assert
Response.StatusCode. - •Assert response body content (for payload endpoints).
- •Assert error-to-status mapping for at least one error path.
For JSON body assertions:
- •Read
response.OutputStream. - •
Seek(0, Begin)before read. - •Compare JSON string or deserialize and assert fields.
Self-contained test example (DemoService-style assertion):
[Test]
[Description("Returns OK and serialized payload for custom response writer")]
public void GetExample_ReturnsExpectedJson() {
ExampleService sut = new ExampleService {
HttpContextAccessor = _httpContextAccessor
};
sut.GetExample();
HttpResponse response = _httpContextAccessor.GetInstance().Response;
response.StatusCode.Should().Be(200);
using (var reader = new System.IO.StreamReader(response.OutputStream)) {
reader.BaseStream.Seek(0, System.IO.SeekOrigin.Begin);
string result = reader.ReadToEnd();
result.Should().Be("{\"text\":\"Hello World\"}");
}
}
For methods that return DTO directly:
- •Assert returned object values.
- •Document that default Creatio serialization is used for DTO mapping.
- •If custom status is required, prefer entry-point pattern with explicit status and manual response body writing.
Verification Checklist
- •Build succeeds with required Creatio environment variables set.
- •Tests added/updated for all changed production files.
- •Endpoint route, method name, and response schema documented in code/tests.
- •Error flow returns typed value and does not throw.
- •Endpoint test coverage includes status code + payload + negative case.
- •Manual HTTP test steps provided with concrete endpoint URL pattern.
Output Requirements
When executing this skill for a user request, always provide:
- •Files changed with short reason per file.
- •Service contract summary (input/output + error format).
- •Tests added/updated and coverage intent.
- •Commands used to build and run tests (or exact blocker if not runnable).