diff --git a/Areas/Admin/Controllers/ProductController.cs b/Areas/Admin/Controllers/ProductController.cs index b091f91..3aab295 100644 --- a/Areas/Admin/Controllers/ProductController.cs +++ b/Areas/Admin/Controllers/ProductController.cs @@ -38,13 +38,18 @@ namespace pwt_0x01_ng.Areas.Admin.Controllers [HttpPost] public async Task Create(Product product) { - product.ImageSrc = string.Empty; - MegaUpload mega_upload = new MegaUpload(hosting_env); - await mega_upload.DoMegaUpload(product); + if (ModelState.IsValid) { + product.ImageSrc = string.Empty; + MegaUpload mega_upload = new MegaUpload(hosting_env); + await mega_upload.DoMegaUpload(product); - dbctx.Product.Add(product); - await dbctx.SaveChangesAsync(); - return RedirectToAction(nameof(Select)); + dbctx.Product.Add(product); + await dbctx.SaveChangesAsync(); + return RedirectToAction(nameof(Select)); + } else { + ViewData["Message"] = "error creating Product"; + return View(product); + } } public IActionResult Edit(int id) diff --git a/Areas/Admin/Views/Carousel/Create.cshtml b/Areas/Admin/Views/Carousel/Create.cshtml index c3b04e5..500cd02 100644 --- a/Areas/Admin/Views/Carousel/Create.cshtml +++ b/Areas/Admin/Views/Carousel/Create.cshtml @@ -13,4 +13,5 @@ @section Scripts { @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} + } diff --git a/Areas/Admin/Views/Carousel/Edit.cshtml b/Areas/Admin/Views/Carousel/Edit.cshtml index 6165230..67999e3 100644 --- a/Areas/Admin/Views/Carousel/Edit.cshtml +++ b/Areas/Admin/Views/Carousel/Edit.cshtml @@ -13,4 +13,5 @@ @section Scripts { @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} + } diff --git a/Areas/Admin/Views/Carousel/PartialForm_EditCreate.cshtml b/Areas/Admin/Views/Carousel/PartialForm_EditCreate.cshtml index 6e0e81f..df709c3 100644 --- a/Areas/Admin/Views/Carousel/PartialForm_EditCreate.cshtml +++ b/Areas/Admin/Views/Carousel/PartialForm_EditCreate.cshtml @@ -12,22 +12,22 @@ }}
- +
- +
- +
- +
diff --git a/Areas/Admin/Views/Product/Create.cshtml b/Areas/Admin/Views/Product/Create.cshtml index 0bef27d..a29fca0 100644 --- a/Areas/Admin/Views/Product/Create.cshtml +++ b/Areas/Admin/Views/Product/Create.cshtml @@ -12,4 +12,5 @@ @section Scripts { @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} + } diff --git a/Areas/Admin/Views/Product/Edit.cshtml b/Areas/Admin/Views/Product/Edit.cshtml index a2df7c0..02636d2 100644 --- a/Areas/Admin/Views/Product/Edit.cshtml +++ b/Areas/Admin/Views/Product/Edit.cshtml @@ -12,4 +12,5 @@ @section Scripts { @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} + } diff --git a/Areas/Admin/Views/Product/edit-create_part.cshtml b/Areas/Admin/Views/Product/edit-create_part.cshtml index 3560e57..953612a 100644 --- a/Areas/Admin/Views/Product/edit-create_part.cshtml +++ b/Areas/Admin/Views/Product/edit-create_part.cshtml @@ -27,7 +27,7 @@
- +
diff --git a/Models/Carousel.cs b/Models/Carousel.cs index b7c971c..05a820d 100644 --- a/Models/Carousel.cs +++ b/Models/Carousel.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Http; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using pwt_0x01_ng.Models.Validation; namespace pwt_0x01_ng.Models { @@ -10,8 +11,8 @@ namespace pwt_0x01_ng.Models [Required] public string DataTarget { get; set; } [NotMapped] + [FileTypeAttr("image")] public IFormFile Image { get; set; } - [Required] [StringLength(255)] public string ImageSrc { get; set; } [Required] diff --git a/Models/Product.cs b/Models/Product.cs index 3ee2cd6..ed9aee3 100644 --- a/Models/Product.cs +++ b/Models/Product.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Http; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using pwt_0x01_ng.Models.Validation; namespace pwt_0x01_ng.Models { @@ -13,10 +14,9 @@ namespace pwt_0x01_ng.Models public int Price { get; set; } [Required] public string Description { get; set; } - [Required] + [FileTypeAttr("image")] [NotMapped] public IFormFile Image { get; set; } - [Required] [StringLength(255)] public string ImageSrc { get; set; } [Required] diff --git a/Models/Validation/FileTypeAttr.cs b/Models/Validation/FileTypeAttr.cs new file mode 100644 index 0000000..a376d4a --- /dev/null +++ b/Models/Validation/FileTypeAttr.cs @@ -0,0 +1,48 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; + +namespace pwt_0x01_ng.Models.Validation +{ + public class FileTypeAttr : ValidationAttribute, IClientModelValidator + { + private readonly string type; + public FileTypeAttr(string type){ + this.type = type.ToLower(); + } + + protected override ValidationResult IsValid(object value, ValidationContext validationContext) { + if (value == null) { + /* img is optional as of now */ + return ValidationResult.Success; + } else if (value is IFormFile iff) { + if(iff.ContentType.ToLower().Contains(type)) { + return ValidationResult.Success; + } else { + return new ValidationResult(GetErrorMessage(validationContext.MemberName), new List { validationContext.MemberName }); + } + } + throw new NotImplementedException($"Attribute {nameof(FileTypeAttr)} not implemented for object {value.GetType()}."); + } + + protected string GetErrorMessage(string member_name) => $"make sure the {member_name} you picked really is of type {type}/*. help"; + + public void AddValidation(ClientModelValidationContext ctx){ + MergeAttribute(ctx.Attributes, "data-val", "true"); + MergeAttribute(ctx.Attributes, "data-val-content", GetErrorMessage("file")); + MergeAttribute(ctx.Attributes, "data-val-content-type", type); + } + + private bool MergeAttribute(IDictionary attributes, string key, string value){ + if (attributes.ContainsKey(key)){ + return false; + } + + attributes.Add(key, value); + return true; + } + } +} \ No newline at end of file diff --git a/pwt-0x01-ng.csproj b/pwt-0x01-ng.csproj index 439d273..70b5bcd 100644 --- a/pwt-0x01-ng.csproj +++ b/pwt-0x01-ng.csproj @@ -28,6 +28,7 @@ + diff --git a/wwwroot/js/validation/file_type.js b/wwwroot/js/validation/file_type.js new file mode 100644 index 0000000..45461ee --- /dev/null +++ b/wwwroot/js/validation/file_type.js @@ -0,0 +1,25 @@ +$.validator.addMethod('content', function (value, element, params) { + var f_type = params[1] + uploaded_type = ""; + + if (!value) { + return true; + } + + if (element && element.files && element.files.length > 0) { + uploaded_type = element.files[0].type; + } + + if (f_type && uploaded_type != "" && uploaded_type.toLowerCase().includes(f_type)) { + return true; + } + + return false; +}); + +$.validator.unobtrusive.adapters.add('content', ['type'], function (options) { + var element = $(options.form).find('#file')[0]; + + options.rules['content'] = [element, options.params['type']]; + options.messages['content'] = options.message; +}); \ No newline at end of file