Search code examples
c#databasefilewebrequestrecover

How recover and create file from WebRequest and write this in database (C#)?


My problem is that I want to recover the file that the server send me, by a WebRequest. With this stream, i want to create a file AND store the file in database (varbinary(MAX) variable). How can i do this ? My request : HttpWebRequest webRequest = WebRequest.Create("https://test.website.fr/website/api/test/") as HttpWebRequest;

Thanks Iris


Solution

  • I found the solution yesterday :D. The following code explains how to recover the file from the stream, how to write this in a database, how get the file from the database and how create a file from it. You can directly write the file ! (The "main" function is "Download()"

    private void Download()
    {
        //Create de request
        HttpWebRequest webRequest = WebRequest.Create("https://test.website.fr/website/api/test/") as HttpWebRequest;
    
        webRequest.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1";
        webRequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
    
        //encode to Base64
        string sAuthorization = "username:password";
        byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(sAuthorization);
        string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
    
        //Add authentification to request's header
        webRequest.Headers.Add("Authorization: Basic " + returnValue);
    
        try
        {
            //Get response
            HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
            Stream input = webResponse.GetResponseStream(); //Store the response in a Stream
    
            //Transform stream to byte array
            byte[] tabTempTest = ReadFully(input);
            int i = tabTempTest.Length;
    
            WitreToDatabase(tabTempTest, i);
    
    
    
            //At this moment, your file is write in database !!!
            //Then i'll go to get this file from database
    
            //my param idFile indicate the file in the db
            int idFile = 6;
            byte[] fileFromDatabase = GetFileFromDB(idFile);
    
            //Here, your file is store in the byte array.
            //Now, just write this in a file
    
            //Convert to a Stream
            Stream newStream = new MemoryStream(fileFromDatabase);
    
            //Create the file
            using (Stream file = File.OpenWrite("NewFile.pdf"))
            {
                CopyStreamToFile(newStream, file);
            }
    
            //Clore the procedure
            webRequest.GetResponse().Close();
        }
        catch (WebException ex)
        {
            int iRetourcode = 0;
            if (ex.Status == WebExceptionStatus.ProtocolError)
            {
                var response = ex.Response as HttpWebResponse;
                if (response != null)
                {
                    iRetourcode = (int)response.StatusCode;
                }
                else
                {
                    // no http status code available
                }
            }
            else
            {
                // no http status code available
            }
        }
    }
    

    This function stores a stream in a byte array :

    public static byte[] ReadFully(Stream input)
    {
        byte[] buffer = new byte[16 * 1024];
        using (MemoryStream ms = new MemoryStream())
        {
            int read;
            while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, read);
            }
            return ms.ToArray();
        }
    }
    

    WriteToDatabase function stores the byte array (the file) in database :

    public static void WitreToDatabase(byte[] tabTempTest, int i)
    {
        //First method to execute SQL procedure
        string queryStmt = "INSERT INTO dbo.DOCUMENT(DOC_CONTENU, DOC_LENGTH) VALUES(@CONTENU, @LENGTH)"; //Store length it's to easy for future
        using (SqlConnection _con = new SqlConnection("Data Source=SERVER_NAME;Initial Catalog=THOMAS;User ID=id;Password=pass"))
        using (SqlCommand _cmd = new SqlCommand(queryStmt, _con))
        {
            SqlParameter param = _cmd.Parameters.Add("@CONTENU", SqlDbType.VarBinary);
            SqlParameter param2 = _cmd.Parameters.Add("@LENGTH", SqlDbType.Int);
            param.Value = tabTempTest;
            param2.Value = i;
    
            _con.Open();
            _cmd.ExecuteNonQuery();
            _con.Close();
        }
    }
    

    Get the byte array (the file) from database :

    public static byte[] GetFileFromDB(int idFile)
    {
        int length = 0;
        //Second method to execute SQL procedure
        DataSet ds = SqlHelper.ExecuteDataset("Data Source=SERVER_NAME;Initial Catalog=THOMAS;User ID=id;Password=pass", "GetFile", idFile);
    
        /*
            StoredProcedure : 
            SELECT DOC_CONTENU, DOC_LENGTH FROM THOMAS.dbo.DOCUMENT WHERE DOC_ID = @ID_FILE
         */
        foreach (DataRow dr in ds.Tables[0].Rows)
        {
            length = Convert.ToInt32(dr["DOC_LENGTH"]);
        }
    
        byte[] tabFile = new byte[length];
    
        foreach (DataRow dr in ds.Tables[0].Rows)
        {
            tabFile = (byte[])dr["DOC_CONTENU"];
        }
        return tabFile;
    }
    

    Write in a file :

    public static void CopyStreamToFile(Stream input, Stream output)
    {
        byte[] buffer = new byte[8 * 1024];
        int len;
        while ((len = input.Read(buffer, 0, buffer.Length)) > 0)
        {
            output.Write(buffer, 0, len);
        }
    }
    

    I hope that this code will help you ! Thomas B.