I have not had any trouble uploading various image formats(.png,.jpg.gif) or text files(.txt,.doc). Is there a reason that pdfs are different?
FYI I am not actually inserting the blob into the database. I am intercepting the insert and update events and saving the file to the server. I have also tried using a GridTemplateColumn but I wasn't able to get the RadUpload control to work inside the template.
Here is some of the code from my insert method...
//Cast EditableItem |
GridEditableItem editedItem = e.Item as GridEditableItem; |
//Get the ColumnEditor for the FileColumn |
//Get the RadUpload from the ColumnEditor |
GridAttachmentColumnEditor editor = GridAttachmentColumnEditor)editedItem.EditManager.GetColumnEditor("FileColumn"); |
RadUpload upload = (RadUpload)editor.RadUploadControl; |
//If file invalid, Throw an error |
if (upload.UploadedFiles.Count == 0 && upload.InvalidFiles.Count > 0) |
{ |
throw new Exception("Invalid File Type."); |
} |
//If no file found, Throw an error |
else if (upload.UploadedFiles.Count == 0 && upload.InvalidFiles.Count == 0) |
{ |
throw new Exception("No file to Upload."); |
} |
Everything I have tried always throws the Invalid File Type exception if I try to upload a pdf.
If anyone can help me out it would be appreciated.
5 Answers, 1 is accepted
Your setup seems fine. The GridAttachmentColumn does not show any preferences over file types, unless you explicitly specify the AllowedMimeTypes and AllowedFileExtension of the RadUpload or GridAttachmentColumn. In the online demo for the attachment column, you can also see there is a PDF file successfully uploaded. You can even try uploading your PDF file in the demo.
Have you set any size limit for your uploaded files? If you have done so and your PDF file is larger than the limit, you will not be able to successfully upload the file.
Another reason you would not be able to upload large files is if your ASP.NET HTTP runtime does not allow large files. The default size limit is 4096 KB (4 megabytes) and you may have to adjust that using the httpRuntime node in web.config:
MSDN: Uploading files in ASP.NET 2.0
Greetings,
Veli
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
I was never able to get a pdf to work with my GridAttachmentColumn. I had already set the max file size to 100mb via the web.config file and also on the column itself.
I decided to try using a GridTemplateColumn with a RadUpload control in the EditItemTemplate instead. The odd thing, however, was that once I had made all the changes to my RadGrid the problem persisted. I was still unable to upload any .pdf files, and I later found out I wasn't able to upload .dwg files.
I was able to work around the problem by handling the FileValidation event of the RadUpload control, and write my own file extension validation method. I had to make sure to set SkipInternalValidation to true, as without this I was still unable to upload .pdf or .dwg files.
It worked out for the best anyway, as I had a lot of trouble trying to get a custom validator into the GridAttachmentColumn anyway, and I didn't really like the hackish way I had done it. Using the GridTemplateColumn I was able to drop a CustomValidator into the EditItemTemplate and the validation was much more elegant.
I did test the demo version and I was able to successfully upload my pdf without issue. I'm sure that this is a rare issue and probably has something to do with the way I used the controls. I never intended to save the files to a binary data field in the database anyway, and my grid is bound to an IList of Custom objects. I have manually handled all of the CRUD events, as well as the validation. The RadControls just provided me a good framework, stylish look, and some pretty awesome paging.
Here is my validation method in case anyone runs into a similar problem. Note: My RadGrid is inside of a UserControl. "AllowedFileExtensions" is an string property of the control that I fill with comma separated file extensions. This method could be easily modified to cast the sender to a RadUpload and validate against it's "AllowedFileExtensions" property.
/// <summary> |
/// This method is fired on the ValidatingFile event of the RadUpload. |
/// Checks file extensions versus the allowed file extensions. |
/// </summary> |
protected void ValidateFiles(object sender, Telerik.Web.UI.Upload.ValidateFileEventArgs e) |
{ |
//If AllowedFileExtensions is Specified |
if (AllowedFileExtensions != string.Empty) |
{ |
//Get Extensions |
string[] extensions = AllowedFileExtensions.ToLower().Split((",").ToCharArray()); |
//Get Current File Extension |
string extension = e.UploadedFile.GetExtension().ToLower(); |
//Compare |
bool valid = (extensions.Contains(extension)); |
//Return Validity |
e.IsValid = valid; |
} |
else |
{ |
//No Extensions Specified, so All Files Valid |
e.IsValid = true; |
} |
//Skip default validation... |
e.SkipInternalValidation = true; |
} |
You seem to have done what I need to do with the grid and uploading of a file from within an edit template.
I know it may seem a little cheeky to ask but if possible, can you post the code that you have done to acheive this as I am tearing my hair out trying to get it all to work.
Thank you in advance.
Regards
Paul
Sorry to take so long to reply, I've been down with a cold for a few days. Took a while to catchup on emails.
Here is the basic markup for the aspx page or ascx control:
<telerik:RadAjaxPanel ID="apUploadGrid" runat="server" ClientEvents-OnRequestStart="conditionalPostback"> |
<telerik:RadFormDecorator ID="FormDecorator1" runat="server" DecoratedControls="All" Skin="Default"> |
</telerik:RadFormDecorator> |
<telerik:RadProgressManager ID="pmUploadGrid" runat="server" /> |
<telerik:RadGrid |
runat="server" |
ID="rgUploadGrid" |
AllowPaging="True" |
AllowSorting="True" |
AutoGenerateColumns="False" |
AllowAutomaticDeletes="true" |
ShowStatusBar="True" |
GridLines="None" |
OnInsertCommand="UploadGridInsert" |
OnUpdateCommand="UploadGridUpdate" |
OnDeleteCommand="UploadGridDelete" |
OnNeedDataSource="BindUploadedFiles" |
PageSize="10" |
Skin="Default"> |
<PagerStyle |
Mode="NextPrevAndNumeric" |
AlwaysVisible="true" /> |
<AlternatingItemStyle BackColor="#DADADA" /> |
<ItemStyle BackColor="#E0E0E0" /> |
<MasterTableView |
TableLayout="Fixed" |
Width="100%" |
CommandItemDisplay="Top" |
EditMode="EditForms" |
DataKeyNames="PrimaryKey"> |
<CommandItemSettings AddNewRecordText="Upload a new file" RefreshText="Check for new files" /> |
<Columns> |
<telerik:GridTemplateColumn |
HeaderText="Name" |
UniqueName="NameColumn" |
SortExpression="FileName"> |
<ItemStyle VerticalAlign="Top" /> |
<ItemTemplate> |
<asp:Label runat="server" ID="lblName" Text='<%# Eval("FileName") %>' /> |
</ItemTemplate> |
<EditItemTemplate> |
<telerik:RadTextBox |
runat="server" |
Width="200px" |
MaxLength="50" |
ID="tbFileName" |
Text='<%# Bind("FileName") %>' /> |
<asp:RequiredFieldValidator |
ID="rfvName" |
runat="server" |
ControlToValidate="tbFileName" |
ErrorMessage="File name is required." |
Display="Dynamic" |
SetFocusOnError="true" /> |
</EditItemTemplate> |
</telerik:GridTemplateColumn> |
<telerik:GridTemplateColumn |
HeaderText="File" |
UniqueName="FileColumn" |
DataField="FileData" |
SortExpression="FileName"> |
<ItemStyle VerticalAlign="Top" /> |
<ItemTemplate> |
<a href='<%# Page.ResolveUrl(UploadDirectory + Eval("Author").ToString() + "/" + Eval("FileName").ToString()) %>' target="_blank"><%# Eval("FileName")%></a> |
</ItemTemplate> |
<EditItemTemplate> |
<telerik:radprogressarea |
runat="server" |
id="RadProgressArea1" |
Skin="Default" /> |
<telerik:radupload |
runat="server" |
id="RadUpload1" |
Skin="Default" |
AllowedFileExtensions=".pdf,.jpg" |
ControlObjectsVisibility="None" |
InitialFileInputsCount="1" |
InputSize="35" |
MaxFileInputsCount="1" |
MaxFileSize="102400" |
OnValidatingFile="ValidateFiles" /> |
<asp:CustomValidator runat="server" ID="cvFileExtension" |
OnServerValidate="ValidateFileTypes" |
ErrorMessage="Only .pdf or .jpg files are allowed." |
SetFocusOnError="true" |
Display="Dynamic" /> |
</EditItemTemplate> |
</telerik:GridTemplateColumn> |
<telerik:GridEditCommandColumn |
ButtonType="ImageButton" |
Reorderable="false" |
UniqueName="EditColumn"> |
<HeaderStyle Width="30" /> |
</telerik:GridEditCommandColumn> |
<telerik:GridButtonColumn |
UniqueName="DeleteColumn" |
Text="Delete" |
CommandName="Delete" |
ButtonType="ImageButton" |
ConfirmText='Are you sure you want to delete this file?' |
ConfirmDialogType="Classic" |
Reorderable="false"> |
<HeaderStyle Width="30" /> |
</telerik:GridButtonColumn> |
</Columns> |
<EditFormSettings> |
<FormStyle BackColor="#ffffff" ForeColor="#000000" /> |
<PopUpSettings Height="330" /> |
<EditColumn ButtonType="PushButton" InsertText="Upload" /> |
</EditFormSettings> |
</MasterTableView> |
</telerik:RadGrid> |
</telerik:RadAjaxPanel> |
<telerik:RadCodeBlock ID="RadCodeBlock1" runat="server"> |
<script type="text/javascript"> |
// <![CDATA[ |
//On insert and update buttons click temporarily disables ajax to perform upload actions |
function conditionalPostback(sender, args) { |
var theRegexp = new RegExp("\.UpdateButton$|\.PerformInsertButton$", "ig"); |
if (args.get_eventTarget().match(theRegexp)) { |
//var upload = $find(window['UploadId']); |
//AJAX is disabled only if file is selected for upload |
//if (upload.getFileInputs()[0].value != "") { |
args.set_enableAjax(false); |
//} |
} |
} |
// ]]> |
</script> |
</telerik:RadCodeBlock> |
Here are the Insert, Update, and Delete methods:
/// <summary> |
/// This method fires on the InsertCommand event of the RadGrid. |
/// Overrides standard insert function. |
/// </summary> |
protected void UploadGridInsert(object sender, GridCommandEventArgs e) |
{ |
if (e.CommandName == RadGrid.PerformInsertCommandName) |
{ |
//Create Blank UploadedFile Object |
UploadedFile uf = new UploadedFile(); |
try |
{ |
//Cast EditableItem |
GridEditableItem editedItem = e.Item as GridEditableItem; |
//Create NewValues Dictionary |
Hashtable newValues = new Hashtable(); |
//The GridTableView will fill the values from all editable columns in the hash |
e.Item.OwnerTableView.ExtractValuesFromItem(newValues, editedItem); |
//Get the ColumnEditor for the FileColumn |
//Get the RadUpload from the ColumnEditor |
GridTemplateColumnEditor itemEditor = (GridTemplateColumnEditor)editedItem.EditManager.GetColumnEditor("FileColumn"); |
RadUpload ru = (RadUpload)itemEditor.ContainerControl.FindControl("RadUpload1"); |
//If file invalid, Throw an error |
if (ru.UploadedFiles.Count == 0 && ru.InvalidFiles.Count > 0) |
{ |
throw new Exception("Invalid File Type."); |
} |
//If no file found, Throw an error |
else if (ru.UploadedFiles.Count == 0 && ru.InvalidFiles.Count == 0) |
{ |
throw new Exception("No file to Upload."); |
} |
//Map path to the upload directory |
string directoryPath = Server.MapPath(_uploadDirectory + "/"); |
//If the directory doesnt exist, create it |
if (!Directory.Exists(directoryPath)) |
{ |
Directory.CreateDirectory(directoryPath); |
} |
//Save the Object, and the File |
uf.SaveOrUpdate(_connectionStringName); |
ru.UploadedFiles[0].SaveAs(directoryPath + uf.FileName, true); |
//Rebind the Grid, and turn off Insert Mode |
rgUploadGrid.Rebind(); |
rgUploadGrid.MasterTableView.IsItemInserted = false; |
} |
//If there is an error |
catch (Exception ex) |
{ |
throw ex; |
} |
} |
} |
/// <summary> |
/// This method is fired on the UpdateCommand of the RadGrid. |
/// Loads the UploadedFile object, updates the properties, and saves the object. |
/// </summary> |
protected void UploadGridUpdate(object sender, GridCommandEventArgs e) |
{ |
if (e.CommandName == RadGrid.UpdateCommandName) |
{ |
try |
{ |
//Cast EditableItem |
GridEditableItem editedItem = e.Item as GridEditableItem; |
//Extract the PrimaryKey value from the Item |
int primaryKey = Convert.ToInt32(editedItem.OwnerTableView.DataKeyValues[editedItem.ItemIndex]["PrimaryKey"]); |
//Load the UploadedFile Object |
UploadedFile uf = new UploadedFile(primaryKey); |
//Create NewValues Dictionary |
Hashtable newValues = new Hashtable(); |
//The GridTableView will fill the values from all editable columns in the hash |
e.Item.OwnerTableView.ExtractValuesFromItem(newValues, editedItem); |
//Get the ColumnEditor for the FileColumn of the Item |
//Get the RadUpload from the editor |
GridTemplateColumnEditor itemEditor = (GridTemplateColumnEditor)editedItem.EditManager.GetColumnEditor("FileColumn"); |
RadUpload upload = (RadUpload)itemEditor.ContainerControl.FindControl("RadUpload1"); |
//If file is invalid, Throw an error |
if (upload.UploadedFiles.Count == 0 && upload.InvalidFiles.Count > 0) |
{ |
throw new Exception("Invalid File Type."); |
} |
else if (upload.UploadedFiles.Count == 1) |
{ |
//Should Delete the Old File Here |
uf.FileName = newValues["FileName"].ToString(); |
upload.UploadedFiles[0].SaveAs(Server.MapPath(_uploadDirectory + "/") + uf.FileName, true); |
//Save the Object |
uf.SaveOrUpdate(_connectionStringName); |
} |
//Rebind the RadGrid |
//Turn off Edit mode |
rgUploadGrid.Rebind(); |
e.Item.OwnerTableView.ClearEditItems(); |
} |
//If there is an error, throw it |
//Depending on where the error occured we may get some broken data here |
//Either missing files or files in the wrong directory |
catch (Exception ex) |
{ |
throw ex; |
} |
} |
} |
/// <summary> |
/// This method fires on the DeleteCommand event of the RadGrid. |
/// Loads the UploadeFile and deletes it. |
/// Deletes the actual file. |
/// </summary> |
protected void UploadGridDelete(object sender, GridCommandEventArgs e) |
{ |
if (e.CommandName == RadGrid.DeleteCommandName) |
{ |
//Collect the Primary key for the item |
int primaryKey = Convert.ToInt32(e.Item.OwnerTableView.DataKeyValues[e.Item.ItemIndex]["PrimaryKey"]); |
//Load the UploadedFile Object |
UploadedFile uf = new UploadedFile(primaryKey); |
//Delete the File |
File.Delete(Server.MapPath(_uploadDirectory + "/" + uf.FileName)); |
//Delete the Object |
uf.Delete(); |
} |
} |
NOTE: UploadedFile is a custom object class I made. You could use MS Entities or LinqToSQL or your own custom class. You should also be able to do direct queries to your db if that is what you like to do.
I tried to strip out anything that was unnecessary to prevent confusion, hopefully this will help and not make it more confusing. :)
Thanks for that. It is much appreciated as I have found some useful pointers in your code.
Best regards
Paul