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:
<%@ 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:
public partial class CustomControl : System.Web.UI.UserControl
{
private bool pGotFile;
private string pFileExt;
private HttpPostedFile pFilePost;
private bool pRequired;
private string pVgroup;
private string[] pFileTypeRange;
private bool Ind = false;
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)
{
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";
return;
}
}
else
{
pGotFile = false;
if (pRequired)
{
args.IsValid = false;
ErrorMsg.Text = "You must upload something";
}
}
}
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:
<%@ 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.
<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:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
if (Page.IsValid)
{
if (MyUpload1.GotFile)
{
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:
System.Drawing.Image CheckSize =
System.Drawing.Image.FromStream(FilUpl.PostedFile.InputStream);
if (CheckSize.PhysicalDimension.Width < minWidth)
{
}
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...
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
{
private bool pGotFile;
private string pFileExt;
private HttpPostedFile pFilePost;
private bool pRequired;
private string pVgroup;
private string[] pFileTypeRange;
private bool Ind = false;
private int minWidth = 0;
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)
{
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";
return;
}
if (minWidth > 0)
{
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";
return;
}
}
}
else
{
pGotFile = false;
if (pRequired)
{
args.IsValid = false;
ErrorMsg.Text = "You must upload something";
}
}
}
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:
<%@ Register TagPrefix="ARDesigns" TagName="IUpload" Src="CustomControl.ascx" %>
And then the tag itself:
<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.:
pFileExt = GetExtension(FilUpl.PostedFile.FileName).ToLower();