cp-stack
cp-stack

Reputation: 866

ASP.NET MVC 5 Custom Attribute Error

I am implementing an image upload option in my MVC application but I keep getting the following error: The type or namespace name 'FileSizeAttribute' could not be found.

As you can see from my code below I am implementing cusom attributes to determine the allowed file size and type.

public class UploadImageModel
    {
        [FileSize(10240)]
        [FileTypes("jpg,jpeg,png")]
        public HttpPostedFileBase File { get; set; }
    }

I define these attributes in my ProfileController.cs as you can see here.

public class FileSizeAttribute : ValidationAttribute
        {
            private readonly int _maxSize;

            public FileSizeAttribute(int maxSize)
            {
                _maxSize = maxSize;
            }

            public override bool IsValid(object value)
            {
                if (value == null) return true;

                return _maxSize > (value as HttpPostedFile).ContentLength;
            }
            public override string FormatErrorMessage(string name)
            {
                return string.Format("The image size should not exceed {0}", _maxSize);
            }
        }

        public class FileTypesAttribute : ValidateInputAttribute
        {
            private readonly List<string> _types;

            public FileTypesAttribute(string types)
            {
                _types = types.Split(',').ToList();
            }

            public override bool IsValid(object value)
            {
                if (value == null) return true;

                var fileExt = System.IO.Path.GetExtension((value as HttpPostedFile).FileName).Substring(1);
                return _types.Contains(fileExt, StringComparer.OrdinalIgnoreCase);
            }

            public override string FormatErrorMessage(string name)
            {
                return string.Format("Invalid file type. Only the following types {0} are supported.",
                    String.Join(", ", _types));
            }
        }
        [HttpPost]
        public ActionResult PhotoUpload(UploadImageModel imageModel)
        {
            string path = @"D:\Temp\";

            if (ModelState.IsValid)
            {
                if (imageModel != null && imageModel.File != null)
                    image.SaveAs(path + imageModel.File.FileName);

                return RedirectToAction("Profile");
            }

            return View();
        }

I should mention that I am adapting code from this article as I am new to MVC and just learning the ropes. That said, do I need to include a using clause in my header the references my Controller or is it a syntax issue that I am missing? Thanks in advance for the help.

Upvotes: 0

Views: 1285

Answers (1)

Tieson T.
Tieson T.

Reputation: 21191

Let's assume you, at a minimum, moved those attributes out into a combined file, call it ExtensionAttributes.cs. Inside that file, you would have something like

namespace artisan.Attributes
{
    public class FileSizeAttribute : ValidationAttribute
    {
        private readonly int _maxSize;

        public FileSizeAttribute(int maxSize)
        {
            _maxSize = maxSize;
        }

        public override bool IsValid(object value)
        {
            if (value == null) return true;

            return _maxSize > (value as HttpPostedFile).ContentLength;
        }
        public override string FormatErrorMessage(string name)
        {
            return string.Format("The image size should not exceed {0}", _maxSize);
        }
    }

    public class FileTypesAttribute : ValidateInputAttribute
    {
        private readonly List<string> _types;

        public FileTypesAttribute(string types)
        {
            _types = types.Split(',').ToList();
        }

        public override bool IsValid(object value)
        {
            if (value == null) return true;

            var fileExt = System.IO.Path.GetExtension((value as HttpPostedFile).FileName).Substring(1);
            return _types.Contains(fileExt, StringComparer.OrdinalIgnoreCase);
        }

        public override string FormatErrorMessage(string name)
        {
            return string.Format("Invalid file type. Only the following types {0} are supported.",
                String.Join(", ", _types));
        }
    }
}

Then, to use the attribute on your model, you would do something like

using artisan.Attributes;

public class UploadImageModel
{
    [FileSize(10240)]
    [FileTypes("jpg,jpeg,png")]
    public HttpPostedFileBase File { get; set; }
}

Otherwise, as-is, you need to add a artisan.Controllers to your model class, but that (given the default project template) might cause some circular references.

Upvotes: 2

Related Questions