How can I get Byte[] file?

23 posts, 1 answers
  1. Jan Michael
    Jan Michael avatar
    13 posts
    Member since:
    Oct 2008

    Posted 06 Nov 2008 Link to this post

    Is there a way were I can get the byte[] type of the file I am uploading?
    The reason for this is I want to store the files(e.g image) to the database using byte[] type.
  2. Jan Michael
    Jan Michael avatar
    13 posts
    Member since:
    Oct 2008

    Posted 06 Nov 2008 Link to this post

    Hi, can someone answer my question? Tnx.
  3. DevCraft banner
  4. Valentin.Stoychev
    Admin
    Valentin.Stoychev avatar
    2198 posts

    Posted 10 Nov 2008 Link to this post

    Hello Jan Michael,

    The files are sent as a Base64String. You can use the code below to get the data as a byte[].

     

    byte[] buffer;

     

    buffer =

    Convert.FromBase64String(this.Request.Form[RadUploadConstants.ParamNameData]);

     


    Check this article to see how a custom upload handler can be created:
    http://www.telerik.com/help/silverlight/creating_custom_server-side_handler.html

    Please let us know if you need more help in implementing your scenario.

    Kind regards,
    Valentin.Stoychev
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  5. Jan Michael
    Jan Michael avatar
    13 posts
    Member since:
    Oct 2008

    Posted 10 Nov 2008 Link to this post

    Hi, thanks for the answer.
    I checked the custom server-side handler but it still confuses me. Can you show me the way how can I override and save the file bytes[] to db? Or you can send me sample codes on how can I use it implement my scenario? Thanks! Your response is very important to me. Many thanks!
  6. Valentin.Stoychev
    Admin
    Valentin.Stoychev avatar
    2198 posts

    Posted 17 Nov 2008 Link to this post

    Hi Jan Michael,

    Sorry for the late replay on this ticket!

    Here is the code below to see how you can get the saved file and later process it for your needs.

     public class RadUploadHandler : Telerik.Windows.RadUploadHandler  
        {  
     
            public override void ProcessStream()  
            {  
                base.ProcessStream();  
     
                /*
                 * The file is coming in chunks, so you 
                 * have to make sure that the whole file is uploaded before to proceed.
                 * */ 
                if (this.IsFinalFileRequest())  
                {  
                    // Insert here your custom logic for processing the file stream.   
                    // You can read the saved file on the disc and to process it in the way you need.  
                    // You can save the file in DB, compress it, etc.  
     
                    // get a reference to the uploaded file  
                    FileStream fs = File.OpenRead(this.GetFilePath());  
     
                     // modify the stream and save in DB ...  
                }  
            }  
        } 

    Please let us know if you have any problems building your application.

    All the best,
    Valentin.Stoychev
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  7. Richard
    Richard avatar
    26 posts
    Member since:
    Oct 2008

    Posted 17 Nov 2008 Link to this post

    Valentin,

    Is it possibel to just have the byte array and not save the file to disk?  Is there a switch to turn off the save to disk?
  8. Valentin.Stoychev
    Admin
    Valentin.Stoychev avatar
    2198 posts

    Posted 18 Nov 2008 Link to this post

    Hi Richard,

    Yes - it is possible. If you skip the call to base.ProcessStream(), then you will have full control over the upload process. Please note that this will not stop the upload by chunks. If you want to stop the upload by chunks you can set a bigger BufferSize, and to set a MaxFileSize smaller than the BufferSize.

    Basically to get the uploaded stream you need this line of code:

    byte
    [] buffer = Convert.FromBase64String(this.Request.Form[RadUploadConstants.ParamNameData]);

    I'm pasting the base implementation of the ProcessStream method that you can use as a reference.



     public virtual void ProcessStream()  
            {  
                string fileName = this.Request.Form[RadUploadConstants.ParamNameFileName];  
     
                string filePath = this.GetFilePath(fileName);  
     
                this.AddReturnParam(RadUploadConstants.ParamNameFinalFileRequest, this.IsFinalFileRequest());  
     
                if (filePath == null)  
                {  
                    this.AddReturnParam(RadUploadConstants.ParamNameSuccess, false);  
                    this.AddReturnParam(RadUploadConstants.ParamNameMessage, String.Format("Cannot find the target folder [{0}]", this.GetTargetFolder()));  
                    return;  
                }  
                else if (this.IsNewFileRequest() && File.Exists(filePath) && !this.OverwriteExistingFiles)  
                {  
                    this.AddReturnParam(RadUploadConstants.ParamNameSuccess, false);  
                    this.AddReturnParam(RadUploadConstants.ParamNameMessage, String.Format("File already exists name:[{0}], path:[{1}]", fileName, filePath));  
                    return;  
                }  
     
                byte[] buffer;  
                try  
                {  
                    buffer = Convert.FromBase64String(this.Request.Form[RadUploadConstants.ParamNameData]);  
                }  
                catch (System.FormatException)  
                {  
                    this.AddReturnParam(RadUploadConstants.ParamNameSuccess, false);  
                    this.AddReturnParam(RadUploadConstants.ParamNameMessage, "Bad stream format");  
                    return;  
                }  
     
                long position = Convert.ToInt64(this.Request.Form[RadUploadConstants.ParamNamePosition]);  
                long contentLength = 0;  
                FileStream stream = null;  
                try  
                {                  
                    // remove any old file with the same name  
                    if (this.IsNewFileRequest())  
                    {  
                        if (File.Exists(filePath))  
                        {  
                            this.RemoveFile(filePath);                        
                        }  
                    }  
     
                    stream = File.OpenWrite(filePath);  
                    stream.Position = position;  
                    stream.Write(buffer, 0, buffer.Length);  
                    contentLength = stream.Length;  
                }  
                catch (Exception e)   
                {  
                    this.AddReturnParam(RadUploadConstants.ParamNameSuccess, false);  
                    this.AddReturnParam(RadUploadConstants.ParamNameMessage, String.Format("Cannot open the file for writing [{0}]", e.Message));  
                }  
                finally   
                {   
                    if (stream != null)   
                    {   
                        stream.Dispose();   
                    }  
                }  
     
                if (contentLength == 0)  
                {  
                    return;  
                }  
     
                buffer = null;  
     
                this.AddReturnParam(RadUploadConstants.ParamNameSuccess, true);  
     
                if (this.IsFinalFileRequest())  
                {  
                    this.AddReturnParam(RadUploadConstants.ParamNameFileIdent, filePath);  
                    this.AddReturnParam(RadUploadConstants.ParamNameFileName, fileName);  
                    this.AddReturnParam(RadUploadConstants.ParamNameFilePath, filePath);  
     
                    // serialize the custom params  
                    string associatedDataString = String.Empty;  
     
                    Dictionary<string, object> associatedData = this.GetAssociatedData();  
                    if (associatedData.Count > 0)  
                    {  
                        foreach (string key in associatedData.Keys)  
                        {  
                            object value = associatedData[key];  
                            if (value == null)  
                            {  
                                value = "null";  
                            }  
     
                            value = "\"" + value.ToString().Replace("\\", "\\\\") + "\"";  
                            associatedDataString += "{" + String.Format(@"""Key"":""{0}"",""Value"":{1}", key, value) + "},";  
                        }  
     
                        associatedDataStringassociatedDataString = associatedDataString.TrimEnd(',');  
                    }  
     
                    this.AddReturnParam(RadUploadConstants.ParamNameAssociatedData, associatedDataString);  
                }  
     
                this.AddReturnParam(RadUploadConstants.ParamNameFinalFileRequest, this.IsFinalFileRequest());  
            } 


    Greetings,
    Valentin.Stoychev
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  9. Richard
    Richard avatar
    26 posts
    Member since:
    Oct 2008

    Posted 30 Dec 2008 Link to this post

    Valentin,

    I am doing what Ricahrd below is asking about.  (Funny my name is Richard too) and can't quite seem to get it going.

     

    What I want to do is not save to disk but instead place the data into a byte array that I can save to SQL. 

    I have commented out the call to base.ProcessStream();

     


    and then simply put in the line of code:

    byte

    [] buffer = Convert.FromBase64String(Request.Form[RadUploadConstants.ParamNameData]);

     


    When I step through in debug, I can see the bytes stored in the buffer so this is good. 

    I didn't use any of the code you have in the ProcessStream method except for this one line. 

    So all I have is this code:

     

    public override void ProcessStream()

     

    {

     

        //base.ProcessStream();

     

     

        byte[] buffer = Convert.FromBase64String(Request.Form[RadUploadConstants.ParamNameData]);

     

        (need to put some code here to finish the process)
    }


    Now I need to have the code to bring back the upload control because when I run this I get a blank screen and a javascript error.

    What code do I need to finish this off?  Any help would be appreciated.
  10. Richard
    Richard avatar
    26 posts
    Member since:
    Oct 2008

    Posted 30 Dec 2008 Link to this post

    Valentin,

    One more piece of info on the problem I just posted.  When I look at the error in Firebug, it reads:

    Error: Sys.InvalidOperationException: ManagedRuntimeError error #4004 in control 'Xaml1': System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
       at System.ThrowHelper.ThrowKeyNotFoundException()
       at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
       at Telerik.Windows.Controls.FileUploader.OnResponse(IAsyncResult asyncResult)
       at System.Net.BrowserHttpWebRequest.<>c__DisplayClassd.<InvokeGetResponseCallback>b__b(Object state2)
       at System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading._ThreadPoolWaitCallback.PerformWaitCallbackInternal(_ThreadPoolWaitCallback tpWaitCallBack)
       at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)
    Source File: http://localhost:60248/ScriptResource.axd?d=3-m7EoK3mAKs-lt0553guOI8E9mTTpUBR4u8MnkgMPHgzWJg92YRrGIWUNzrl9sqrjEhH6rs93vuK2llQDs73A2&t=1f1ca10
    Line: 461

    It looks like I am missing a key that needs to be returned back to the upload control??  I also think that the code you posted above for the base.ProcessStream might be outdated.  Have any changes been made to it?  The reason I ask is if I take that code and place it in the raduploadhandler in place of the base.ProcessStream, it will not work.

  11. Valentin.Stoychev
    Admin
    Valentin.Stoychev avatar
    2198 posts

    Posted 05 Jan 2009 Link to this post

    Hello Richard,

    I see that the problem is that some parameters are not returned from the handler.

    There are a couple of mandatory parameters that should be returned.

     

     

     

    You should add the following code:

    this.AddReturnParam(RadUploadConstants.ParamNameAssociatedData, "");  
     
     
    this.AddReturnParam(RadUploadConstants.ParamNameFinalFileRequest, this.IsFinalFileRequest());  
     
    this.AddReturnParam(RadUploadConstants.ParamNameSuccess, true); // or false if something fails  
     
     
     
     
    this.AddReturnParam(RadUploadConstants.ParamNameMessage, "");// or add an error message if it is needed  
     
     
    string fileName = this.Request.Form[RadUploadConstants.ParamNameFileName];  
     
    string filePath = this.GetFilePath(fileName);  
     
    this.AddReturnParam(RadUploadConstants.ParamNameFileIdent, filePath);  
     
    this.AddReturnParam(RadUploadConstants.ParamNameFileName, fileName);  
     
    this.AddReturnParam(RadUploadConstants.ParamNameFilePath, filePath);  
     

    Please let us know how it goes.

    Regards,
    Valentin.Stoychev
    the Telerik team


    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  12. Richard
    Richard avatar
    26 posts
    Member since:
    Oct 2008

    Posted 06 Jan 2009 Link to this post

    Valentin,

    I added the parameters to the code and still no luck.  The upload control going blank after the upload so there is still something missing.  I am going to post my entire raduploadhandler code.  As you can see, there is not much there right now.

    FolderID and OrganizationID are two variables I am passing in the url to the page with the upload control.
    AssetVersionID is the ID of the data that will be inserted into the sql table.  On a side note, when the file is over 100k, I need to write the data into the sql table in chunks.  I already have a stored proc to do that but now I need to pass the AssetVersionID back to the upload control as the raduploadhandler loses focus on each pass so I have to continually pass the AssetVersionID back to the contol so it can be passed back to the raduploadhandler on each pass.

    The dict.Add("MyServerFolderID"..... code is just a test so disregard that line of code for now.  I am not worried about error handling at this time.  I just want to get the code working and then I'll add error handling.

    Do you see what I am missing?

     

    using System;  
    using System.Collections.Generic;  
    using Telerik.Windows.Controls;  
     
    public class RadUploadHandlerNoFile : Telerik.Windows.RadUploadHandler  
    {  
        string FolderID;  
        string OrganizationID;  
        private long AssetVersionID;  
     
        public override Dictionary<string, object> GetAssociatedData()  
        {  
            var dict = new Dictionary<string, object>();  
     
            //collects the FolderID from the textblock (txtFolderID) on the fileupload.xaml file  
            FolderID = Request.Form["FolderID"];  
            OrganizationID = Request.Form["OrganizationID"];  
     
            ////test to return folderid to xaml page  
            if (FolderID != null)  
            {  
                //returns this value to the textblock (txtServerFolderID) on the fileupload.xaml file  
                //this was for testing only and can be used to get values back to the xaml page  
                dict.Add("MyServerFolderID", String.Format("Server_Value[{0}]. The file name is [{1}]", FolderID, Request.Form[RadUploadConstants.ParamNameFileName]));  
            }  
     
            return dict;  
        }  
        public override void ProcessStream()  
        {  
            byte[] assetData = Convert.FromBase64String(Request.Form["RadUAG_data"]);  
     
            this.AddReturnParam(RadUploadConstants.ParamNameAssociatedData, "");  
     
            this.AddReturnParam(RadUploadConstants.ParamNameFinalFileRequest, this.IsFinalFileRequest());  
     
            this.AddReturnParam(RadUploadConstants.ParamNameSuccess, true); // or false if something fails    
     
            this.AddReturnParam(RadUploadConstants.ParamNameMessage, "");// or add an error message if it is needed    
     
            string fileName = this.Request.Form[RadUploadConstants.ParamNameFileName];  
     
            string filePath = this.GetFilePath(fileName);  
     
            this.AddReturnParam(RadUploadConstants.ParamNameFileIdent, filePath);  
     
            this.AddReturnParam(RadUploadConstants.ParamNameFileName, fileName);  
     
            this.AddReturnParam(RadUploadConstants.ParamNameFilePath, filePath);    
            }  
        }  

  13. Answer
    Valentin.Stoychev
    Admin
    Valentin.Stoychev avatar
    2198 posts

    Posted 06 Jan 2009 Link to this post

    Hi Richard,

    I created a test app with your upload handler and everything is ok with it. What are you doing in the Silverlight application after the upload is done? I assume that you are handling the FileUploaded event? Can you remove the entire logic and run the RadUpload with just the handler changed?

    Is it possible for you to attach the application, so we can debug it?

    Best wishes,
    Valentin.Stoychev
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  14. Alex
    Alex avatar
    20 posts
    Member since:
    Jun 2008

    Posted 12 Aug 2009 Link to this post

    hi there:
    I have watched this page through,i have a question.
    i get the file buffer by override this  function GetAssociatedData:

    buffer = Convert.FromBase64String(this.Request.Form[Telerik.Windows.Controls.RadUploadConstants.ParamNameData]);

    but i want to return this buffer to xaml page ,so i can get this buffer in FileUploaded event.

    i used the GetAssociatedData return Dictionary to return,this is not work,maybe i am not use it as a right way.

    do you get any solution to fix this?
    thanks.

     

  15. Ivan
    Admin
    Ivan avatar
    519 posts

    Posted 12 Aug 2009 Link to this post

    Hi Alex,

    Thank you for your interest in the RadUpload for Silverlight.

    Looking into your code I can say you are on the right way. But I have to mention some things:
    1. Note the upload process divided the uploaded files into chunks and upload these chunks in a sequence. By default the chunk size is 100'000 bytes (you can change it via BufferSize property). Each file which size is bigger buffer size will be uploaded within a few chunks.
    2. GetAssociatedData is calling only for the Final-File-Request, i.e. when the last chuck was uploaded. As an effect of this you will get / return only the data from the last chunk.
    3. Please do not convert uploaded data back from base-64 in the upload handler - this can lead to a trouble when responding to the client. Of course you should convert it in the client code to get the original data.

    Below is all the code you need:
    • Server side:
       
      public override Dictionary<stringobject> GetAssociatedData() 
          Dictionary<stringobject> dict = base.GetAssociatedData(); 
       
          string buffer = this.Request.Form[ Telerik.Windows.Controls.RadUploadConstants.ParamNameData]; 
          dict.Add("LastChunkData", buffer); 
       
          return dict; 
       
    • Client side:
       
      private void radUpload_FileUploaded(object sender, Telerik.Windows.Controls.FileUploadedEventArgs e) 
          string returnedData = e.HandlerData.CustomData["LastChunkData"]; 
          string realData = System.Convert.FromBase64String(returnedData); 
       

    We hope this information will help you.

    Sincerely yours,
    Ivan
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
  16. Alex
    Alex avatar
    20 posts
    Member since:
    Jun 2008

    Posted 12 Aug 2009 Link to this post

    Thanks very much,it is fixed.
  17. Alex
    Alex avatar
    20 posts
    Member since:
    Jun 2008

    Posted 21 Sep 2009 Link to this post

    hi,i get an other question.
    if my file is smaller than 100,000,it do works,but if the file is bigger than 100,000,there will be more than one shunk,right?
    Telerik.Windows.Controls.RadUploadConstants.ParamNameData can only get the last shunk,can i get all the shunks by this way?

    i mean can i get all the shunks' string,so i can bring it back to client.
  18. Ivan
    Admin
    Ivan avatar
    519 posts

    Posted 22 Sep 2009 Link to this post

    Hello Alex,

    If you need to return all the file's content you should save it somewhere (in a file or a database) and to return it when the last chunk is uploaded. But please keep in mind this is workable only for small files - if your files are bigger (the range is around two megabytes) enough you will get in troubles. However if you still want to return data you should decide how to save files with unique names (in order to preserve content from overwriting) and how to track all the chunks from uploaders. Please preview following articles where these techniques are discussed in depth, of course with examples:
    We hope this information will help you.

    Sincerely yours,
    Ivan
    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.
  19. kirakosyan
    kirakosyan avatar
    1 posts
    Member since:
    Apr 2007

    Posted 01 May 2011 Link to this post

    hi 
    in case if you set condition to if (this.IsFinalFileRequest())

    only last file is uploaded :-(
  20. Alex Fidanov
    Admin
    Alex Fidanov avatar
    636 posts

    Posted 05 May 2011 Link to this post

    Hi kirakosyan,

    The IsFinalFileRequest method will return true only when the final file of the upload session is uploaded. I am not sure what you mean by only this file has been uploaded. Could you please elaborate on that and what you are trying to achieve?
    Greetings,
    Alex Fidanov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  21. Sam Vanhoutte
    Sam Vanhoutte avatar
    7 posts
    Member since:
    Aug 2011

    Posted 04 Nov 2011 Link to this post

    Hello Ivan,
    The code you posted is not working for me.

    I'm trying to save a file and immediately get the file contents in the silverlight client.
    I'm stuck at filling the Dictionary with the file byte array. The ParamNameData does not exist (anymore). And the buffer value is null.

    Also not saving a file to disk would be even easier in my case (my files are < 50kb (only 1 buffer chunck)). Is there a quick example for this?

    public class UploadHandler : RadUploadHandler
        {
            public override Dictionary<string, object> GetAssociatedData()
            {
                Dictionary<string, object> dict = base.GetAssociatedData();
     
                string buffer = this.Request.Form[Telerik.Windows.Controls.RadUploadConstants.ParamNameAssociatedData];
                dict.Add("LastChunkData", buffer);
     
                return dict;
            }
     
        }

    Kind Regards
  22. Alex Fidanov
    Admin
    Alex Fidanov avatar
    636 posts

    Posted 09 Nov 2011 Link to this post

    Hi Sam Vanhoutte,

    If you want to get the bytes of the uploading(ed) file, you could access the FileInfo object from the RadUploadSelectedFile. For example, you can handle the FileUploaded event and get the SelectedFile's FileInfo object and its file stream.
    private void upload_FileUploaded(object sender, FileUploadedEventArgs e)
    {
        var stream = e.SelectedFile.File.OpenRead();
    }


    Please let me know if that works for you.

    All the best,
    Alex Fidanov
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  23. Ed
    Ed avatar
    1 posts
    Member since:
    Jul 2012

    Posted 18 Jul 2012 Link to this post

    The server-side examples you show use an older version of the RadUploadHandler control.  I'm using a newer version, 2001.1.419.35, and the RadUploadConstants.ParamNameData constant no longer exists.  What its equivalent in the newer version of the control?
  24. Tina Stancheva
    Admin
    Tina Stancheva avatar
    3298 posts

    Posted 19 Jul 2012 Link to this post

    Hello Ed,

    In the latest version of the control the this.Request.Form[key] syntax should be replaced with this.GetQueryParameter(key); More information about the changes in the control you can find here.

    However, I am not sure what exactly you need to implement so I'm not sure what approach to suggest you. If what you need to implement is upload a file and as soon as its uploaded, use it on the client-side, then you can try the approach demonstrated in our ImageGallery demo solution.

    All the best,
    Tina Stancheva
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

Back to Top
DevCraft banner