Skip to content

Commit

Permalink
v1.1.0: Added UmbracoIFormFileExtensions and UmbracoMaxFileSize attri…
Browse files Browse the repository at this point in the history
…butes, as suggested in #1
  • Loading branch information
ZioTino committed Jan 24, 2022
1 parent 19d0cc9 commit e00bf0b
Show file tree
Hide file tree
Showing 5 changed files with 212 additions and 13 deletions.
46 changes: 36 additions & 10 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Include the following scripts in your layout.cshtml file, or in your master page
```

The above is just a sample, you may use any method you like to include the scripts.
**NOTE: *jquery.validation.custom.js* is required to ensure that the UmbracoMustBeTrue attribute is working.**
**NOTE: *jquery.validation.custom.js* is required to ensure that UmbracoIFormFileExtensions, UmbracoMaxFileSize and UmbracoMustBeTrue attributes are working correctly.**
**As an alternative you can include yourself its content with any method you like.**

The end result for a page with validation could look like:
Expand Down Expand Up @@ -70,6 +70,8 @@ Decorate your properties with the following attributes
* UmbracoCompare
* UmbracoDisplayName
* UmbracoEmailAddress
* UmbracoIFormFileExtensions
* UmbracoMaxFileSize
* UmbracoMaxLength
* UmbracoMinLength
* UmbracoMustBeTrue
Expand All @@ -85,7 +87,7 @@ Decorate your properties with the following attributes
public string MyProperty { get; set; }
```

### UmbracoCompareAttribute
### UmbracoCompare

| Umbraco Dictionary Key | Default |
| -- | -- |
Expand All @@ -109,7 +111,7 @@ public string ConfirmPassword { get; set; }

| Key | Default |
| -- | -- |
| Provied key | Must be created by your self. |
| Provied key | Must be created by yourself. |

Example:
```C#
Expand All @@ -122,19 +124,43 @@ public string Username { get; set; }

| Key | Default |
| -- | -- |
| EmailError | Must be created by your self. |
| EmailError | Must be created by yourself. |

Example:
```C#
[UmbracoEmailAddress]
public string Email { get; set; }
```

### UmbracoIFormFileExtensions

| Key | Default |
| -- | -- |
| FormFileExtensionsError | Must be created by yourself. |

Example:
```C#
[UmbracoIFormFileExtensions("jpeg,png,jpg")] // List of comma-separated file extensions
public IFormFile UmbracoIFormFileExtensions { get; set; }
```

### UmbracoMaxFileSize

| Key | Default |
| -- | -- |
| MaxFileSizeError | Must be created by yourself. |

Example:
```C#
[UmbracoMaxFileSize(5 * 1024 * 1024)] // Max size in bytes
public IFormFile UmbracoMaxFileSize { get; set; }
```

### UmbracoMinLength

| Key | Default |
| -- | -- |
| MinLengthError | Must be created by your self. |
| MinLengthError | Must be created by yourself. |

Example:
```C#
Expand All @@ -146,7 +172,7 @@ public string MyProperty { get; set; }

| Key | Default |
| -- | -- |
| MaxLengthError | Must be created by your self. |
| MaxLengthError | Must be created by yourself. |

Example:
```C#
Expand All @@ -158,7 +184,7 @@ public string MyProperty { get; set; }

| Key | Default
| -- | -- |
| MinMaxLengthError | Must be created by your self. |
| MinMaxLengthError | Must be created by yourself. |

Examples:
```C#
Expand All @@ -172,7 +198,7 @@ public string Message { get; set; }
### UmbracoMustBeTrue
| Key | Default |
| -- | -- |
| MustBeTrueError | Must be created by your self. |
| MustBeTrueError | Must be created by yourself. |

Example:
```C#
Expand All @@ -199,11 +225,11 @@ public string MyProperty { get; set; }
```

## Custom dictionary keys
Each Attribute, has a public property `DictionaryKey` which can be set like this:
Each Attribute has a public property `DictionaryKey` which can be set like this:
```C#
[UmbracoRequired(DictionaryKey = "MyCustomKey")]
public string MyProperty { get; set; }
```

Not setting a custom key, will fallback to the default dictionary key.
**You have to create Dictionary Keys manually, taking example from this documentation.**
**You have to create Dictionary Keys manually, as explained in this documentation.**
Original file line number Diff line number Diff line change
@@ -1,2 +1,51 @@
// Requires jquery, jquery-validation and jquery-validation-unobtrusive to work.
$.validator.unobtrusive.adapters.addBool("mustbetrue", "required");

// Validator for UmbracoMustBeTrueAttribute
$.validator.unobtrusive.adapters.addBool("mustbetrue", "required");

// Validators for UmbracoMaxFileSizeAttribute
$.validator.addMethod("maxfilesize", function (value, element, param) {
if (value === "") {
return true;
}
var maxBytes = parseInt(param);
if (element.files !== undefined && element.files[0] !== undefined && element.files[0].size !== undefined) {
var filesize = parseInt(element.files[0].size);
return filesize <= maxBytes;
}
return true;
});
$.validator.unobtrusive.adapters.add('maxfilesize', ['size'], function (options) {
options.rules['maxfilesize'] = options.params.size;
if (options.message) {
options.messages['maxfilesize'] = options.message;
}
});

// Validators for UmbracoIFormFileExtensionsAttribute
$.validator.addMethod("filetypes", function(value, element, param) {
if (value === "") {
return true;
}
var validFileTypes = [];
if (param.indexOf(',') > -1) {
validFileTypes = param.split(',');
} else {
validFileTypes = [param];
}
var currentFileType = value.split('.')[value.split('.').length - 1];
for (var i = 0; i < validFileTypes.length; i++)
{
if (validFileTypes[i] === currentFileType)
{
return true;
}
}
return false;
});
$.validator.unobtrusive.adapters.add('filetypes', ['types'], function(options) {
options.rules['filetypes'] = options.params.types;
if (options.message) {
options.messages['filetypes'] = options.message;
}
});
4 changes: 2 additions & 2 deletions src/Our.Umbraco.ValidationAttributes.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<Title>Umbraco.ValidationAttributes</Title>
<Description>[Umbraco v9] Contains validation attributes to decorate your classes, but using Umbraco Dictionary as the resource.</Description>
<PackageTags>umbraco plugin package</PackageTags>
<Version>1.0.2</Version>
<Version>1.1.0</Version>
<Authors>ZioTino</Authors>
<RootNamespace>Our.Umbraco.ValidationAttributes</RootNamespace>
<PackageLicenseFile>LICENSE.md</PackageLicenseFile>
Expand All @@ -24,7 +24,7 @@

<ItemGroup>
<None Include="..\LICENSE.md" Pack="true" PackagePath=""/>
<None Include="..\README.md" Pack="true" PackagePath=""/>
<None Include="..\docs\README.md" Pack="true" PackagePath=""/>
<None Include="..\assets\icon.png" Pack="true" PackagePath="\"/>
</ItemGroup>

Expand Down
67 changes: 67 additions & 0 deletions src/UmbracoIFormFileExtensionsAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using J2N.Collections.Generic;
using Lucene.Net.Analysis.Hunspell;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using Our.Umbraco.ValidationAttributes.Helpers;
using Our.Umbraco.ValidationAttributes.Interfaces;
using Our.Umbraco.ValidationAttributes.Services;

namespace Our.Umbraco.ValidationAttributes
{
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public sealed class UmbracoIFormFileExtensionsAttribute : ValidationAttribute, IClientModelValidator, IUmbracoValidationAttribute
{
public string DictionaryKey {get; set;} = "FormFileExtensionsError";

public string[] ValidFileTypes { get; set; }

public UmbracoIFormFileExtensionsAttribute(string fileTypes)
{
ValidFileTypes = ParseFileTypes(fileTypes);
}

public UmbracoIFormFileExtensionsAttribute(string fileTypes, string dictionaryKey)
{
DictionaryKey = dictionaryKey;
ValidFileTypes = ParseFileTypes(fileTypes);
}

public void AddValidation(ClientModelValidationContext context)
{
ErrorMessage = ValidationAttributesService.DictionaryValue(DictionaryKey);
ErrorMessage = FormatErrorMessage(string.Join(", ", ValidFileTypes));
AttributeHelper.MergeAttribute(context.Attributes, "data-val", "true");
AttributeHelper.MergeAttribute(context.Attributes, "data-val-filetypes", ErrorMessage);
AttributeHelper.MergeAttribute(context.Attributes, "data-val-filetypes-types", string.Join(',', ValidFileTypes));

// input type="file" accept attribute
List<string> validExtensions = new List<string>();
foreach (string type in ValidFileTypes)
{
validExtensions.Add($".{type}");
}
AttributeHelper.MergeAttribute(context.Attributes, "accept", string.Join(',', validExtensions));
}

public override bool IsValid(object value)
{
IFormFile file = value as IFormFile;
bool isValid = true;

if (file != null)
{
isValid = ValidFileTypes.Any(x => file.FileName.EndsWith(x));
}

return isValid;
}

private string[] ParseFileTypes(string fileTypes)
{
return fileTypes.ToLower().Split(',');
}
}
}
57 changes: 57 additions & 0 deletions src/UmbracoMaxFileSizeAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System;
using System.ComponentModel.DataAnnotations;
using Lucene.Net.Analysis.Hunspell;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using Our.Umbraco.ValidationAttributes.Helpers;
using Our.Umbraco.ValidationAttributes.Interfaces;
using Our.Umbraco.ValidationAttributes.Services;

namespace Our.Umbraco.ValidationAttributes
{
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public sealed class UmbracoMaxFileSizeAttribute : ValidationAttribute, IClientModelValidator, IUmbracoValidationAttribute
{
public string DictionaryKey { get; set; } = "MaxFileSizeError";

public int MaxFileSize { get; set; }

public UmbracoMaxFileSizeAttribute(int maxFileSize)
{
MaxFileSize = maxFileSize;
}

public UmbracoMaxFileSizeAttribute(int maxFileSize, string dictionaryKey)
{
DictionaryKey = dictionaryKey;
MaxFileSize = maxFileSize;
}

public void AddValidation(ClientModelValidationContext context)
{
ErrorMessage = ValidationAttributesService.DictionaryValue(DictionaryKey);
ErrorMessage = FormatErrorMessage(GetMaxFileSizeInMB());
AttributeHelper.MergeAttribute(context.Attributes, "data-val", "true");
AttributeHelper.MergeAttribute(context.Attributes, "data-val-maxfilesize", ErrorMessage);
AttributeHelper.MergeAttribute(context.Attributes, "data-val-maxfilesize-size", MaxFileSize.ToString());
}

public override bool IsValid(object value)
{
IFormFile file = value as IFormFile;
bool isValid = true;

if (file != null)
{
isValid = file.Length <= MaxFileSize;
}

return isValid;
}

private string GetMaxFileSizeInMB()
{
return (MaxFileSize % 1048576M == 0) ? (MaxFileSize / 1048576).ToString() : Math.Round(MaxFileSize / 1048576M, 3).ToString();
}
}
}

0 comments on commit e00bf0b

Please sign in to comment.