{"id":25846491,"url":"https://github.com/chr1st0scli/rainsoft.validations","last_synced_at":"2025-08-02T11:04:03.128Z","repository":{"id":116414095,"uuid":"324605837","full_name":"chr1st0scli/Rainsoft.Validations","owner":"chr1st0scli","description":"A library for easy validations.","archived":false,"fork":false,"pushed_at":"2023-07-24T17:54:20.000Z","size":101,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-01T04:47:27.876Z","etag":null,"topics":["class","decorator-pattern","dto","poco","validation","validation-library"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chr1st0scli.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-12-26T17:43:57.000Z","updated_at":"2023-09-10T09:47:39.000Z","dependencies_parsed_at":null,"dependency_job_id":"11b66aa4-b032-4118-939e-56b1cbd353a0","html_url":"https://github.com/chr1st0scli/Rainsoft.Validations","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/chr1st0scli/Rainsoft.Validations","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chr1st0scli%2FRainsoft.Validations","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chr1st0scli%2FRainsoft.Validations/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chr1st0scli%2FRainsoft.Validations/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chr1st0scli%2FRainsoft.Validations/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chr1st0scli","download_url":"https://codeload.github.com/chr1st0scli/Rainsoft.Validations/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chr1st0scli%2FRainsoft.Validations/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268378380,"owners_count":24240894,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-02T02:00:12.353Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["class","decorator-pattern","dto","poco","validation","validation-library"],"created_at":"2025-03-01T09:32:00.806Z","updated_at":"2025-08-02T11:04:03.106Z","avatar_url":"https://github.com/chr1st0scli.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Rainsoft.Validations\n![badge](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/chr1st0scli/f0fdc8ecc54e8bc61730caa4d91a8a3f/raw/rain-validations-code-coverage.json)\n[![nuget](https://img.shields.io/nuget/vpre/Rainsoft.Validations?color=blue)](https://www.nuget.org/packages/Rainsoft.Validations/)\n[![License](https://img.shields.io/github/license/chr1st0scli/Rainsoft.Validations)](LICENSE)\n\n![Logo](RainApps.png)\n\nA library for easy validations. You can easily validate instances of your classes or any values, whether it be method parameters or anything else. It can also be used for validating user input or writing tests.\n\nYou may combine different validations at runtime using decorators to validate individual values. It also allows you to expressibly validate instances of your classes, either in source code or declaratively using attributes on class data members.\n\n# Decorators #\nDecorators are particularly useful for checking individual values against several validation rules.\n\nAt runtime, you may compose a complicated rule by combining simpler ones and then simply call the `IsValid` method with a value.\n\n```csharp\n// Combine multiple validators to run.\nIValueValidator\u003cstring\u003e validator =\n    new LengthValidator(10,\n    new StartsWithValidator(\"POS\", true,\n    new EndsWithValidator(\"Z\", true)));\n\n// Check if a single value complies with several rules.\nstring employeePositionCode = \"POS123456Z\";\nbool isValid = validator.IsValid(employeePositionCode);\n```\nThis is available in the `Rainsoft.Validations.Core` namespace with several more validators.\n\n# Instance Validators #\nInstance validators are particularly useful for checking whole instances of classes and their members.\n\n```csharp\n// Given a class instance.\nvar employee = new Employee\n{\n    Name = \"Bob\",\n    TaxNo = 23434546,\n    Position = \"POS123456Z\",\n    Salary = 1150.50m\n};\n\n// You can create a validator for it.\nvar employeeValidator = new InstanceValidator\u003cEmployee\u003e(employee);\n\n// For every member you want to validate, specify the rules it must comply with.\nemployeeValidator.Checks(empl =\u003e empl.Position)\n    .OfLength(10)\n    .StartsWith(\"POS\")\n    .EndsWith(\"Z\");\n\n// You can also specify appropriate error messages for each violated rule.\nemployeeValidator.Checks(empl =\u003e empl.Name)\n    .LongerThan(1, \"Name should be longer than 1 character.\")\n    .ShorterThan(100, \"Name should be shorter than 100 characters.\");\n\nemployeeValidator.Checks(empl =\u003e empl.TaxNo)\n    .Matches(new Regex(\"[0-9]{8}\"));\n\nemployeeValidator.Checks(empl =\u003e empl.Salary)\n    .GreaterThan(1000, true);\n\n// Simply call IsValid to determine if your instance is valid.\nbool isValid = employeeValidator.IsValid();\n\n// Or you can find out exactly which rules are not satisfied by checking the offenses.\nIList\u003cValidationOffense\u003e offenses = null;\nisValid = employeeValidator.IsValid(ref offenses);\n```\nThis is also available in the `Rainsoft.Validations.Core` namespace with more validations. Instance validators are inspired by FluentValidation.\n\n# Attributes #\nAttributes are particularly useful for defining validations declaratively on simple data-centric classes like DTOs.\n\nYou can declare a class and apply validation attributes on its properties or fields. The validations are performed on the class itself and all other related classes via aggregation/composition and inheritance relationships.\n\nGiven the following class.\n\n```csharp\n// Declaratively specify the validation rules and optional error messages in your class declaration.\npublic class Employee\n{\n    [LongerThan(1, ErrorMessage = \"Name should be longer than 1 character.\")]\n    [ShorterThan(100, ErrorMessage = \"Name should be shorter than 100 characters.\")]\n    public string Name { get; set; }\n\n    [Length(10)]\n    [StartsWith(\"POS\")]\n    [EndsWith(\"Z\")]\n    public string Position { get; set; }\n\n    [Matches(\"[0-9]{8}\")]\n    public int TaxNo { get; set; }\n\n    [GreaterThanOrEqualTo(1000.0)]\n    public decimal Salary { get; set; }\n}\n```\n\nYou can validate it as follows.\n\n```csharp\n// Given a class instance.\nvar employee = new Employee\n{\n    Name = \"Bob\",\n    TaxNo = 23434546,\n    Position = \"POS123456Z\",\n    Salary = 1150.50m\n};\n\n// Use namespace Rainsoft.Validations.Attributes.Engine to have the IsValid extension method available on your classes.\n// Simply call IsValid to determine if your instance satisfies all rules.\nbool isValid = employee.IsValid();\n\n// Or you can find out exactly which rules are not satisfied by checking the offenses.\nIList\u003cValidationOffense\u003e offenses = null;\nisValid = employee.IsValid(ref offenses);\n\n// You can also validate a specific member of your object.\nisValid = employee.IsMemberValid(nameof(Employee.Position));\n\n// Or again...\nIList\u003cValidationOffense\u003e memberOffenses = null;\nisValid = employee.IsMemberValid(nameof(Employee.Position), ref memberOffenses);\n```\nThis is available in the `Rainsoft.Validations.Attributes` namespace.\n\n# MVC and Web API Integration #\n[![Nuget (with prereleases)](https://img.shields.io/nuget/vpre/Rainsoft.Validations.MSAnnotations)](https://www.nuget.org/packages/Rainsoft.Validations.MSAnnotations)\n\nIf you want to use or combine Rainsoft.Validations attributes with Microsoft's MVC or Web API infrastructure, you can use the Rainsoft.Validations.MSAnnotations library.\nYou can then use all Rainsoft attributes and the additional MSValidationAdapter to enable the .NET infrastructure use your attributes implicitly.\n\n```csharp\npublic class Employee\n{\n    [MSValidationAdapter]\n    [LongerThan(1, ErrorMessage = \"Name should be longer than 1 character.\")]\n    [ShorterThan(100, ErrorMessage = \"Name should be shorter than 100 characters.\")]\n    public string Name { get; set; }\n\n    [MSValidationAdapter]\n    [Length(10, ErrorMessage = \"Position should be 10 characters long.\")]\n    [StartsWith(\"POS\", ErrorMessage = \"Position should start with POS.\")]\n    [EndsWith(\"Z\", ErrorMessage = \"Position should end with Z.\")]\n    public string Position { get; set; }\n\n    [MSValidationAdapter]\n    [Matches(\"[0-9]{8}\", ErrorMessage = \"Tax number should be 8 digits.\")]\n    public int TaxNo { get; set; }\n\n    [MSValidationAdapter]\n    [GreaterThanOrEqualTo(1000, ErrorMessage = \"Salary should be greater than or equal to 1000.\")]\n    public decimal Salary { get; set; }\n}\n\n// Then, in your Controller or ApiController, you can check if the validation fails.\nif (!ModelState.IsValid)\n{\n\t//...\n}\n```\n\n# Further Details #\nThere are validators for all basic needs like the following.\n* Starting and ending values.\n* Length related (equal, shorter or longer than a given length).\n* Comparisons on primitives or custom IComparable classes.\n* Regular expressions.\n* DateTime related.\n* Set related.\n* Predicates that can be used with custom classes.\n\nFor more needs or even business specific validations, you can easily extend the library. Additional examples and details can be found in the ValidationsTests project.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchr1st0scli%2Frainsoft.validations","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchr1st0scli%2Frainsoft.validations","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchr1st0scli%2Frainsoft.validations/lists"}