Click here to Skip to main content
15,867,453 members
Articles / Web Development / ASP.NET

A Custom File Upload Using a Web Control and Integrated Validation

Rate me:
Please Sign up or sign in to vote.
3.69/5 (7 votes)
30 Oct 2006CPOL3 min read 105.4K   686   63   14
This is a Web Control which is a custom file upload. It will accept only a specified range of file formats, and also integrates with the target page's validation.

Introduction

I have wrote this article to demonstrate custom validation with web controls.

As I only wanted the Custom Validator to fire when a button on an .aspx page had been clicked, all I am going to show in this article is how to create a simple File Upload control, which:

  • Only accepts .gif, .jpg, .png, .bmp.
  • Allow the user to state whether the image is required or not.

Pages Involved

Here is the page (with code file) which we will implement the control on:

  • Default.aspx
  • Default.aspx.cs

Here are the Web Control page names:

  • CustomControl.ascx
  • CustomControl.ascx.cs

Tasks for the Web Control (CustomControl.ascx)

For the web control, we need to do the following:

  • Add a File Upload
  • Add a Custom Validator
  • Assign something to the Custom Validator's ServerValidate event

Here is the code:

ASP.NET
<%@ Control Language="C#" AutoEventWireup="true" 
  CodeFile="CustomControl.ascx.cs" Inherits="WebUserControl" %>
<asp:FileUpload ID="FilUpl" runat="server" />
<br />
<asp:CustomValidator ID="ErrorMsg" runat="server" 
  ErrorMessage="CustomValidator" 
  OnServerValidate="ErrorMsg_ServerValidate">
</asp:CustomValidator><br />

Tasks for the Web Control Code File (CustomControl.ascx.cs)

For the code file for the Web Control, we need to:

  • define all the private variables.
  • define all the gets/sets which we will use to set the tag parameters and retrieve others.
  • define the ServerValidate function which we assigned to the custom validator.
  • define a function to get the file extension of the file which is attempting to upload.

Here is the code:

C#
public partial class CustomControl : System.Web.UI.UserControl
{
    //Has the user browsed for a file?
    private bool pGotFile;
    //The file extension of the Posted File
    private string pFileExt;
    //The File itself
    private HttpPostedFile pFilePost;
    //Is the user required to upload an image?
    private bool pRequired;
    //The validation group that the Custom Validator belongs to on the page
    private string pVgroup;
    //Extensions you allow to be uploaded
    private string[] pFileTypeRange;
    //Boolean indicator to check if file extension is allowed
    private bool Ind = false;

    /*
     * Get and Sets for the above private variables.
     * */
    public bool GotFile
    {
        get { return pGotFile; }
    }
    public string FileExt
    {
        get { return pFileExt; }
    }
    public HttpPostedFile FilePost
    {
        get { return pFilePost; }
    }
    public bool Required
    {
        set { pRequired = value; }
    }
    public string Vgroup
    {
        set { pVgroup = value; }
    }
    public string FileTypeRange
    {
        set { pFileTypeRange = value.ToString().Split(','); }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        //here we assign the validation group to the Custom Validator, 
        //which I have inefficiently named ErrorMsg
        ErrorMsg.ValidationGroup = pVgroup;
    }

    protected void ErrorMsg_ServerValidate(object source, 
                   ServerValidateEventArgs args)
    {
        if (FilUpl.HasFile)
        {
            pGotFile = true;
            pFileExt = GetExtension(FilUpl.PostedFile.FileName);
            pFilePost = FilUpl.PostedFile;

            foreach (string str in pFileTypeRange)
            {
                if (str == pFileExt)
                {
                    Ind = true;
                }
            }

            if (!Ind)
            {
                args.IsValid = false;
                ErrorMsg.Text = "The file format you " + 
                                "specified is not supported";
                //Stop the function
                return;
            }
        }
        else
        {
            //So if we get here the user has not browsed for a file
            pGotFile = false;
            //If you have stated that the user has to browse for a file.
            //then we must stop now and inform the user of such.
            if (pRequired)
            {
                args.IsValid = false;
                ErrorMsg.Text = "You must upload something";
            }
        }
    }
    /// <summary>
    /// This returns the file extension. It does not contain the preceding full stop
    /// so it would return jpg and NOT .jpg . Please adjust your coding accordingly.
    /// </summary>
    /// <param name="FileName">string</param>
    /// <returns>string: the file extension e.g. jpg</returns>
    private string GetExtension(string FileName)
    {
        string[] split = FileName.Split('.');
        string Extension = split[split.Length - 1];
        return Extension;
    }
}

Tasks for the Test Page (Default.aspx)

  • Add the tag line at the very top of your page which registers the custom tag which we will use:
  • ASP.NET
    <%@ Register TagPrefix="CC1" TagName="IUpload" Src="CustomControl.ascx" %>
  • Add the tag itself and also a button underneath which we will use to trigger the file upload.
  • ASP.NET
    <CC1:IUpload ID="MyUpload1" runat="server" 
       Required="false" Vgroup="Val1" FileTypeRange="jpg,gif,png,bmp" />
     
    <asp:Button ID="Button1" runat="server" Text="Upload Image" 
      CausesValidation="true" ValidationGroup="Val1" OnClick="Button1_Click"/>

Tasks for the Test Page's Code File (Default.aspx.cs)

  • Add the event for the button.
  • Inside this event, check to see if the page is valid. Check to see if there is a file, and if so, upload it.

Here is the code:

C#
public partial class _Default : System.Web.UI.Page 
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
    protected void Button1_Click(object sender, EventArgs e)
    {
        //First We Check if the page is valid or if we need to flag up an error message
        if (Page.IsValid)
        {
            //Second we need to check if the user has browsed for a file
            if (MyUpload1.GotFile)
            {
                //We can safely upload the file here because it has passed all validation.
                //Remeber to add the fullstop before
                //the FileExt variable as it comes without.
                MyUpload1.FilePost.SaveAs(Server.MapPath("images/MyFile." + 
                                                         MyUpload1.FileExt));
            }
        }
    }
}

Please Note

I have developed this using ASP.NET version 2.0, and also using Visual Web Developer Express.

Updates

Update with Effect from 11 August 2006

I am going to insert something extra to this. Let's say that for the file type range, you specify jpg,png,gif,bmp, then you might also want to check that the width of the image meets a certain minimum requirement that you set in the tag. It will check the size without having to save it to disk, by using InputStream.

Here is how I achieve the check without saving the file to disk first:

C#
System.Drawing.Image CheckSize = 
       System.Drawing.Image.FromStream(FilUpl.PostedFile.InputStream);
if (CheckSize.PhysicalDimension.Width < minWidth)
{
    //Conditional actions here
}

So here is the code again, but this time with the inclusion of the image size check. If it does not meet the required minimum width, it will output this: "Your image does not meet the required minimum size requirements which are" + MinWidth +"px" etc...

C#
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class CustomControl : System.Web.UI.UserControl
{
    //Has the user browsed for a file?
    private bool pGotFile;
    //The file extension of the Posted File
    private string pFileExt;
    //The File itself
    private HttpPostedFile pFilePost;
    //Is the user required to upload an image?
    private bool pRequired;
    //The validation group that the Custom Validator belongs to on the page
    private string pVgroup;
    //Extensions you allow to be uploaded
    private string[] pFileTypeRange;
    //Boolean indicator to check if file extension is allowed
    private bool Ind = false;
    //The Image Minimum Width
    private int minWidth = 0;


    /*
     * Get and Sets for the above private variables.
     * */
    public bool GotFile
    {
        get { return pGotFile; }
    }
    public string FileExt
    {
        get { return pFileExt; }
    }
    public HttpPostedFile FilePost
    {
        get { return pFilePost; }
    }
    public bool Required
    {
        set { pRequired = value; }
    }
    public string Vgroup
    {
        set { pVgroup = value; }
    }
    public string FileTypeRange
    {
        set { pFileTypeRange = value.ToString().Split(','); }
    }
    public int MinWidth
    {
        set { minWidth = value; }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        //here we assign the validation group to the Custom Validator, 
        //which I have inefficiently named ErrorMsg
        ErrorMsg.ValidationGroup = pVgroup;
    }

    protected void ErrorMsg_ServerValidate(object source, 
                   ServerValidateEventArgs args)
    {
        if (FilUpl.HasFile)
        {
            pGotFile = true;
            pFileExt = GetExtension(FilUpl.PostedFile.FileName);
            pFilePost = FilUpl.PostedFile;

            foreach (string str in pFileTypeRange)
            {
                if (str == pFileExt)
                {
                    Ind = true;
                }
            }

            if (!Ind)
            {
                args.IsValid = false;
                ErrorMsg.Text = "The file format you specified is not supported";
                //Stop the function
                return;
            }

            if (minWidth > 0)
            {
                //If you get here then you have set
                //the MinWidth because you are expecting an image,
                //and due to validation once at this stage in the code,
                //we know that the user has uploaded some sort of image type
                System.Drawing.Image CheckSize = 
                  System.Drawing.Image.FromStream(FilUpl.PostedFile.InputStream);
                if (CheckSize.PhysicalDimension.Width < minWidth)
                {
                    args.IsValid = false;
                    ErrorMsg.Text = "Your image does not meet the minimum width " + 
                      "requirements which are " + minWidth.ToString() +"px";
                    //Stop the function
                    return;
                }
            }
        }
        else
        {
            //So if we get here the user has not browsed for a file
            pGotFile = false;
            //If you have stated that the user has to browse for a file.
            //then we must stop now and inform the user of such.
            if (pRequired)
            {
                args.IsValid = false;
                ErrorMsg.Text = "You must upload something";
            }
        }
    }
    /// <SUMMARY>
    /// This returns the file extension. It does not contain the preceding full stop
    /// so it would return jpg and NOT .jpg . Please adjust your coding accordingly.
    /// </SUMMARY>
    /// <PARAM name="FileName">string</PARAM>
    /// <RETURNS>string: the file extension e.g. jpg</RETURNS>
    private string GetExtension(string FileName)
    {
        string[] split = FileName.Split('.');
        string Extension = split[split.Length - 1];
        return Extension;
    }
}

Finally the Updated Tag

Inline with my updated code, here is how I would implement it in the Custom Tag.

Register the tag first, I am using a different tag prefix this time:

ASP.NET
<%@ Register TagPrefix="ARDesigns" TagName="IUpload" Src="CustomControl.ascx" %>

And then the tag itself:

ASP.NET
<ARDesigns:IUpload ID="MyUpload1" runat="server" 
  Vgroup="Val1" FileTypeRange="jpg,gif,png,bmp" MinWidth="400" />

Update with Effect from 3 September 2006

Basically, I needed to put this in as I tripped over myself yesterday. Simple, but slipped my mind. People can have files with upper case file extensions, so we need to put it into lowercase to make the comparison, i.e.:

C#
pFileExt = GetExtension(FilUpl.PostedFile.FileName).ToLower();

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questionhow to upload to FTP? Pin
Aslesh1-Dec-08 7:29
Aslesh1-Dec-08 7:29 
QuestionHow can i rename file? Pin
Phan Thanh Lam8-Oct-07 5:52
Phan Thanh Lam8-Oct-07 5:52 
AnswerRe: How can i rename file? Pin
REA_ANDREW8-Oct-07 6:08
REA_ANDREW8-Oct-07 6:08 
GeneralDefault.aspx Pin
mahesh kumar s9-Sep-07 18:50
mahesh kumar s9-Sep-07 18:50 
GeneralRe: Default.aspx Pin
REA_ANDREW9-Sep-07 22:18
REA_ANDREW9-Sep-07 22:18 
GeneralError compiling Pin
mahesh kumar s7-Sep-07 4:00
mahesh kumar s7-Sep-07 4:00 
QuestionUploading from client app Pin
alexey.nayda11-Aug-06 3:57
alexey.nayda11-Aug-06 3:57 
AnswerRe: Uploading from client app Pin
REA_ANDREW11-Aug-06 4:14
REA_ANDREW11-Aug-06 4:14 
Questionre Pin
vaibhav tiwari11-Aug-06 1:01
vaibhav tiwari11-Aug-06 1:01 
AnswerRe: re Pin
REA_ANDREW11-Aug-06 3:07
REA_ANDREW11-Aug-06 3:07 
Questionits really very good Pin
vaibhav tiwari8-Aug-06 18:14
vaibhav tiwari8-Aug-06 18:14 
QuestionRe: its really very good Pin
REA_ANDREW8-Aug-06 21:02
REA_ANDREW8-Aug-06 21:02 
AnswerRe: its really very good Pin
alexey.nayda11-Aug-06 3:54
alexey.nayda11-Aug-06 3:54 
GeneralRe: its really very good Pin
db_cooper195013-Aug-06 6:00
db_cooper195013-Aug-06 6:00 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.