3

I want to restrict the file size and file type on the profile picture. I want to allow only .jpg and .png pictures, and i also want to only allow a maximum file size of for example 1 megabyte. Under you see my code for uploading a file with no restrictions. I am using base64. I need to check file type and file size before the picture is uploaded but I really don't know how and where. If you need to see more of my code please let me know. Thank you very much.

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> ChangePic(IndexViewModel model)
    {
        if (ModelState.IsValid)
        {
            var user = await _userManager.FindByIdAsync(User.GetUserId());

            var breader = new BinaryReader(model.ProfilePic.OpenReadStream());

            var byteImage = breader.ReadBytes((int)breader.BaseStream.Length);

            user.ProfilePic = byteImage;

            var result = await _userManager.UpdateAsync(user);
            if (result.Succeeded)
            {
                // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=532713
                // Send an email with this link
                //var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
                //var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme);
                //await _emailSender.SendEmailAsync(model.Email, "Confirm your account",
                //    "Please confirm your account by clicking this link: <a href=\"" + callbackUrl + "\">link</a>");
                await _signInManager.SignInAsync(user, isPersistent: false);
                _logger.LogInformation(3, "Profile info updated");
                return RedirectToAction(nameof(ManageController.Index), "Manage");
            }
            AddErrors(result);

        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }
  • 1
    You can use validation attributes so that you get both client and server side validation - refer [this example of a FileTypeAttribute](http://stackoverflow.com/questions/33414158/checking-image-mime-size-etc-in-mvc/33426397#33426397) (and includes a link to a `FileSizeAttribute`) –  Apr 28 '16 at 08:59

2 Answers2

1

You could add the following validation. That way it wont affect your existing action code.

public class IndexViewModel : IValidatableObject
{
    public HttpPostedFileBase ProfilePic { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {

        if (ProfilePic.ContentType != "image/png" && ProfilePic.ContentType != "image/jpeg")
        {
            yield return new ValidationResult("Application only supports PNG or JPEG image types");
        }

        if (ProfilePic.ContentLength > 1000000)
        {
            yield return new ValidationResult("File size must not exceed 1MB");
        }

    }
}

Hope this helps!

heymega
  • 9,215
  • 8
  • 42
  • 61
0

For the FileSize u could check something like this:

int maxUploadSize = 1000000 
if((int)breader.BaseStream.Length < maxUploadSize){
//upload it
}

To check the ImageType have a look at: https://stackoverflow.com/a/55876/4992212

The Link actually tells, that the initial bytes of an image are set to a particular value, so you can check the initial bytes and compare them with the image types you want to have.

Community
  • 1
  • 1
Tobias Theel
  • 3,088
  • 2
  • 25
  • 45