Link to home
Start Free TrialLog in
Avatar of Brian
BrianFlag for United States of America

asked on

FileUpload Control restrict FileSize

Hello Experts,

I have the following code below that works fine. I need to add something to it though to prevent a user from uploading a .pdf file with 0 bytes. So far I have it setup where a user cannot upload a file unless it's .pdf and no bigger than 1MB.

Thanks in advance!!!



protected void btn_AnnualPhysical_Click(object sender, EventArgs e)
    {
        if (Page.IsValid && cb_AnnualPhysical.Checked == true) // make sure all fields have data and cb_AnnualPhysical is Checked before Inserting to DB.
        {
            if (fuVerificationForm.HasFile) // a file has been uploaded
            {
                //Make sure we are dealing a .pdf file only
                string extension = Path.GetExtension(fuVerificationForm.PostedFile.FileName).ToLower();
                string MIMEType = null;

                switch (extension)
                {
                    case ".pdf":
                        MIMEType = "application/pdf";
                        break;
                    default:
                        lblVerificationFormTypeError.Visible = true;
                        lblVerificationFormTypeError.Text = "PDF files only!";
                        return;
                }

                string filename = fuVerificationForm.PostedFile.FileName.Split(new char[] { '\\' }).Last();
                int fileSize = fuVerificationForm.PostedFile.ContentLength;

                // Allow only files less than 1,048,576 bytes (approximately 1 MB) to be uploaded.
                if ((fileSize < 1048576))
                {
                    SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["WellnessTracker"].ConnectionString);

                    SqlCommand cmd = new SqlCommand();
                    cmd.CommandText = "InsertAnnualPhysical";
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Connection = conn;

                    // Load PDF InputStream into Byte array
                    byte[] imageBytes = new byte[fuVerificationForm.PostedFile.InputStream.Length + 1];
                    fuVerificationForm.PostedFile.InputStream.Read(imageBytes, 0, imageBytes.Length);

                    cmd.Parameters.AddWithValue("@emp_id", SqlDbType.Int).Value = hf_emp_id.Value;
                    cmd.Parameters.AddWithValue("@ap_pdf_file", SqlDbType.Image).Value = imageBytes;
                    cmd.Parameters.AddWithValue("@ap_pdf_filename", SqlDbType.VarChar).Value = filename;
                    cmd.Parameters.AddWithValue("@ap_pdf_mime", SqlDbType.VarChar).Value = MIMEType;
                    cmd.Parameters.AddWithValue("@ap_pdf_size", SqlDbType.VarChar).Value = fileSize;
                    cmd.Parameters.AddWithValue("@ap_section_complete", SqlDbType.Int).Value = cb_AnnualPhysical.Checked;

                    if (string.IsNullOrEmpty(txtDateCompleted.Text))
                    {
                        cmd.Parameters.AddWithValue("@ap_date", SqlDbType.DateTime).Value = DBNull.Value;
                    }
                    else
                    {
                        cmd.Parameters.AddWithValue("@ap_date", SqlDbType.DateTime).Value = txtDateCompleted.Text;
                    }

                    try
                    {
                        conn.Open();
                        cmd.ExecuteNonQuery();
                    }

                    catch (Exception ex)
                    {
                        lblInsertError.Visible = true;
                        lblInsertError.Text = ("Error on insert: " + ex.Message.ToString());
                    }

                    finally
                    {
                        Response.Redirect("index.aspx");
                        conn.Close();
                    }
                }

                else
                {
                    lblFileSize.Visible = true;
                    lblFileSize.Text = "File size must be 1MB or smaller";
                }
            }
            else  // no file has been uploaded, we only need to update txtPhysicalDateCompleted
            {
                SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["WellnessTracker"].ConnectionString);

                SqlCommand cmd = new SqlCommand();
                cmd.CommandText = "InsertAnnualPhysical";
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Connection = conn;

                byte[] imageBytes = new byte[1];

                cmd.Parameters.AddWithValue("@emp_id", SqlDbType.Int).Value = hf_emp_id.Value;
                cmd.Parameters.AddWithValue("@ap_pdf_file", SqlDbType.Image).Value = imageBytes;
                cmd.Parameters.AddWithValue("@ap_pdf_filename", SqlDbType.VarChar).Value = "";
                cmd.Parameters.AddWithValue("@ap_pdf_mime", SqlDbType.VarChar).Value = "application/octet-stream";
                cmd.Parameters.AddWithValue("@ap_pdf_size", SqlDbType.VarChar).Value = 0;
                cmd.Parameters.AddWithValue("@ap_section_complete", SqlDbType.Int).Value = cb_AnnualPhysical.Checked;

                if (string.IsNullOrEmpty(txtDateCompleted.Text))
                {
                    cmd.Parameters.AddWithValue("@ap_date", SqlDbType.DateTime).Value = DBNull.Value;
                }

                else
                {
                    cmd.Parameters.AddWithValue("@ap_date", SqlDbType.DateTime).Value = txtDateCompleted.Text;
                }

                try
                {
                    conn.Open();
                    cmd.ExecuteNonQuery();
                }

                catch (Exception ex)
                {
                    lblInsertError.Visible = true;
                    lblInsertError.Text = ("Error on insert: " + ex.Message.ToString());
                }

                finally
                {
                    Response.Redirect("index.aspx");
                    conn.Close();
                }
            }
        }
    }
Avatar of Todd Gerbert
Todd Gerbert
Flag of United States of America image

In the interest of full disclosure, I didn't read through your entire code snippet. ;)

Replace if ((fileSize < 1048576)) with if (fileSize > 0 && fileSize < 1048576), or add a separate if block before this one to check if (fileSize > 0) if you want to act differently than you would if it was too big.
Avatar of Brian

ASKER

Hi tgerbert,

Thank you for replying. I tried your solution but it still adds the file even though it is 0 bytes :(
try this free control instead: http://neatupload.codeplex.com/
Avatar of Brian

ASKER

@emoreau,

I do not want to use any other controls other than what I have now. Are you able to assist based on what I provided?
the problem with the builtin control is that the complete file has to be uploaded (whatever the size) before the validation takes place.
Actually, it appears that the HasFile property of the FileUpload control might return false in the event of a zero-byte file (or maybe the browser I tested with just doesn't send a zero-byte file). At any rate, here's a simple example; let me know if you need help adapting any concepts to your code, or something doesn't make sense.

The HTML:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
	
</head>
<body>
    <form id="form1" runat="server">
    <div>
		<asp:FileUpload ID="fileUploader" runat="server" EnableViewState="true" />
		<br />
		<asp:Button ID="submitButton" runat="server" Text="Upload File" OnClick="submitButton_Click" />
		<hr />
		<asp:Label ID="resultsLabel" runat="server"></asp:Label>
    </div>
    </form>
</body>
</html>

Open in new window


The code-behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication1
{
	public partial class Default : System.Web.UI.Page
	{
		private const long ONE_MEGABYTE = 1048576;

		protected void submitButton_Click(object sender, EventArgs e)
		{
			if (fileUploader.HasFile)
			{
				string fileExtension = System.IO.Path.GetExtension(fileUploader.FileName).ToLower();

				if (fileUploader.FileContent.Length <= 0)
				{
					resultsLabel.Text = "File is too small (less than or equal to zero).";
					resultsLabel.ForeColor = System.Drawing.Color.Red;
				}
				else if (fileUploader.FileContent.Length > ONE_MEGABYTE)
				{
					resultsLabel.Text = "File is too big (greater than 1MB).";
					resultsLabel.ForeColor = System.Drawing.Color.Red;
				}
				else if (fileExtension != ".pdf")
				{
					resultsLabel.Text = "File is not a PDF.";
					resultsLabel.ForeColor = System.Drawing.Color.Red;
				}
				else
				{
					string localServerPath = System.IO.Path.Combine(
						Server.MapPath("~/Uploaded PDFs"), DateTime.Today.ToString("s"), fileUploader.FileName);

					resultsLabel.Text = "Upload successful.";
					resultsLabel.ForeColor = System.Drawing.Color.Green;
				}
			}
		}
	}
}

Open in new window

Avatar of Brian

ASKER

@tgerbert,

As you can see I'm declaring fileSize below before I test the actual fileSize. My question is how do I check to see if it meets two conditions and if it meets both conditions then submit file if not then fail.

int fileSize = fuVerificationForm.PostedFile.ContentLength;

if fileSize > 1 and if fileSize < 10485 = submit file to DB.

else

if fileSize < 1 or fileSize == 0 = fail submit from uploading file to DB.
If you re-post your code as an attachment, or in a [ CODE ] [ /CODE ] block, I'll take a closer look (it's kinda hard to read when you just paste it into the text box since the formatting gets messed up).

But, the syntax for such an expression in C# would be:
if (fileSize > 0 && fileSize < 10485)
{
    // Success - save the file
}
else
{
    // Error - tell the user
}

Open in new window

Avatar of Brian

ASKER

@tgerbert,

Sorry, I'm attaching as a .txt file. I When you look at my code and see the line below I have tried the following below and still no luck.

I tried adding the following below as you mentioned above but if I create a .txt file with nothing in it and then choose Save As "All Types" and then enter "test.pdf" for the filename the .txt file will be 0 bytes. This is something that I did to prevent a user from uploading a file with a fileSize of 0.

if ((fileSize > 1 && fileSize < 1048576))
ee.txt
I have made some minor adjustments to your code, they are all marked with // TODO: .... Let me know if something's not clear.

// TODO: Review Change
private const long PDF_MAX_SIZE = 1048576;
private const long PDF_MIN_SIZE = 1024;
// End Change

protected void btn_AnnualPhysical_Click(object sender, EventArgs e)
{
	if (Page.IsValid && cb_AnnualPhysical.Checked == true) // make sure all fields have data and cb_AnnualPhysical is Checked before Inserting to DB.
	{
		// TODO: fuVerificationForm.HasFile will be "false" if file is zero bytes, in which case execution
		//       will jump to the "else" statement on line 106 below - that is, a zero byte file is treated the
		//       same as no file uploaded. Also, a valid PDF document MUST start with "%PDF-1.5", and end
		//       with "%EOF", so minimum valid size will actually be somewhere a little over 12 bytes. I'd
		//       wager that 1k is probably a reasonable minimum size.
		if (fuVerificationForm.HasFile) // a file has been uploaded
		{
			string extension = Path.GetExtension(fuVerificationForm.PostedFile.FileName).ToLower();
			string MIMEType = null;

			// TODO: Review Change
			if (extension == ".pdf")
				MIMEType = "application/pdf";
			else
			{
				lblVerificationFormTypeError.Visible = true;
				lblVerificationFormTypeError.Text = "PDF files only!";
				return;
			}
			// End Change

			// TODO: Review Change
			string filename = Path.GetFileName(fuVerificationForm.PostedFile.FileName);
			// End Change

			int fileSize = fuVerificationForm.PostedFile.ContentLength;

			// Allow only files less than 1,048,576 bytes (approximately 1 MB) to be uploaded.

			// TODO: Review Change
			if (fileSize < PDF_MIN_SIZE || fileSize > PDF_MAX_SIZE)
			{
				lblFileSize.Visible = true;
				lblFileSize.Text = "File size must be greater than zero bytes, and smaller than 1MB.";
			}
			// End Change

			// TODO: Review Change
			else
			// End Change
			{
				SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["WellnessTracker"].ConnectionString);

				SqlCommand cmd = new SqlCommand();
				cmd.CommandText = "InsertAnnualPhysical";
				cmd.CommandType = CommandType.StoredProcedure;
				cmd.Connection = conn;

				// Load PDF InputStream into Byte array
				byte[] imageBytes = new byte[fuVerificationForm.PostedFile.InputStream.Length + 1];
				fuVerificationForm.PostedFile.InputStream.Read(imageBytes, 0, imageBytes.Length);

				cmd.Parameters.AddWithValue("@emp_id", SqlDbType.Int).Value = hf_emp_id.Value;
				cmd.Parameters.AddWithValue("@ap_pdf_file", SqlDbType.Image).Value = imageBytes;
				cmd.Parameters.AddWithValue("@ap_pdf_filename", SqlDbType.VarChar).Value = filename;
				cmd.Parameters.AddWithValue("@ap_pdf_mime", SqlDbType.VarChar).Value = MIMEType;
				cmd.Parameters.AddWithValue("@ap_pdf_size", SqlDbType.VarChar).Value = fileSize;
				cmd.Parameters.AddWithValue("@ap_section_complete", SqlDbType.Int).Value = cb_AnnualPhysical.Checked;

				if (string.IsNullOrEmpty(txtDateCompleted.Text))
				{
					cmd.Parameters.AddWithValue("@ap_date", SqlDbType.DateTime).Value = DBNull.Value;
				}
				else
				{
					cmd.Parameters.AddWithValue("@ap_date", SqlDbType.DateTime).Value = txtDateCompleted.Text;
				}

				try
				{
					conn.Open();
					cmd.ExecuteNonQuery();
				}

				catch (Exception ex)
				{
					lblInsertError.Visible = true;
					lblInsertError.Text = ("Error on insert: " + ex.Message.ToString());
				}

				finally
				{
					Response.Redirect("index.aspx");
					conn.Close();
				}
			}

			// TODO: Review Change
			/**** This block deleted. ****
			{
				lblFileSize.Visible = true;
				lblFileSize.Text = "File size must be 1MB or smaller";
			}
			******************************/
			// End Change
		}
		else
		{
			SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["WellnessTracker"].ConnectionString);

			SqlCommand cmd = new SqlCommand();
			cmd.CommandText = "InsertAnnualPhysical";
			cmd.CommandType = CommandType.StoredProcedure;
			cmd.Connection = conn;

			byte[] imageBytes = new byte[1];

			cmd.Parameters.AddWithValue("@emp_id", SqlDbType.Int).Value = hf_emp_id.Value;
			cmd.Parameters.AddWithValue("@ap_pdf_file", SqlDbType.Image).Value = imageBytes;
			cmd.Parameters.AddWithValue("@ap_pdf_filename", SqlDbType.VarChar).Value = "";
			cmd.Parameters.AddWithValue("@ap_pdf_mime", SqlDbType.VarChar).Value = "application/octet-stream";
			cmd.Parameters.AddWithValue("@ap_pdf_size", SqlDbType.VarChar).Value = 0;
			cmd.Parameters.AddWithValue("@ap_section_complete", SqlDbType.Int).Value = cb_AnnualPhysical.Checked;

			if (string.IsNullOrEmpty(txtDateCompleted.Text))
			{
				cmd.Parameters.AddWithValue("@ap_date", SqlDbType.DateTime).Value = DBNull.Value;
			}

			else
			{
				cmd.Parameters.AddWithValue("@ap_date", SqlDbType.DateTime).Value = txtDateCompleted.Text;
			}

			try
			{
				conn.Open();
				cmd.ExecuteNonQuery();
			}

			catch (Exception ex)
			{
				lblInsertError.Visible = true;
				lblInsertError.Text = ("Error on insert: " + ex.Message.ToString());
			}

			finally
			{
				Response.Redirect("index.aspx");
				conn.Close();
			}
		}
	}
}

Open in new window

Avatar of Brian

ASKER

@tgerbert

I tried your code above and found the following issues below.

1.) The code still does not prevent a .pdf of 0MB or 0Bytes from getting inserted into DB.
2.) If a user tries to insert a .pdf file bigger than 1MB then I get a blank page displayed.
Avatar of Brian

ASKER

@tgerbert,

I'm also a litte confused where you got private const long PDF_MIN_SIZE = 1024; from. 1MB is equivalent to 1048576 bytes and 1 MB is also 1024 Kilobytes. Should the 1024 be 0 or null?
Avatar of Brian

ASKER

@tgerbert,

Are you able to assist? If not then I plan on deleting this question and reposting for additional help.
Avatar of Brian

ASKER

@tgerbert,

I was able to figure this out on my own since i did not hear back from you. I plan on closing this post and grading accordingly but would appreciate your feedback on what I did below. For some reason I cannot add both the statements belwo together I have to include them separetly can you tell me how I can include them together?

You will notice below that I have to add a check for fileSize in order to submit the code and another fileSize to display error. I would like to have only one fileSize check with both fileSize < 1048576 and fileSize <= 0.


protected void btn_AnnualPhysical_Click(object sender, EventArgs e)
    {
        if (Page.IsValid && cb_AnnualPhysical.Checked == true) // make sure all fields have data and cb_AnnualPhysical is Checked before Inserting to DB.
        {
            if (fuVerificationForm.HasFile) // a file has been uploaded
            {
                //Make sure we are dealing a .pdf file only
                string extension = Path.GetExtension(fuVerificationForm.PostedFile.FileName).ToLower();
                string MIMEType = null;

                switch (extension)
                {
                    case ".pdf":
                        MIMEType = "application/pdf";
                        break;
                    default:
                        lblVerificationFormTypeError.Visible = true;
                        lblVerificationFormTypeError.Text = "PDF files only!";
                        return;
                }

                string filename = fuVerificationForm.PostedFile.FileName.Split(new char[] { '\\' }).Last();
                int fileSize = fuVerificationForm.PostedFile.ContentLength;

                if ((fileSize < 1048576))
                {

                    SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["WellnessTracker"].ConnectionString);

                    SqlCommand cmd = new SqlCommand();
                    cmd.CommandText = "InsertAnnualPhysical";
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Connection = conn;

                    // Load PDF InputStream into Byte array
                    byte[] imageBytes = new byte[fuVerificationForm.PostedFile.InputStream.Length + 1];
                    fuVerificationForm.PostedFile.InputStream.Read(imageBytes, 0, imageBytes.Length);

                    cmd.Parameters.AddWithValue("@emp_id", SqlDbType.Int).Value = hf_emp_id.Value;
                    cmd.Parameters.AddWithValue("@ap_pdf_file", SqlDbType.Image).Value = imageBytes;
                    cmd.Parameters.AddWithValue("@ap_pdf_filename", SqlDbType.VarChar).Value = filename;
                    cmd.Parameters.AddWithValue("@ap_pdf_mime", SqlDbType.VarChar).Value = MIMEType;
                    cmd.Parameters.AddWithValue("@ap_pdf_size", SqlDbType.VarChar).Value = fileSize;
                    cmd.Parameters.AddWithValue("@ap_section_complete", SqlDbType.Int).Value = cb_AnnualPhysical.Checked;

                    if (string.IsNullOrEmpty(txtDateCompleted.Text))
                    {
                        cmd.Parameters.AddWithValue("@ap_date", SqlDbType.DateTime).Value = DBNull.Value;
                    }
                    else
                    {
                        cmd.Parameters.AddWithValue("@ap_date", SqlDbType.DateTime).Value = txtDateCompleted.Text;
                    }

                    try
                    {
                        conn.Open();
                        cmd.ExecuteNonQuery();
                    }

                    catch (Exception ex)
                    {
                        lblInsertError.Visible = true;
                        lblInsertError.Text = ("Error on insert: " + ex.Message.ToString());
                    }

                    finally
                    {
                        Response.Redirect("index.aspx");
                        conn.Close();
                    }
                }

                // Allow only files less than 1,048,576 bytes (approximately 1 MB) to be uploaded.
                {
                    lblFileSize.Visible = true;
                    lblFileSize.Text = "File size must be 1MB or smaller";
                }
            }
            else  // no file has been uploaded, we only need to update txtPhysicalDateCompleted
            {
                string filename = fuVerificationForm.PostedFile.FileName.Split(new char[] { '\\' }).Last();
                int fileSize = fuVerificationForm.PostedFile.ContentLength;

                if ((fileSize <= 0))
                {
                    lblFileSize.Visible = true;
                    lblFileSize.Text = "File size must be 1MB or smaller";
                }
            }
        }
    }
Avatar of Brian

ASKER

I've requested that this question be deleted for the following reason:

Would like to delete question since I figured it out on my own but most importantly I did not get the answers that I was looking for nor did I get any other responses after I asked for additional help.
ASKER CERTIFIED SOLUTION
Avatar of Brian
Brian
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Brian

ASKER

I figured out the problem on my own.