Install B1SLayer via NuGet
devYou can install B1SLayer into your .NET project using either the Package Manager Console or the .NET CLI.
PM> Install-Package B1SLayer
dotnet add package B1SLayerrepository·dev·Indexed 41 days ago
https://github.com/bgmulinari/b1slayerA lightweight .NET client for the SAP Business One Service Layer. It provides fluent request building, automatic session management, and automatic retries for GET, POST, PATCH, and DELETE operations, including support for batch requests and file updates.
You can install B1SLayer into your .NET project using either the Package Manager Console or the .NET CLI.
PM> Install-Package B1SLayer
dotnet add package B1SLayerYou can perform multiple operations in a single HTTP request using SLBatchRequest. This is highly efficient for reducing network round-trips.
SLBatchRequest objects specifying the HttpMethod, the resource path, and the payload..WithReturnNoContent() if you want to add the Prefer: return-no-content header.serviceLayer.PostBatchAsync(...) to execute them.Returns an array of HttpResponseMessage objects representing the result of each operation.
var req1 = new SLBatchRequest(
HttpMethod.Post,
"BusinessPartners",
new { CardCode = "C00001", CardName = "I'm a new BP" })
.WithReturnNoContent();
var req2 = new SLBatchRequest(HttpMethod.Patch,
"BusinessPartners('C00001')",
new { CardName = "This is my updated name" });
var req3 = new SLBatchRequest(HttpMethod.Delete, "BusinessPartners('C00001')");
HttpResponseMessage[] batchResult = await serviceLayer.PostBatchAsync(req1, req2, req3);B1SLayer supports standard CRUD operations via fluent API calls.
Use .PostAsync<T>(object) to send a JSON body to a resource. The provided object is serialized to JSON, and the response is deserialized into the specified type T.
.PatchAsync(object) to update specific fields using an anonymous object or a model..PatchWithFileAsync(string path) to update or add an item image or other file-based resource.Batch requests can include HttpMethod.Delete to remove resources.
// POST a new order
var createdOrder = await serviceLayer.Request("Orders").PostAsync<MyOrderModel>(myNewOrderObject);
// PATCH a Business Partner name
await serviceLayer.Request("BusinessPartners", "C00001")
.PatchAsync(new { CardName = "Updated BP name" });
// PATCH an item image file
await serviceLayer.Request("ItemImages", "A00001")
.PatchWithFileAsync(@"C:\ItemImages\A00001.jpg");
// POST an attachment
var attachmentEntry = await serviceLayer.PostAttachmentAsync(@"C:\files\myfile.pdf");The SLConnection object is the central entry point for all Service Layer requests and session management.
Key usage rules:
Constructor parameters:
baseUrl: The Service Layer URL (e.g., https://sapserver:50000/b1s/v1).companyDb: The name of the Company Database.username: The Service Layer username.password: The Service Layer password.var serviceLayer = new SLConnection("https://sapserver:50000/b1s/v1", "CompanyDB", "manager", "12345");B1SLayer provides fluent methods to perform GET requests on specific resources, supporting filtering, selection, and pagination.
Use .Request(resource, id).GetAsync<T>() to fetch a record and deserialize it into a custom model.
You can chain methods to build complex queries:
.Filter(string): Adds a Service Layer filter (e.g., startswith(...))..Select(string): Specifies which fields to return..OrderBy(string): Specifies the sort order..WithPageSize(int): Sets the page size..WithCaseInsensitive(): Enables case-insensitive searching.Use .GetAllAsync<T>() to perform multiple GET requests until all entities in the database are retrieved. This method automatically unwraps the result from the Service Layer's 'value' array.
// Get single record
var order = await serviceLayer.Request("Orders", 823).GetAsync<MyOrderModel>();
// Get filtered list
var bpList = await serviceLayer.Request("BusinessPartners")
.Filter("startswith(CardCode, 'c')")
.Select("CardCode, CardName")
.OrderBy("CardName")
.WithPageSize(50)
.WithCaseInsensitive()
.GetAsync<List<MyBusinessPartnerModel>>();
// Get all records
var allItemsList = await serviceLayer.Request("Items").GetAllAsync<MyItemModel>();
// Get via composite key
var altCatNum = await serviceLayer
.Request("AlternateCatNum(ItemCode='A00001',CardCode='C00001',Substitute='BP01')")
.GetAsync<MyAltCatModel>();To explicitly end the current session, call LogoutAsync() on your SLConnection instance.
await serviceLayer.LogoutAsync();