2

My aim is to GET and POST files to SP Online.

I have written a WEB API with the two methods. These methods use CSOM to interact with SP Online.

The GET returns the response Ok(array of bytes) to the client and the POST gets the entire file to upload in the request body and performs the upload to Sharepoint Online in chunks.

I've been told that i should use streaming techniques, since the context is an enterprise application with many simultaneous requests. So the GET method should return a stream to the client and the client should send the request as a stream to the POST.

In the client side i'm forced to use the RestSharp library.

So:

1) How to use RestSharp to deal with streams?

2) How can the WebAPI return a stream?

3) Along with the file i send a lot of metadata. How can i upload the file in streaming mode and send the metadata only once?

Client side, the get requires an array of bytes and the post sends an array of bytes along with metadata.

Online i've found too many techniques. Is there a standard one?

Stephu
  • 3,236
  • 4
  • 21
  • 33
Loris
  • 454
  • 7
  • 19

1 Answers1

5

There a very basic example. It does not covers all of your questions but this is a point to start.

Client with RestSharp:

(I did small ASP.NET Core 2.0 console Application). Add the following code to your Programm.cs)

using System;
using System.IO;
using RestSharp;

namespace RestSharpClient
{
    class Program
    {
        public const string baseUrl = "http://localhost:58610/api/values"; // <-- Change URL to yours!
        static void Main(string[] args)
        {
            Console.ReadKey();
            string tempFile = Path.GetTempFileName();
            using (var writer = File.OpenWrite(tempFile))
            {
                var client = new RestClient(baseUrl);
                var request = new RestRequest();
                request.ResponseWriter = (responseStream) => responseStream.CopyTo(writer);
                var response = client.DownloadData(request);
            }

            Console.ReadKey();
        }
    }
}

Server

My controlller:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Net.Http.Headers;

namespace Server.Controllers { [Route("api/[controller]")]
    public class ValuesController: Controller {
        // GET api/values
        [HttpGet]
        public FileStreamResult GetTest() {
            var stream = new MemoryStream(Encoding.ASCII.GetBytes("Hello World"));
            return new FileStreamResult(stream, new MediaTypeHeaderValue("text/plain")) {
                FileDownloadName = "test.txt"
            };
        }
    }
}

Important: Enable CORS. For that add the following line to your Startup.cs before services.AddMvc();

services.AddCors();

How to add metadata:

WebAPI method that takes a file upload and additional arguments

Ali Bdeir
  • 4,151
  • 10
  • 57
  • 117
Stephu
  • 3,236
  • 4
  • 21
  • 33
  • I added code-formatting hints to your code blocks. Note that you don't have to edit the question's tags to make that happen... – Heretic Monkey Feb 11 '18 at 17:49
  • 1
    Client side i need to know the response code from the Web API. Is it possible to encapsulate the stream in an IHttpActionResult object, or rather, a Task object since my methods are async? – Loris Feb 12 '18 at 09:31
  • @Loris: FileStreamResult inherits from ActionResult. Take a look to: https://stackoverflow.com/questions/42460198/return-file-in-asp-net-core-web-api – Stephu Feb 12 '18 at 09:37
  • IHttpActionResult comes from System.Web.Http, while FileStreamResult comes from System.Web.Mvc. – Loris Feb 12 '18 at 09:48
  • Indeed, i'm dealing with a Web API project, not an MVC project :) – Loris Feb 12 '18 at 09:51