Skip to main content
Version: 1.0.1

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

Dummy attribute sample;

[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 KeySample
"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 KeySample
"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 and List<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
  • For int and List<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 KeySample
"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 KeySample
"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 KeySample
"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 KeySample
"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){ ... }

PropertiesDescription
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."