This is a migrated thread and some comments may be shown as answers.

How can I get Byte[] file?

22 Answers 759 Views
Upload
This is a migrated thread and some comments may be shown as answers.
Jan Michael
Top achievements
Rank 1
Jan Michael asked on 06 Nov 2008, 09:30 AM
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.

22 Answers, 1 is accepted

Sort by
0
Jan Michael
Top achievements
Rank 1
answered on 07 Nov 2008, 12:27 AM
Hi, can someone answer my question? Tnx.
0
Valentin.Stoychev
Telerik team
answered on 10 Nov 2008, 05:05 PM
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.
0
Jan Michael
Top achievements
Rank 1
answered on 10 Nov 2008, 05:56 PM
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!
0
Valentin.Stoychev
Telerik team
answered on 17 Nov 2008, 10:31 AM
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.
0
Richard
Top achievements
Rank 1
answered on 17 Nov 2008, 08:48 PM
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?
0
Valentin.Stoychev
Telerik team
answered on 18 Nov 2008, 07:23 PM
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.
0
Richard
Top achievements
Rank 1
answered on 30 Dec 2008, 04:44 PM

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.
0
Richard
Top achievements
Rank 1
answered on 30 Dec 2008, 07:37 PM
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.

0
Valentin.Stoychev
Telerik team
answered on 05 Jan 2009, 03:33 PM
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.
0
Richard
Top achievements
Rank 1
answered on 06 Jan 2009, 04:46 PM
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);    
        }  
    }  

0
Accepted
Valentin.Stoychev
Telerik team
answered on 06 Jan 2009, 05:05 PM
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.
0
Alex
Top achievements
Rank 1
answered on 12 Aug 2009, 09:47 AM
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.

 

0
Ivan
Telerik team
answered on 12 Aug 2009, 11:48 AM
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.
0
Alex
Top achievements
Rank 1
answered on 13 Aug 2009, 01:40 AM
Thanks very much,it is fixed.
0
Alex
Top achievements
Rank 1
answered on 21 Sep 2009, 07:45 AM
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.
0
Ivan
Telerik team
answered on 22 Sep 2009, 11:52 AM
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.
0
kirakosyan
Top achievements
Rank 1
answered on 01 May 2011, 10:14 PM
hi 
in case if you set condition to if (this.IsFinalFileRequest())

only last file is uploaded :-(
0
Alex Fidanov
Telerik team
answered on 05 May 2011, 09:05 AM
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
0
Sam Vanhoutte
Top achievements
Rank 1
answered on 04 Nov 2011, 04:54 PM
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
0
Alex Fidanov
Telerik team
answered on 09 Nov 2011, 04:42 PM
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 >>

0
Ed
Top achievements
Rank 1
answered on 18 Jul 2012, 07:19 PM
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?
0
Tina Stancheva
Telerik team
answered on 19 Jul 2012, 07:52 AM
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.

Tags
Upload
Asked by
Jan Michael
Top achievements
Rank 1
Answers by
Jan Michael
Top achievements
Rank 1
Valentin.Stoychev
Telerik team
Richard
Top achievements
Rank 1
Alex
Top achievements
Rank 1
Ivan
Telerik team
kirakosyan
Top achievements
Rank 1
Alex Fidanov
Telerik team
Sam Vanhoutte
Top achievements
Rank 1
Ed
Top achievements
Rank 1
Tina Stancheva
Telerik team
Share this question
or