Silky Microservice FrameworkSilky Microservice Framework
Home
Docs
Config
Source
github
gitee
  • 简体中文
  • English
Home
Docs
Config
Source
github
gitee
  • 简体中文
  • English
  • Introduction

    • Silky Framework Overview
  • Getting Started

    • Glossary
    • Quick Start
    • Project Template
    • Microservice Architecture
    • Sample Projects
  • Host & Module

    • Host Types
    • Gateway Configuration
    • Module System
    • Plugin System
  • Gateway & HTTP

    • Swagger / OpenAPI
    • MiniProfiler
    • CORS
    • Audit Logging
  • Service & RPC

    • App Services & Service Entries
    • RPC Communication
    • WebSocket
    • Service Registry
    • Service Governance
  • Data & Cache

    • EFCore Data Access
    • Caching
    • Distributed Lock
  • Security & Auth

    • Identity & Authentication
    • Distributed Transactions
  • Infrastructure

    • Dependency Injection
    • Object Mapping
    • Validation
    • Link Tracking (SkyAPM)
    • Logging (Serilog)
    • Health Checks
    • Message Bus (MassTransit)
    • Unit & Integration Testing

Overview

Silky has a built-in parameter validation mechanism that automatically validates service entry input parameters during RPC communication. Two validation approaches are supported:

ApproachNuGet PackageNotes
DataAnnotationsSilky.Core (built-in)Standard .NET System.ComponentModel.DataAnnotations attributes
FluentValidationSilky.Validation.FluentComplex validation rules with a fluent DSL

Validation failures throw a ValidationException — HTTP status code 400 Bad Request.


DataAnnotations Validation

Annotate DTO properties directly:

public class CreateOrderInput
{
    [Required(ErrorMessage = "Product ID is required")]
    public long ProductId { get; set; }

    [Range(1, 9999, ErrorMessage = "Quantity must be between 1 and 9999")]
    public int Quantity { get; set; }

    [Required(ErrorMessage = "Shipping address is required")]
    [MaxLength(200, ErrorMessage = "Address cannot exceed 200 characters")]
    public string Address { get; set; }

    [Phone(ErrorMessage = "Invalid phone number format")]
    public string Phone { get; set; }
}

Use the DTO in the service interface — validation runs automatically before the method executes:

[ServiceRoute]
public interface IOrderAppService
{
    Task<OrderOutput> CreateOrderAsync(CreateOrderInput input);
}

FluentValidation

For complex validation rules, FluentValidation provides a powerful DSL.

Installation

PM> Install-Package Silky.Validation.Fluent -Version 3.9.2

Define a Validator

Inherit from AbstractValidator<T> and implement IScopedDependency (auto-registered by the framework):

using FluentValidation;
using Silky.Core.DependencyInjection;

public class CreateOrderInputValidator : AbstractValidator<CreateOrderInput>, IScopedDependency
{
    public CreateOrderInputValidator()
    {
        RuleFor(x => x.ProductId)
            .GreaterThan(0).WithMessage("Product ID must be greater than 0");

        RuleFor(x => x.Quantity)
            .InclusiveBetween(1, 9999).WithMessage("Quantity must be between 1 and 9999");

        RuleFor(x => x.Address)
            .NotEmpty().WithMessage("Shipping address is required")
            .MaximumLength(200).WithMessage("Address cannot exceed 200 characters");

        RuleFor(x => x.Phone)
            .Matches(@"^\+?[1-9]\d{7,14}$").WithMessage("Invalid phone number format");
    }
}

No manual registration needed — Silky detects IScopedDependency and registers the validator automatically.

Enable FluentValidation Module

[DependsOn(
    typeof(FluentValidationModule),
    typeof(DotNettyTcpModule)
)]
public class CustomHostModule : GeneralHostModule { }

Validation Error Response

When validation fails, the framework returns a structured error response:

{
  "code": 400,
  "message": "Validation failed",
  "errors": [
    { "field": "ProductId", "message": "Product ID must be greater than 0" },
    { "field": "Quantity",  "message": "Quantity must be between 1 and 9999" }
  ]
}

Combining Both Approaches

DataAnnotations and FluentValidation can be used together. Both run before the method executes, and all validation errors are collected and returned in a single response.

Edit this page
Prev
Object Mapping
Next
Link Tracking (SkyAPM)