Muslim.Result
10.0.1
dotnet add package Muslim.Result --version 10.0.1
NuGet\Install-Package Muslim.Result -Version 10.0.1
<PackageReference Include="Muslim.Result" Version="10.0.1" />
<PackageVersion Include="Muslim.Result" Version="10.0.1" />
<PackageReference Include="Muslim.Result" />
paket add Muslim.Result --version 10.0.1
#r "nuget: Muslim.Result, 10.0.1"
#:package Muslim.Result@10.0.1
#addin nuget:?package=Muslim.Result&version=10.0.1
#tool nuget:?package=Muslim.Result&version=10.0.1
Muslim.Result
One result type for every operation in .NET 10: the data on success, the errors on failure, and the page numbers when the data is a list. Your API always answers in the same shape.
dotnet add package Muslim.Result
Quick start
Return a Result<T> from your service:
using Muslim.Result;
using Muslim.Validator;
public class ProductService(ShopContext db, IServiceProvider services)
{
public async Task<Result<ProductDto>> GetAsync(int id)
{
var product = await db.Products.FindAsync(id);
return product is null
? Result<ProductDto>.Fail("Product not found")
: Result<ProductDto>.Success(new ProductDto { Id = product.Id, Name = product.Name });
}
public async Task<Result<int>> CreateAsync(CreateProductDto dto, CancellationToken ct)
{
var (errors, isValid) = await ValidateResult.ErrorsAsync(dto, services, ct);
if (!isValid)
return Result<int>.ValidatorFail(errors);
var product = new Product { Name = dto.Name, Price = dto.Price };
db.Products.Add(product);
await db.SaveChangesAsync(ct);
return Result<int>.Success(product.Id);
}
}
Send it back from the endpoint:
app.MapGet("/products/{id:int}", async (int id, ProductService service) =>
{
var result = await service.GetAsync(id);
return result.IsSuccess ? Results.Ok(result) : Results.NotFound(result);
});
The client always gets the same fields:
{
"response": { "id": 7, "name": "Coffee" },
"error": null,
"validatorError": null,
"isSuccess": true,
"page": null,
"filter": null
}
{
"response": null,
"error": [ "Product not found" ],
"validatorError": null,
"isSuccess": false,
"page": null,
"filter": null
}
Creating results
| Method | Result |
|---|---|
Success(value) |
success with that value — any value, even null |
Success() |
success with no value |
Fail(message) |
failure with one error; an empty message gets a default text |
ValidatorFail(errors) |
failure with the validation errors from Muslim.Validator |
Exception(ex) |
failure with the exception's message (and inner message) |
Create(value) |
success, or a "not found" failure when the value is null, "" or an empty list |
await Create(task) |
same as Create(value), after awaiting the task |
You can add errors to an existing result. Either call marks it as failed:
result.AddError("Stock is not enough");
result.AddValidateError("Quantity", "Quantity must be at least 1");
Lists and paging
Pass the total count and page size, and the result works out the number of pages:
var page = filter.ToPagedResult(db.Products.AsNoTracking()); // Muslim.Filter
return Result<IReadOnlyList<Product>>.Success(page.Items, count: page.TotalCount, pageSize: page.PageSize);
{
"response": [ ... ],
"isSuccess": true,
"page": { "count": 21, "numberOfPages": 3, "pageSize": 10 }
}
A page size of 0 means "not paged", and page is left empty. A negative count or page size throws
ArgumentOutOfRangeException.
Chaining
Map changes the value, Bind calls the next step, and Match turns the result into one final
value. On failure, Map and Bind skip their code and carry the errors forward.
var result = await service.GetAsync(id);
var message = result
.Map(product => product.Name)
.Bind(name => name.Length > 0
? Result<string>.Success(name)
: Result<string>.Fail("Product has no name"))
.Match(
onSuccess: name => $"Found {name}",
onFailure: failed => string.Join(", ", failed.Error ?? []));
MapAsync, BindAsync and MatchAsync do the same with async code. Page and filter data are kept
through Map.
To return the same status and errors with a different value, use To:
Result<string> nameResult = productResult.To(productResult.Response?.Name ?? "");
Good to know
Create(value)checks only fornull, an empty string or an empty list.0,falseand a DTO with empty properties all count as found.Createreads the first item of a sequence to see if it is empty. For a stream or a sequence that must not be read twice, useSuccessinstead, or callToList()first.Exception(ex)puts the exception message in the response. Decide whether that message is safe to show your users.ResultPagelives in theMuslim.HandelResultnamespace.
Related packages
| Package | Use it for |
|---|---|
| Muslim.Validator | FluentValidation helpers with Arabic/English messages |
Coding-agent guidance
When you build a project that uses this package, a short guide for AI coding agents is copied to
.agents/skills/muslim-result/ at the root of your repository. Agents that read skills from
.agents/skills, such as Codex and GitHub Copilot in VS Code, use it to write correct code against
this package. Your own files and other skills are never touched, and nothing is deleted
automatically.
To turn it off, add this to your project or Directory.Build.props:
<PropertyGroup>
<MuslimResultGenerateAgentSkills>false</MuslimResultGenerateAgentSkills>
</PropertyGroup>
License
See LICENSE.txt.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
-
net10.0
- Muslim.Validator (>= 10.0.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Muslim.Result:
| Package | Downloads |
|---|---|
|
Muslim.GenericService.Interface
Service abstraction for Muslim.GenericService: IService<TEntity> and the interfaces it composes — reads, finds with paging, create, update, delete, soft delete and restore, counts and raw SQL — all returning Muslim.Result Result<T>. Reference this to depend on the contract without the implementation. |
GitHub repositories
This package is not used by any popular GitHub repositories.
Distribute versioned agent skills through NuGet and safely generate repository guidance after normal consumer builds.