0

I'm connecting to an on-prem 2016 SharePoint system.

I'm trying to use REST to download a file from a doc library. I'm able to create the REST call, however the data I'm being returned looks jumbled...

The call:

using (var client = new WebClient())
{
    client.Headers.Add(HttpRequestHeader.ContentType, "application/json;odata=verbose");
    client.Headers.Add(HttpRequestHeader.Accept, "application/json;odata=verbose");
    client.Headers.Add(HttpRequestHeader.ContentEncoding, "UTF-8");

    client.Headers.Add(HttpRequestHeader.Cookie, FedAuthToken);
    var endpointUri = new Uri("https://test.mycorp.com/sites/RESTPOC/_api/web/getfilebyserverrelativeurl('/sites/RESTPOC/Shared%20Documents/banner-05.jpg')/OpenBinaryStream");
    var result = client.DownloadString(endpointUri);
}

The output of 'Result' looks like:

"ÿØÿá\0\u0018Exif\0\0II*\0\b\0\0\0\0\...goes on quite a while...

Any advice on how I should handle this, and the best way to stream this into an actual file?

Thanks

3 Answers 3

2

You asked for JSON as your response format, and you got a JavaScript encoded string back. Maybe try:

client.Headers.Add(HttpRequestHeader.Accept, "image/jpeg");

or

client.Headers.Add(HttpRequestHeader.Accept, "application/octet-stream");
2
  • Thanks, however the response still looks scrambled, even after trying the different headers. I've also tried encoding it into an array: byte[] byteArray = Encoding.UTF8.GetBytes(result); --> without success. Mar 13, 2018 at 9:08
  • You just dont use DownloadString method... there needs to be method to download byte array, isnt there DownloadData?
    – michalh
    Feb 15, 2019 at 9:04
1

Found the solution, I should have been using client.DownloadData rather than client.DownloadString.

Also, included the additional header as provided in the first answer:

using (var client = new WebClient())
        {
            client.Headers.Add(HttpRequestHeader.Accept, "application/octet-stream");
            client.Headers.Add("binaryStringRequestBody", "true");

            client.Headers.Add(HttpRequestHeader.Cookie, cook2);
            var endpointUri = new Uri("https://collab.myCorp.com/sites/RESTPOC/_api/web/getfilebyserverrelativeurl('/sites/RESTPOC/Shared%20Documents/banner-05.jpg')/OpenBinaryStream");
            var result = client.DownloadData(endpointUri);

            MemoryStream stream = new MemoryStream(result);
            File.WriteAllBytes("C:\\temp\\image.jpg", result);

            Console.ReadKey();
        }
2
  • what is cook2?? Jun 18, 2019 at 12:20
  • Its the FedAuth cookie value Jun 18, 2019 at 16:08
0

Here is a demo for your reference:

//Create a stream for the file
Stream stream = null;

//This controls how many bytes to read at a time and send to the client
int bytesToRead = 10000;

// Buffer to read bytes in chunk size specified above
byte[] buffer = new Byte[bytesToRead];

// The number of bytes read
try
{
  //Create a WebRequest to get the file
  HttpWebRequest fileReq = (HttpWebRequest) HttpWebRequest.Create(url);

  //Create a response for this request
  HttpWebResponse fileResp = (HttpWebResponse) fileReq.GetResponse();

  if (fileReq.ContentLength > 0)
    fileResp.ContentLength = fileReq.ContentLength;

    //Get the Stream returned from the response
    stream = fileResp.GetResponseStream();

    // prepare the response to the client. resp is the client Response
    var resp = HttpContext.Current.Response;

    //Indicate the type of data being sent
    resp.ContentType = "application/octet-stream";

    //Name the file 
    resp.AddHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
    resp.AddHeader("Content-Length", fileResp.ContentLength.ToString());

    int length;
    do
    {
        // Verify that the client is connected.
        if (resp.IsClientConnected)
        {
            // Read data into the buffer.
            length = stream.Read(buffer, 0, bytesToRead);

            // and write it out to the response's output stream
            resp.OutputStream.Write(buffer, 0, length);

            // Flush the data
            resp.Flush();

            //Clear the buffer
            buffer = new Byte[bytesToRead];
        }
        else
        {
            // cancel the download if client has disconnected
            length = -1;
        }
    } while (length > 0); //Repeat until no data is read
}
finally
{
    if (stream != null)
    {
        //Close the input stream
        stream.Close();
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.