{"id":31702331,"url":"https://github.com/selcukgural/sguard.dataannotations","last_synced_at":"2026-05-15T01:36:46.233Z","repository":{"id":314001485,"uuid":"1051803999","full_name":"selcukgural/SGuard.DataAnnotations","owner":"selcukgural","description":"🛡️ Advanced, extensible, and multilingual data validation and guard clause library for .NET. Includes custom validation attributes, guard helpers, and resource-based error messages for enterprise-grade applications.","archived":false,"fork":false,"pushed_at":"2025-09-09T22:37:38.000Z","size":258,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-10T02:10:52.745Z","etag":null,"topics":["attributes","data-annotations","dotnet","enterprise","guard","library","localization","multilingual","validation"],"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/selcukgural.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":".github/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":null},"created_at":"2025-09-06T18:51:04.000Z","updated_at":"2025-09-09T22:36:33.000Z","dependencies_parsed_at":"2025-09-10T08:18:14.355Z","dependency_job_id":null,"html_url":"https://github.com/selcukgural/SGuard.DataAnnotations","commit_stats":null,"previous_names":["selcukgural/sguard.dataannotations"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/selcukgural/SGuard.DataAnnotations","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/selcukgural%2FSGuard.DataAnnotations","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/selcukgural%2FSGuard.DataAnnotations/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/selcukgural%2FSGuard.DataAnnotations/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/selcukgural%2FSGuard.DataAnnotations/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/selcukgural","download_url":"https://codeload.github.com/selcukgural/SGuard.DataAnnotations/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/selcukgural%2FSGuard.DataAnnotations/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279000701,"owners_count":26082837,"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-10-08T02:00:06.501Z","response_time":56,"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":["attributes","data-annotations","dotnet","enterprise","guard","library","localization","multilingual","validation"],"created_at":"2025-10-08T21:51:01.313Z","updated_at":"2025-10-08T21:51:02.737Z","avatar_url":"https://github.com/selcukgural.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SGuard.DataAnnotations\n\n![CI](https://github.com/selcukgural/SGuard.DataAnnotations/actions/workflows/ci.yml/badge.svg)\n[![NuGet Version](https://img.shields.io/nuget/v/SGuard.DataAnnotations.svg?style=flat-square)](https://www.nuget.org/packages/SGuard.DataAnnotations/)\n[![NuGet Downloads](https://img.shields.io/nuget/dt/SGuard.DataAnnotations.svg?style=flat-square)](https://www.nuget.org/packages/SGuard.DataAnnotations/)\n[![Coverage](https://codecov.io/gh/selcukgural/SGuard.DataAnnotations/branch/main/graph/badge.svg)](https://codecov.io/gh/selcukgural/SGuard.DataAnnotations)\n\n\n**SGuard.DataAnnotations** provides localized and extensible DataAnnotations support for .NET, including:\n- Localizable validation attributes (with robust fallback and custom error handling)\n- Collection, conditional, and property comparison validators are not found in standard DataAnnotations\n- Guard pattern (`Is.*` for boolean return, `ThrowIf.*` for exception-throwing) for model validation\n- Seamless integration with DataAnnotations and SGuard's fail-fast/callback philosophy\n- Well-tested and extensible for real-world application scenarios\n\n\u003e **Note:** For fluent validation/guard support, see the upcoming [`SGuard.FluentValidation`](https://github.com/selcukgural/SGuard.FluentValidation) package.\n\u003e\n\u003e **Important:** If you want to implement custom callback, fail-fast, or chainable guard logic, you should also review the [SGuard core project](https://github.com/selcukgural/SGuard), which provides advanced guard and callback APIs used by this library.\n\n---\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Features](#features)\n- [Supported Languages](#supported-languages)\n- [Supported Attributes](#supported-attributes)\n    - [String \u0026 Common Validators](#string--common-validators)\n    - [Collection Validators](#collection-validators)\n    - [Conditional Validators](#conditional-validators)\n    - [Comparison Validators](#comparison-validators)\n- [Guard Pattern API](#guard-pattern-api)\n    - [Is.* Methods](#is-methods)\n    - [ThrowIf.* Methods](#throwif-methods)\n- [Localization \u0026 Fallback](#localization--fallback)\n- [Extending SGuard.DataAnnotations](#extending-sguarddataannotations)\n- [Minimal API Example (Real World)](#minimal-api-example-real-world)\n- [Advanced Topics](#advanced-topics)\n    - [Error Handling](#error-handling)\n- [FAQ / Tips](#faq--tips)\n- [Contributing](#contributing)\n- [License](#license)\n\n---\n\n## Installation\n\nInstall via NuGet:\n\n```bash\ndotnet add package SGuard.DataAnnotations\n```\n\n---\n\n## Features\n\n- **Localized error messages** via resource files (`.resx`), with fallback to default or custom messages.\n- **Advanced collection and conditional validation** (min/max count, required-if, required collection, collection element validation, etc.).\n- **Comparison attributes** for property-to-property or value-to-value checks (greater than, less than, between, compare, etc.).\n- **Full DataAnnotations compatibility**—use SGuard attributes anywhere a standard attribute is accepted.\n- **Guard pattern API** (`Is`/`ThrowIf`) for easy imperative validation and exception/callback handling.\n\n---\n\n## Supported Languages\n\nSGuard.DataAnnotations ships with built-in resource support for the following languages:\n\n| Language          | Culture Code | Localized Resource File         |\n|-------------------|--------------|---------------------------------|\n| English (default) | `en`         | `SGuardDataAnnotations.resx`    |\n| Turkish           | `tr`         | `SGuardDataAnnotations.tr.resx` |\n| German            | `de`         | `SGuardDataAnnotations.de.resx` |\n| French            | `fr`         | `SGuardDataAnnotations.fr.resx` |\n| Russian           | `ru`         | `SGuardDataAnnotations.ru.resx` |\n| Japanese          | `ja`         | `SGuardDataAnnotations.ja.resx` |\n| Hindi             | `hi`         | `SGuardDataAnnotations.hi.resx` |\n\n\u003e **Note:**\n\u003e - If the current UI culture is not found, SGuard will fallback to English or to the fallback message if provided.\n\u003e - You can add your own resource files to support additional languages.\n\u003e - [How to add your own language?](#how-to-add-a-custom-language)\n---\n\n## Supported Attributes\n\n### String \u0026 Common Validators\n\n| Attribute                          | Purpose                              | Supported Types                  | Example Usage                                                                                                         |\n|------------------------------------|--------------------------------------|----------------------------------|-----------------------------------------------------------------------------------------------------------------------|\n| `SGuardRequiredAttribute`          | Required field (localized)           | Any                              | `[SGuardRequired(typeof(Resources.SGuardDataAnnotations), \"Username_Required\")]`                                      |\n| `SGuardMinLengthAttribute`         | Minimum string length                | `string`, `array`, `ICollection` | `[SGuardMinLength(5, typeof(Resources.SGuardDataAnnotations), \"Username_MinLength\")]`                                 |\n| `SGuardMaxLengthAttribute`         | Maximum string length                | `string`, `array`, `ICollection` | `[SGuardMaxLength(20, typeof(Resources.SGuardDataAnnotations), \"Username_MaxLength\")]`                                |\n| `SGuardStringLengthAttribute`      | Min/max string length                | `string`                         | `[SGuardStringLength(12, typeof(Resources.SGuardDataAnnotations), \"Username_MaxLength\")]`                             |\n| `SGuardRegularExpressionAttribute` | Regex pattern                        | `string`                         | `[SGuardRegularExpression(\"^[a-zA-Z0-9_]+$\", typeof(Resources.SGuardDataAnnotations), \"Username_InvalidCharacters\")]` |\n| `SGuardEmailAddressAttribute`      | Email format                         | `string`                         | `[SGuardEmailAddress(typeof(Resources.SGuardDataAnnotations), \"Email_InvalidFormat\")]`                                |\n| `SGuardPhoneAttribute`             | Phone format                         | `string`                         | `[SGuardPhone(typeof(Resources.SGuardDataAnnotations), \"Profile_Phone_Invalid\")]`                                     |\n| `SGuardUrlAttribute`               | URL format                           | `string`                         | `[SGuardUrl(typeof(Resources.SGuardDataAnnotations), \"Common_Url_Invalid\")]`                                          |\n| `SGuardCreditCardAttribute`        | Credit card format                   | `string`                         | `[SGuardCreditCard(typeof(Resources.SGuardDataAnnotations), \"Common_CreditCard_Invalid\")]`                            |\n| `SGuardRangeAttribute`             | Value must be within a numeric range | `int`, `double`                  | `[SGuardRange(1, 10, typeof(Resources.SGuardDataAnnotations), \"Common_Range\")]`                                       |\n\n### Collection Validators\n\n| Attribute                             | Purpose                                                         | Supported Types             | Example Usage                                                                                                                                            |\n|---------------------------------------|-----------------------------------------------------------------|-----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `SGuardRequiredCollectionAttribute`   | Collection must not be null/empty                               | `IEnumerable`, arrays, etc. | `[SGuardRequiredCollection(typeof(Resources.SGuardDataAnnotations), \"Common_Collection_Required\")]`                                                      |\n| `SGuardMinCountAttribute`             | Minimum item count in collection                                | `IEnumerable`, arrays, etc. | `[SGuardMinCount(2, typeof(Resources.SGuardDataAnnotations), \"Common_Collection_MinCount\")]`                                                             |\n| `SGuardMaxCountAttribute`             | Maximum item count in collection                                | `IEnumerable`, arrays, etc. | `[SGuardMaxCount(5, typeof(Resources.SGuardDataAnnotations), \"Common_Collection_MaxCount\")]`                                                             |\n| `SGuardCollectionItemsMatchAttribute` | Each item must match one/more validators (e.g. regex, required) | `IEnumerable`, arrays, etc. | `[SGuardCollectionItemsMatch(typeof(EmailAddressAttribute), typeof(Resources.SGuardDataAnnotations), \"Email_InvalidFormat\", AggregateAllErrors = true)]` |\n\n**Details:**\n- `SGuardCollectionItemsMatchAttribute` can take multiple validators and will apply them to each item.\n- `AggregateAllErrors` (default: `false`): If `true`, collects all errors; if `false`, returns on first failure.\n- Supported on any `IEnumerable` (e.g., `List\u003cT\u003e`, arrays, custom collections).\n\n### Conditional Validators\n\n| Attribute                   | Purpose                                         | Supported Types | Example Usage                                                                                       |\n|-----------------------------|-------------------------------------------------|-----------------|-----------------------------------------------------------------------------------------------------|\n| `SGuardRequiredIfAttribute` | Field required if another property equals value | Any             | `[SGuardRequiredIf(\"Country\", \"USA\", typeof(Resources.SGuardDataAnnotations), \"Address_Required\")]` |\n\n### Comparison Validators\n\n| Attribute                    | Purpose                                      | Supported Types   | Example Usage                                                                                            |\n|------------------------------|----------------------------------------------|-------------------|----------------------------------------------------------------------------------------------------------|\n| `SGuardCompareAttribute`     | Values must be equal (like CompareAttribute) | Any               | `[SGuardCompare(\"Password\", typeof(Resources.SGuardDataAnnotations), \"Password_Mismatch\")]`              |\n| `SGuardBetweenAttribute`     | Value must be between two properties         | IComparable types | `[SGuardBetween(\"Min\", \"Max\", true, typeof(Resources.SGuardDataAnnotations), \"Common_Between\")]`         |\n| `SGuardGreaterThanAttribute` | Value must be greater than another property  | IComparable types | `[SGuardGreaterThan(\"MinAge\", typeof(Resources.SGuardDataAnnotations), \"Profile_BirthDate_MinimumAge\")]` |\n| `SGuardLessThanAttribute`    | Value must be less than another property     | IComparable types | `[SGuardLessThan(\"MaxAge\", typeof(Resources.SGuardDataAnnotations), \"Profile_BirthDate_MaximumAge\")]`    |\n\n**Supported types:** `int`, `double`, `decimal`, `DateTime`, `string`, etc. (anything implementing `IComparable`)\n\n---\n\n## Guard Pattern API\n\n**SGuard.DataAnnotations** provides two imperative APIs for runtime validation, following the SGuard pattern.\n\n### Is.* Methods\n\n- **Purpose:** Return `bool` for validation checks (never throw).\n- **Callback:** Optional `SGuardCallback` invoked with `GuardOutcome.Success`/`Failure`.  \n  For advanced callback usage, see the [SGuard project documentation](https://github.com/selcukgural/SGuard).\n- **Example:**\n    ```csharp\n    if (Is.DataAnnotationsValid(model))\n    {\n        // model is valid\n    }\n    ```\n\n- **With callback:**\n    ```csharp\n    bool valid = Is.DataAnnotationsValid(model, callback: outcome =\u003e\n    {\n        if (outcome == GuardOutcome.Failure)\n            Console.WriteLine(\"Validation failed!\");\n    });\n    ```\n\n- **Get all validation errors:**\n    ```csharp\n    bool valid = Is.DataAnnotationsValid(model, out var results);\n    foreach (var err in results)\n        Console.WriteLine($\"{string.Join(\", \", err.MemberNames)}: {err.ErrorMessage}\");\n    ```\n\n### ThrowIf.* Methods\n\n- **Purpose:** Throw exception if validation fails.\n- **Callback:** Invoked before throw (`GuardOutcome.Failure`) or on pass (`GuardOutcome.Success`).\n- **Example:**\n    ```csharp\n    ThrowIf.DataAnnotationsInValid(model);\n    // Throws DataAnnotationsException if model is invalid.\n    ```\n\n- **Custom exception:**\n    ```csharp\n    ThrowIf.DataAnnotationsInValid\u003cArgumentException\u003e(model, new ArgumentException(\"Custom error!\"));\n    ```\n\n- **Custom exception with constructor args:**\n    ```csharp\n    ThrowIf.DataAnnotationsInValid\u003cArgumentException\u003e(model, new object[] { \"Custom error!\" });\n    ```\n\n#### Exception Details\n\n- Throws `DataAnnotationsException` by default, which contains all validation errors.\n- Extract errors (see also [`SGuard.DataAnnotations.Extensions`](./SGuard.DataAnnotations/src/Extensions/DataAnnotationsExceptionExtensions.cs)):\n    ```csharp\n    catch (DataAnnotationsException ex)\n    {\n        if (ex.TryGetValidationErrors(out var errors))\n        {\n            foreach (var err in errors)\n                Console.WriteLine($\"{string.Join(\", \", err.Members)}: {err.Message}\");\n        }\n    }\n    ```\n\n---\n\n## Localization \u0026 Fallback\n\n- All SGuard attributes support:\n    - `ErrorMessageResourceType` and `ErrorMessageResourceName` (standard .NET resource workflow)\n    - `FallbackResourceName`: Used if the main resource key is missing.\n    - `FallbackMessage`: Used if both resource keys are missing.\n- **Culture:** Error messages are localized to the current `UICulture`.\n- **Example:**\n    ```csharp\n    [SGuardMinLength(3, typeof(Resources.SGuardDataAnnotations), \"Username_MinLength\", \n        FallbackResourceName = \"Common_MinLength\", FallbackMessage = \"Min length required.\")]\n    public string Username { get; set; }\n    ```\n\n### How to add a custom language?\n\n1. Copy `SGuardDataAnnotations.resx` and rename to e.g. `SGuardDataAnnotations.es.resx` for Spanish.\n2. Translate all keys/values.\n3. Rebuild and set your thread/UI culture accordingly.\n\n---\n\n## Extending SGuard.DataAnnotations\n\nWant to add your own fully localized validation attribute?  \nInherit from `SGuardValidationAttributeBase` and implement `IsValid`:\n\n```csharp\npublic class MyCustomLocalizedAttribute : SGuardValidationAttributeBase\n{\n    public MyCustomLocalizedAttribute(Type resourceType, string resourceName)\n        : base(resourceType, resourceName) {}\n\n    protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)\n    {\n        // Your logic here\n        if (value == null) \n            return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));\n        return ValidationResult.Success;\n    }\n}\n```\n\n---\n\n## Minimal API Example (Real World)\n\nHere's how you use SGuard.DataAnnotations in an ASP.NET Core Minimal API:\n\n```csharp\nusing Microsoft.AspNetCore.Builder;\nusing Microsoft.AspNetCore.Http;\nusing SGuard.DataAnnotations;\n\nvar builder = WebApplication.CreateBuilder(args);\nvar app = builder.Build();\n\napp.MapPost(\"/register\", (UserRegistration model) =\u003e\n{\n    if (!Is.DataAnnotationsValid(model, out var errors))\n        return Results.BadRequest(errors.Select(e =\u003e new { e.MemberNames, e.ErrorMessage }));\n\n    // If valid, continue\n    return Results.Ok(\"Registration successful!\");\n});\n\napp.Run();\n\npublic class UserRegistration\n{\n    [SGuardRequired(typeof(Resources.SGuardDataAnnotations), \"Username_Required\")]\n    [SGuardMinLength(3, typeof(Resources.SGuardDataAnnotations), \"Username_MinLength\")]\n    [SGuardMaxLength(20, typeof(Resources.SGuardDataAnnotations), \"Username_MaxLength\")]\n    public string Username { get; set; }\n\n    [SGuardRequired(typeof(Resources.SGuardDataAnnotations), \"Email_Required\")]\n    [SGuardEmailAddress(typeof(Resources.SGuardDataAnnotations), \"Email_InvalidFormat\")]\n    public string Email { get; set; }\n\n    [SGuardRequired(typeof(Resources.SGuardDataAnnotations), \"Password_Required\")]\n    [SGuardStringLength(100, typeof(Resources.SGuardDataAnnotations), \"Password_MaxLength\")]\n    public string Password { get; set; }\n\n    [SGuardCompare(\"Password\", typeof(Resources.SGuardDataAnnotations), \"Password_Mismatch\")]\n    public string ConfirmPassword { get; set; }\n\n    [SGuardRequiredCollection(typeof(Resources.SGuardDataAnnotations), \"Profile_Phone_Required\")]\n    [SGuardCollectionItemsMatch(typeof(SGuardPhoneAttribute), typeof(Resources.SGuardDataAnnotations), \"Profile_Phone_Invalid\", AggregateAllErrors = true)]\n    public List\u003cstring\u003e PhoneNumbers { get; set; }\n}\n```\n\n---\n\n## Advanced Topics\n\n### Error Handling\n\n- **Guard methods**: Return `bool` or throw, never both.\n- **Attributes**: Always return `ValidationResult`, never throw.\n- **All exceptions**: Contain full error detail, member names, and support for extraction/extension.\n- **For advanced fail-fast, callback, or custom guard usage:**  \n  See [SGuard project documentation](https://github.com/selcukgural/SGuard).\n\n---\n\n## FAQ / Tips\n\n**Q:** _Can I use SGuard attributes in ASP.NET Core, Blazor, WinForms, etc.?_  \n**A:** Yes, SGuard attributes implement the standard DataAnnotations contract.\n\n**Q:** _What happens if a resource key is missing?_  \n**A:** The attribute will use `FallbackResourceName` if provided, otherwise `FallbackMessage`, otherwise `[ResourceKey]`.\n\n**Q:** _How do I validate a collection’s items?_  \n**A:** Use `[SGuardCollectionItemsMatch(...)]`. See [Collection Validators](#collection-validators).\n\n**Q:** _Can I chain SGuard and standard DataAnnotations attributes?_  \n**A:** Yes, you can stack any combination on your model.\n\n**Q:** _Will SGuard.DataAnnotations work with FluentValidation?_  \n**A:** Yes, as long as you use DataAnnotations integration. For a full fluent API, see [`SGuard.FluentValidation`](https://github.com/selcukgural/SGuard.ValidationBuilder).\n\n**Q:** _How do I quickly test everything?_  \n**A:**\n1. Run all tests (requires .NET SDK):\n    ```bash\n    dotnet test\n    ```\n2. For a quick validation in your app, call:\n    ```csharp\n    if (!Is.DataAnnotationsValid(model, out var results))\n        // handle errors, see 'results'\n    ```\n\n---\n\n## Contributing\n\nPull requests, issues, and suggestions are very welcome!  \nSee [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.\n\n---\n\n## License\n\nMIT License. See [LICENSE](LICENSE).\n\n---\n\n## See Also\n\n- [SGuard (core)](https://github.com/selcukgural/SGuard)\n- [SGuard.FluentValidation (upcoming)](https://github.com/selcukgural/SGuard.FluentValidation)\n\n---\n\u003c!-- TEST-RESULTS:START --\u003e\n## Test and Coverage Status\n\n### Test Results\n\n| Total | Passed | Failed | Skipped |\n|------:|-------:|-------:|--------:|\n| 353 | 353 | 0 | 0 |\n\n### Code Coverage\n# Summary\n|||\n|:---|:---|\n| Generated on: | 09/09/2025 - 22:27:29 |\n| Coverage date: | 09/09/2025 - 22:27:26 - 09/09/2025 - 22:27:27 |\n| Parser: | MultiReport (4x Cobertura) |\n| Assemblies: | 1 |\n| Classes: | 25 |\n| Files: | 25 |\n| **Line coverage:** | 87% (276 of 317) |\n| Covered lines: | 276 |\n| Uncovered lines: | 41 |\n| Coverable lines: | 317 |\n| Total lines: | 1470 |\n| **Branch coverage:** | 80.7% (185 of 229) |\n| Covered branches: | 185 |\n| Total branches: | 229 |\n| **Method coverage:** | [Feature is only available for sponsors](https://reportgenerator.io/pro) |\n\n|**Name**|**Covered**|**Uncovered**|**Coverable**|**Total**|**Line coverage**|**Covered**|**Total**|**Branch coverage**|\n|:---|---:|---:|---:|---:|---:|---:|---:|---:|\n|**SGuard.DataAnnotations**|**276**|**41**|**317**|**1470**|**87%**|**185**|**229**|**80.7%**|\n|SGuard.DataAnnotations.CompareToAttribute|26|13|39|139|66.6%|16|31|51.6%|\n|SGuard.DataAnnotations.Exceptions.DataAnnotationsException|14|0|14|62|100%|2|2|100%|\n|SGuard.DataAnnotations.Extensions.DataAnnotationsExceptionExtensions|9|1|10|47|90%|9|10|90%|\n|SGuard.DataAnnotations.Internal.SGuardDataAnnotations|10|2|12|59|83.3%|6|6|100%|\n|SGuard.DataAnnotations.Is|5|5|10|76|50%|0|0||\n|SGuard.DataAnnotations.SGuardBetweenAttribute|28|2|30|114|93.3%|28|32|87.5%|\n|SGuard.DataAnnotations.SGuardCollectionItemsMatchAttribute|29|4|33|124|87.8%|17|22|77.2%|\n|SGuard.DataAnnotations.SGuardCompareAttribute|4|0|4|25|100%|4|4|100%|\n|SGuard.DataAnnotations.SGuardCreditCardAttribute|7|0|7|38|100%|2|2|100%|\n|SGuard.DataAnnotations.SGuardEmailAddressAttribute|7|0|7|40|100%|2|2|100%|\n|SGuard.DataAnnotations.SGuardGreaterThanAttribute|2|0|2|19|100%|0|0||\n|SGuard.DataAnnotations.SGuardLessThanAttribute|2|0|2|17|100%|0|0||\n|SGuard.DataAnnotations.SGuardMaxCountAttribute|18|2|20|87|90%|16|18|88.8%|\n|SGuard.DataAnnotations.SGuardMaxLengthAttribute|4|0|4|25|100%|4|4|100%|\n|SGuard.DataAnnotations.SGuardMinCountAttribute|18|2|20|87|90%|18|20|90%|\n|SGuard.DataAnnotations.SGuardMinLengthAttribute|4|0|4|25|100%|4|4|100%|\n|SGuard.DataAnnotations.SGuardPhoneAttribute|7|0|7|38|100%|2|2|100%|\n|SGuard.DataAnnotations.SGuardRangeAttribute|8|0|8|42|100%|6|8|75%|\n|SGuard.DataAnnotations.SGuardRegularExpressionAttribute|0|4|4|26|0%|0|4|0%|\n|SGuard.DataAnnotations.SGuardRequiredCollectionAttribute|13|3|16|52|81.2%|11|14|78.5%|\n|SGuard.DataAnnotations.SGuardRequiredIfAttribute|17|0|17|82|100%|13|14|92.8%|\n|SGuard.DataAnnotations.SGuardStringLengthAttribute|4|0|4|24|100%|4|4|100%|\n|SGuard.DataAnnotations.SGuardUrlAttribute|7|0|7|38|100%|2|2|100%|\n|SGuard.DataAnnotations.SGuardValidationAttributeBase|19|1|20|83|95%|19|24|79.1%|\n|SGuard.DataAnnotations.ThrowIf|14|2|16|101|87.5%|0|0||\n\n\u003c!-- TEST-RESULTS:END --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fselcukgural%2Fsguard.dataannotations","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fselcukgural%2Fsguard.dataannotations","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fselcukgural%2Fsguard.dataannotations/lists"}