Attributes
You can use built-in .Net Localization Structure with milva attributes. For this, all milva attributes have constructor with Type resourceType
parameter or they have Type ResourceType
property. Also, all attributes generate error messages with specific Localizer Key in case of unsuccessful validation. These keys are provided in the following relevant sections of the document and LocalizerKeys class. If you are going to use the built-in .Net Localization structure, you can abstract by creating dummy validation attributes in your projects and avoid typing the type repeatedly while using the attribute. Examples are given in ValidateDecimal.
Validation Attributes
Validation attributes control some conditions. Returns ValidationResult if validation is successful or unsuccessful. You can override the .Net model validation for custom response with CommonHelper.CustomErrorResponse method.
ValidateDecimal
Checks if the value is decimal and within certain ranges. If you assign the LocalizerKey
property, the value you assign is added to the localizer arguments. If you do not assign this property, the default behavior will be to combine the "Localized" prefix with the name of the property. Also, if you return custom error message you can set FullMessage
property to true
.
Usage
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
public class MValidateDecimalAttribute : ValidateDecimalAttribute
{
public MValidateDecimalAttribute() : base(typeof(SharedResource)) { }
public MValidateDecimalAttribute(int minValue) : base(minValue, typeof(SharedResource)) { }
}
//This property must be greater than or equal to 0.
[MValidateDecimal]
public int Quantity { get; set; }
//This property must be greater than or equal to 20.
[MValidateDecimal(20)]
public decimal Price { get; set; }
//This property must be greater than or equal to 0 and must be less than or equal to 18.
[MValidateDecimal(0, 18, LocalizerKey = "TaxRate")]
public decimal Tax { get; set; }
//This property must be greater than or equal to 1 and must be less than or equal to 100.
[MValidateDecimal(1, 100, LocalizerKey = "InvalidSoldCount", FullMessage = true)]
public int SoldCount { get; set; }
Default Localizer Key | Sample |
---|---|
"MinDecimalValueException" | Please enter a valid {0}. |
For example, if the Price
property is outside the specified range, it gives the following error message in different languages.
EN : "Please enter a valid Price."
TR : "Lütfen geçerli bir fiyat seçiniz."
Attribute Properties |
---|
(string) LocalizerKey |
(bool) FullMessage |
(decimal) MinValue |
(decimal?) MaxValue |
ValidateString
Checks if the value is within the specified number of characters and contains prohibited words. If you assign the MemberNameLocalizerKey
property, the value you assign is added to the localizer arguments. If you do not assign this property, the default behavior will be to combine the "Localized" prefix with the name of the property.
You can use prohibited word check;
var blackList = await jsonOperations.GetCryptedContentAsync<List<InvalidString>>("blacklist.json");
serviceCollection.AddSingleton(blackList);
Attribute will do equality check this black list if is registered with List<InvalidString>
type. If value contains prohibited word attribute return unsuccessfull validation result and sends mail if MailContent
property is not null.
Usage
//This property length must be less than 100.
[ValidateString(100)]
public string Name { get; set; }
//This property length must be between 10 and 200.
[ValidateString(10, 200)]
public string Descripton { get; set; }
//This property items length must be between 5 and 10.
[ValidateString(5, 10)]
public List<string> Tags { get; set; }
Default Localizer Key | Sample |
---|---|
"PreventStringInjectionLengthResultNotTrue" | {0} must have a character length in the range {1} to {2}. |
"{0} contains invalid words." | {0} must have a character length in the range {1} to {2}. |
"PreventStringInjectionBellowMin" | {0} is below the minimum character limit. Please enter at least {1} characters. |
"PreventStringInjectionContainsForbiddenWordError" | {0} contains invalid words. |
For example, if the Name
property length is outside the specified range, it gives the following error message in different languages.
EN : "Name is below the minimum character limit. Please enter at least 100 characters."
TR : "Ad, minimum karakter sınırının altında. Lütfen en az 100 karakter girin."
Another example, if the Description
property length is outside the specified range, it gives the following error message in different languages.
EN : "Description must have a character length in the range 10 to 20."
TR : "Açıklama, 10 ile 20 aralığında bir karakter uzunluğuna sahip olmalıdır."
Attribute Properties |
---|
(string) MemberNameLocalizerKey |
(int) MaximumLength |
(int) MinimumLength |
(string) MailContent |
(Type) ResourceType |
ValidateIdProperty
It provides validation of the Id values. If you assign the MemberNameLocalizerKey
property, the value you assign is added to the localizer arguments. If you do not assign this property, the default behavior will be to combine the "LocalizedEntityName" prefix with the property's name missing 2 characters from the end.
This attributes validates the following conditions;
- For
Guid
andList<Guid>
types;- Checks whether value is equal to the
Guid.Empty
- Checks whether value is compatible with
"^[{]?[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}[}]?$"
regex
- Checks whether value is equal to the
- For
int
andList<int>
types;- Checks whether value is greater than 0
Usage
[ValidateIdProperty]
public Guid ProductId { get; set; }
[ValidateIdProperty]
public int? UserId { get; set; }
[ValidateIdProperty(MemberNameLocalizerKey = "Attachment", DontCheckNullable = true)]
public List<Guid> AttachmentIdList { get; set; }
Default Localizer Key | Sample |
---|---|
"ValidationIdPropertyError" | Please select a valid {0}. |
For example, if the ProductId
property length is outside the specified range, it gives the following error message in different languages.
EN : "Please select a valid Product."
TR : "Lütfen geçerli bir Ürün seçiniz."
Another example, if the AttachmentIdList
property item count is 0, it doesn't give any error message according to DontCheckNullable property.
Attribute Properties |
---|
(string) MemberNameLocalizerKey |
(bool) DontCheckNullable |
ValidateListCount
Checks if the number of elements in the list is outside the specified range. If you assign the LocalizerKey
property, the value you assign is added to the localizer arguments. If you do not assign this property, the default behavior will be to combine the "Localized" prefix with the name of the property.
Usage
//This property item count must be greater than 10.
[ValidateListCount(10, LocalizerKey = "Product" )]
public List<Product> ProductList { get; set; }
Default Localizer Key | Sample |
---|---|
"ListCountBelowMin" | Please select/send at least {0} {1}. |
"ListCountMustBe" | The number of {0} must be {1}. |
"ListCountNotValid" | The number of {0} must be minimum {1} and maximum {2}. |
For example, if the ProductList
property item count is outside the specified range, it gives the following error message in different languages.
EN : "Please select/send at least 10 Product."
TR : "Lütfen en az 10 Ürün seçiniz/gönderiniz."
Attribute Properties |
---|
(string) LocalizerKey |
(int) MinCount |
(int?) MaxCount |
MilvaRegex
Regular expressions are specially encoded text strings used as patterns for matching sets of strings. Checks if the value matches the specified regex. If you assign the MemberNameLocalizerKey
property, the value you assign is added to the localizer arguments. If you do not assign this property, the default behavior will be to combine the "Localized" prefix with the name of the property.
You can use this attribute with 2 option;
- You can define regex to the attribute constructor
- You can define regex to the
.resx
file
In the example below, the RegexPatternEmail
key is searched in the .resx
file for the Email
property.
Usage
[MilvaRegex("^(0 (\d{3}) (\d{3}) (\d{2}) (\d{2}))$")]
public string PhoneNumber { get; set; }
[MilvaRegex(IsRequired = false)]
public string Email { get; set; }
Default Localizer Key | Sample |
---|---|
"RegexErrorMessage" | {0} is not in the correct format. Please enter in this format: {1} |
For example, if the Email
property item count is outside the specified range, it gives the following error message in different languages.
EN : "Email is not in the correct format. Please enter in this format: [email protected]"
TR : "Email, düzgün formatta değil. Lütfen şu formatta girin: [email protected]"
Attribute Properties |
---|
(string) MemberNameLocalizerKey |
(string) ExampleFormatLocalizerKey |
(bool) IsRequired |
ValidateEnum
Checks whether the value sent for enum properties is in the enum. If you assign the LocalizerKey
property, the value you assign is added to the localizer arguments. If you do not assign this property, the default behavior will be to combine the "Localized" prefix with the name of the property. Also, if you return custom error message you can set FullMessage
property to true
.
Usage
[ValidateEnum]
public AttachmentType Type { get; set; }
Default Localizer Key | Sample |
---|---|
"PleaseSelectAValid" | Please select a valid {0}. |
For example, if the Type
property value is not among the values defined in the AttachmentType
enum, it gives the following error message in different languages.
EN : "Please select a valid Attachment Type."
TR : "Lütfen geçerli bir Dosya Tipi seçiniz."
Attribute Properties |
---|
(string) LocalizerKey |
(bool) FullMessage |
Action Filters
There are 2 types of action filters, async and sync. Both are available in the library. In this documentation we will only consider the sync one.
ValidateStringParameter
It does the same checks as the ValidateString attribute. The only difference here is that it does this for method parameters.
Usage
[HttpGet("Users/User/{username}")]
[ValidateStringParameter(3, 30)]
public async Task<IActionResult> GetUserByUsernameAsync(string username)
Attribute parameters and localizer keys are same as the ValidateString attribute.
ValidateIdParameter
It does the same checks as the ValidateIdProperty attribute. The only difference here is that it does this for method parameters.
Usage
[HttpGet("Users/User/{userId}")]
[ValidateIdParameter(3, 30)]
public async Task<IActionResult> GetUserByIdAsync(string userId)
Attribute parameters and localizer keys are same as the ValidateIdProperty attribute.
Validation Filter
Provides the attribute validation exclude opportunity. You may need this attribute in update operations. For example, suppose we use the same DTO for user Add and Update endpoints. Suppose we apply a validation on behalf of the user while adding the user, but we do not want this validation to be performed because the username cannot be updated during the update process.
Usage
[ValidationFilter(DisabledProperties = "Username")]
public async Task<IActionResult> UpdateUserAsync(UserUpdateDTO userUpdateDTO){ ... }
[ValidationFilter(DisabledProperties = "Username,Password")]
public async Task<IActionResult> UpdateUserAsync(UserUpdateDTO userUpdateDTO){ ... }
Properties | Description |
---|---|
DisabledProperties | "Names of properties to be canceled." |
DisabledNestedProperties | "If we want nested properties to be disabled." |
AssemblyTypeForNestedProps | "Assembly type for disable nested type property validations." |
DTOFolderAssemblyName | "Folder assembly name for disable nested type property validations." |