MikroSharp 1.0.8

dotnet add package MikroSharp --version 1.0.8
                    
NuGet\Install-Package MikroSharp -Version 1.0.8
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="MikroSharp" Version="1.0.8" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="MikroSharp" Version="1.0.8" />
                    
Directory.Packages.props
<PackageReference Include="MikroSharp" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add MikroSharp --version 1.0.8
                    
#r "nuget: MikroSharp, 1.0.8"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package MikroSharp@1.0.8
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=MikroSharp&version=1.0.8
                    
Install as a Cake Addin
#tool nuget:?package=MikroSharp&version=1.0.8
                    
Install as a Cake Tool

MikroSharp

A modern, strongly-typed .NET client for MikroTik RouterOS REST API (User-Manager focused), with clean ergonomics, typed helpers, robust error handling, and explicit dash-case request keys.

  • .NET 9 target (works with .NET 8+ via multi-targeting in the future)
  • Simple client setup with Basic Auth
  • Explicit dash-case (kebab-case) request keys matching RouterOS REST field names
  • Clear models and XML docs for IntelliSense
  • High-level helper extensions for common tasks (creating profiles/limitations, linking, setting attributes)

Note: RouterOS REST must be enabled on the device. Some operations may require specific packages or RouterOS versions.

Installation

NuGet (when available):

# Coming soon (package metadata is prepared)
dotnet add package MikroSharp

From source (ProjectReference):

<ItemGroup>
  <ProjectReference Include="../MikroSharp/MikroSharp.csproj" />
</ItemGroup>

Quick start

using MikroSharp;
using MikroSharp.Abstractions;
using MikroSharp.Endpoints;

// For production with a valid TLS certificate
var client = new MikroSharpClient("https://192.168.88.1", "admin", "password");

// Or for lab/testing environments ONLY (skips TLS validation)
// var client = MikroSharpClient.CreateInsecure("https://192.168.88.1", "admin", "password");

// List users
var users = await client.UserManager.ListUsersAsync();

// Create or update a user
await client.UserManager.CreateOrUpdateUserAsync("alice", "p@ssw0rd", sharedUsers: 1);

// Set handy attributes
await client.UserManager.SetRateLimitAsync("alice", "20M/20M");
await client.UserManager.SetStaticIpAsync("alice", "10.10.10.50");
await client.UserManager.SetSessionTimeoutAsync("alice", 3600);

// Disable/Enable
await client.UserManager.DisableUserAsync("alice", disabled: true);
await client.UserManager.EnableUserAsync("alice");

// Clean up
await client.UserManager.DeleteUserAsync("alice");

Get full user details (user + profiles + limitations)

You can fetch an aggregated view of a user, including the base user entry, linked profiles, the limitations attached to each profile, and parsed attributes (rate-limit, static IP, session-timeout):

using MikroSharp.Endpoints; // for GetUserDetailsAsync extension

var details = await client.UserManager.GetUserDetailsAsync("alice");

// Base user object from RouterOS
Console.WriteLine($"User: {details.User.Name}, Disabled: {details.User.Disabled}, Shared: {details.User.SharedUsers}");

// Parsed attributes (if present)
Console.WriteLine($"RateLimit: {details.RateLimit}, StaticIp: {details.StaticIp}, SessionTimeout: {details.SessionTimeout}");

// Profiles and their linked limitations
foreach (var p in details.Profiles)
{
    Console.WriteLine($"Profile: {p.Profile} -> Limitations: {string.Join(", ", p.Limitations)}");
}

Notes:

  • Duplicated links are de-duplicated in the result.
  • Matching is case-insensitive for usernames and profile names.
  • Unknown or missing attributes are handled gracefully (nulls).

Configure with options

You can also configure the client using an options object (timeouts, extra headers, disposal control), and optionally tweak the JSON serializer.

using MikroSharp.Abstractions;
using System.Text.Json;

var options = new MikroSharpOptions
{
    BaseUrl = "https://192.168.88.1",
    Username = "admin",
    Password = "password",
    Timeout = TimeSpan.FromSeconds(30),
    DefaultHeaders = new Dictionary<string, string>
    {
        ["X-Trace-Id"] = Guid.NewGuid().ToString()
    },
    DisposeHttpClient = true
};

var client = new MikroSharpClient(options, configureJson: json =>
{
    // customize serializer if you need to (e.g., add converters)
});

Profiles and limitations

The API exposes low-level methods and high-level helpers. You can compose your own flows.

Low-level:

// Create a profile (start mode can be "assigned" or "first-auth")
await client.UserManager.CreateProfileAsync("30D-UL-1U", startMode: "assigned", days: 30);

// Create a limitation (cap in GiB, days used to estimate a transfer window)
await client.UserManager.CreateLimitationAsync("100GB-30D", capGiB: 100, days: 30);

// Link the profile to the limitation
await client.UserManager.LinkProfileToLimitationAsync("30D-UL-1U", "100GB-30D");

// Link the user to the profile
await client.UserManager.LinkUserToProfileAsync("alice", "30D-UL-1U");

Typed overloads and helpers:

using MikroSharp.Abstractions; // StartWhenMode

// Typed start mode overload
await client.UserManager.CreateProfileAsync("ProPlan", StartWhenMode.Assigned, days: 30);

// One-shot dynamic plan helper
await client.UserManager.ApplyDynamicPlanAsync(
    user: "alice",
    password: "p@ssw0rd",
    days: 30,
    capGiB: 50,       // 0 means Unlimited plan
    sharedUsers: 1,
    startMode: StartWhenMode.Assigned,
    rateLimit: "20M/20M",
    staticIp: null
);

// Renew dynamic plan (removes previous user-profile links first)
await client.UserManager.RenewDynamicPlanAsync(
    user: "alice",
    password: "p@ssw0rd",
    days: 30,
    capGiB: 50,
    sharedUsers: 1,
    startMode: StartWhenMode.Assigned,
    rateLimit: "20M/20M"
);

JSON field names (dash-case)

RouterOS REST uses dash-case (kebab-case) field names such as shared-users, starts-when, and transfer-limit. To ensure exact compatibility and avoid mistakes, MikroSharp sends request bodies using explicit dictionaries with the exact field names expected by the API. This avoids relying on automatic naming policies.

Examples of keys we send:

  • name, password, group, shared-users
  • starts-when, validity, price
  • transfer-limit
  • user, profile, limitation

Responses are still deserialized into models using [JsonPropertyName] where needed (e.g., .id, shared-users).

Error handling

All HTTP failures and network errors are wrapped in MikroSharp.Core.MikroSharpException, which includes:

  • StatusCode (if available)
  • ResponseBody (raw text)
  • Method and Path for quick diagnostics
try
{
    await client.UserManager.DeleteUserAsync("missing-user");
}
catch (MikroSharp.Core.MikroSharpException ex)
{
    Console.WriteLine($"Failed: {ex.Message}\nStatus: {ex.StatusCode}\nPath: {ex.Path}\nBody: {ex.ResponseBody}");
}

SSL and security

  • Prefer valid TLS certificates on your router. For labs, use MikroSharpClient.CreateInsecure(...) to bypass cert validation.
  • Credentials are sent using HTTP Basic Auth; always use HTTPS.

Lifetime and threading

MikroSharpClient implements IDisposable and owns an internal HttpClient. It's safe to reuse across many calls and threads. Dispose the client when done.

await using var client = new MikroSharpClient("https://router", "admin", "password");
// use client...

Tests

This repository includes a small test suite to prevent regressions around request body field names. In particular, we verify outgoing JSON uses the exact dash-case keys expected by RouterOS (e.g., group, not g-roup).

Run tests:

dotnet test MikroSharp.Tests/MikroSharp.Tests.csproj -v minimal

Roadmap

  • Add more RouterOS endpoints (e.g., IP address management, DHCP, Hotspot, PPP)
  • Add unit tests and integration test harness (with RouterOS container or simulator)
  • Multi-targeting (net8.0, net9.0)

Contributing

Issues and PRs are welcome. Please include a clear reproduction, RouterOS version, and the REST endpoint you’re targeting.

License

MIT

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net9.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.8 3,400 10/27/2025
1.0.7 2,645 10/26/2025
1.0.6 2,621 10/26/2025
1.0.5 2,567 10/25/2025
1.0.4 2,571 10/25/2025
1.0.3 2,566 10/25/2025
1.0.2 2,644 10/23/2025
1.0.1 2,635 10/22/2025
1.0.0 2,631 10/22/2025