locked
Storing PDF files RRS feed

  • Question

  • User-853298616 posted

     In my application I need to upload a few files (PDFs) and store them in a table. I tried creating a column with the time binary: 

    [CV] [varbinary](max) NULL

      but it doesn't show up in the form for creating a row for that table (I was kind of excepting some control to Browse for a file to upload).

    Is this not supported in Dynamic Data?

    Monday, June 23, 2008 7:16 PM

Answers

  • User-797310475 posted

    Hi,

    file uploads are not supported out of the box but it is possible to build a field template for handling them. Scott Hunter wrote a blog post about handling image uploads, but it should be easily adaptable for PDFs.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, June 23, 2008 8:09 PM
  • User-330204900 posted

    Hi Asrfarinha, I have a ready made FileUpload Field Template in part 3 this series of articles.

    1. Part 1 - FileImage_Edit FieldTemplate.
    2. Part 2 - FileImage_Edit FieldTemplate.
    3. Part 3 - FileUpload FiledTemplate.

    Hope this helps [:D]

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, November 14, 2008 3:40 AM
  • User-330204900 posted

    Have a look at the DBImage sample from DD Futures it stores it's images in the DB here Source Code DynamicDataFutures0716.zip

    Hope this helps [:D]

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, November 14, 2008 4:26 PM
  • User-330204900 posted

    It's in the DD Futures project (not the website sample) in the HttpHandlers folder

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, November 18, 2008 12:48 PM

All replies

  • User1641955678 posted

    There are no field templates that do this out of the box, but you should be able to write a custom template to do this.  This is fairly similar to the DbImage example that's part of the Dynamic Data Extensions (soon to be renamed Futures) solution on CodePlex.  Specifically, look at DbImage_Edit.ascx and its code behind logic.

    David

    Monday, June 23, 2008 8:08 PM
  • User-797310475 posted

    Hi,

    file uploads are not supported out of the box but it is possible to build a field template for handling them. Scott Hunter wrote a blog post about handling image uploads, but it should be easily adaptable for PDFs.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, June 23, 2008 8:09 PM
  • User660823006 posted

    Dynamic Data does support these types of columns but only if you write a custom field template for displaying and editing them. This is because a column type like you listed is just a byte array, without further knowledge Dynamic Data does not know how to properly display or edit this type of data. You can take a look at my DbImage sample which you can download as part of our futures sample here: http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=14475. It shows how to have a DbImage and DbImage_Edit field templates for displaying and saving pictures to the database. This same concept could be modified to work for PDF files and if you had the right library you could even show thumnails of the first page in the PDF.

    Monday, June 23, 2008 8:09 PM
  • User-797310475 posted

    Hopefully all three response will provide you with the answers you seek :)

    Monday, June 23, 2008 8:21 PM
  • User-853298616 posted

    First of all thanks for all the answers. I put the problem on hold and now I'm revisiting it, and I'm having some difficulties changing the supplied sample to my needs. I mentioned PDF but now that I think of it, the file can also be an image, or a .doc file. What I need is to store some generic file in the database and then have a link in the application to retrieve it (no need to have a thumbnail or anything). Can someone provide a sample of something like this or point me to the documentation that deals with all the database stuff, like this part:

     

    StringBuilder sb = new StringBuilder();
                for (int i = 0; i < Column.Table.PrimaryKeyColumns.Count; i++) {
                    if (sb.Length > 0) {
                        sb.Append(',');
                    }
                    sb.Append(DataBinder.GetPropertyValue(Row, Column.Table.PrimaryKeyColumns[i].Name));
                }
                string cachekey = string.Format(
                    "{0}:{1}:{2}",
                    Column.Table.Name,
                    Column.Name,
                    sb.ToString()
                );
                ViewState["CacheKey"] = cachekey;
    
                //display picture if in edit mode, 
                if (Mode == DataBoundControlMode.Edit) {
                    //set image properties
                    PlaceHolderFile.Visible = true;
                    sb = new StringBuilder();
                    sb.AppendFormat(
                        "~/ImageHandler.ashx?table={0}&column={1}&width={2}&height={3}",
                        HttpUtility.UrlEncode(Column.Table.Name),
                        HttpUtility.UrlEncode(Column.Name),
                        width,
                        height
                    );
                    for (int i = 0; i < Column.Table.PrimaryKeyColumns.Count; i++) {
                        sb.AppendFormat("&pk{0}={1}", i, DataBinder.GetPropertyValue(Row, Column.Table.PrimaryKeyColumns[i].Name));
                    }
                    ImageEdit.NavigateUrl = sb.ToString();
                }
      
    Thursday, November 13, 2008 7:09 PM
  • User-330204900 posted

    Hi Asrfarinha, I have a ready made FileUpload Field Template in part 3 this series of articles.

    1. Part 1 - FileImage_Edit FieldTemplate.
    2. Part 2 - FileImage_Edit FieldTemplate.
    3. Part 3 - FileUpload FiledTemplate.

    Hope this helps [:D]

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, November 14, 2008 3:40 AM
  • User-853298616 posted
    It does help, but what I would really like would be a way to store the files inside the database, and not only storing the path.
    Friday, November 14, 2008 1:17 PM
  • User-330204900 posted

    Have a look at the DBImage sample from DD Futures it stores it's images in the DB here Source Code DynamicDataFutures0716.zip

    Hope this helps [:D]

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, November 14, 2008 4:26 PM
  • User-853298616 posted

     I've been looking at the DBImage sample from DD Futures and trying to transform it to work with PDF files and I think I can already store the files in the database (at least a lot of gibberish characters show up in the database).

    Now the problem is retrieving said files. From the example there's a "ImageHandler.ashx" which I suppose is the one responsible for that, but I can't find that file anywhere. Where can I find it?

    Tuesday, November 18, 2008 12:17 PM
  • User-330204900 posted

    It's in the DD Futures project (not the website sample) in the HttpHandlers folder

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, November 18, 2008 12:48 PM
  • User-853298616 posted

     Finally did it! Thank you for all the help!

    I've basically stripped most of the code from the DbImage example (everything related to cache and stuff like that, I won't be needing it) and made a new HttpHandler, which I'll post here for reference:

     

    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Drawing.Imaging;
    using System.Globalization;
    using System.IO;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Reflection;
    using System.Text;
    using System.Web;
    using System.Web.DynamicData;
    
    namespace Microsoft.Web.DynamicData {
    
        public class FileHandler : IHttpHandler {
    
            public void ProcessRequest(HttpContext context) {
    
                // get request parameters
                string tableName = context.Request.QueryString["table"];
                string column = context.Request.QueryString["column"];
    
                StringBuilder sb = new StringBuilder();
                List<string> primaryKeyValues = new List<string>();
                int i = 0;
                string primaryKeyValue = context.Request.QueryString["pk" + i.ToString()];
                while (primaryKeyValue != null) {
                    if (sb.Length > 0) {
                        sb.Append(',');
                    }
                    sb.Append(primaryKeyValue);
                    primaryKeyValues.Add(primaryKeyValue);
                    i++;
                    primaryKeyValue = context.Request["pk" + i.ToString()];
                }
    
                MetaTable metaTable = MetaModel.Default.GetTable(tableName);
                IQueryable query = metaTable.GetQuery();
    
                // build query
                // Items.Where(row => row.ID == 1).Single()
                var singleWhereCall = LinqExpressionHelper.BuildSingleItemQuery(query, metaTable, primaryKeyValues.ToArray());
                // Items.Where(row => row.ID == 1).Single().Picture
                var fileBytes = Expression.Property(singleWhereCall, column);
    
                object file = query.Provider.Execute(fileBytes);
                byte[] bytes;
                if (file is byte[])
                {
                    bytes = (byte[])file;
                }
                else if (file is System.Data.Linq.Binary)
                {
                    bytes = ((System.Data.Linq.Binary)file).ToArray();
                }
                else
                {
                    bytes = null;
                }
    
                if (bytes != null)
                {
                    if (bytes.Length > 78 && bytes[0] == 0x15 && bytes[1] == 0x1c && bytes[2] == 0x2f)
                    {
                        //hack to strip off OLE header for Northwind categories table
                        byte[] newbytes = new byte[bytes.Length - 78];
                        Array.Copy(bytes, 78, newbytes, 0, bytes.Length - 78);
                        bytes = newbytes;
                    }
                }
    
                string filename = tableName + primaryKeyValues[0].ToString() + column + ".pdf";
    
                context.Response.ContentType = "application/pdf";
                context.Response.AddHeader("content-disposition", "attachment; filename=" + filename);
                context.Response.BinaryWrite(bytes);
                context.Response.End();
            }
    
            public bool IsReusable {
                get { return true; }
            }
        }
    }
      
    Tuesday, November 18, 2008 7:17 PM
  • User1641955678 posted

    Nice!  You can safely get rid of the quirky OLE header stripping logic, which won't do anything for PDF files.

    David

    Tuesday, November 18, 2008 9:42 PM