Upload files to WS via the REST API

Dear developers,

I am trying to upload a wsxz file back to WS using the API. I use the following code:

var client = new HttpClient();
client.BaseAddress = new Uri(srvAddress);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/octet-stream"));

Byte[] fileBytes = File.ReadAllBytes(wsxzFilePath);

HttpContent fileStreamContent = new ByteArrayContent(fileBytes);
var response = client.PostAsync(" /ws-api/v1/files?token=" + token, fileStreamContent).Result;

The response I am receiving is 406-Not acceptable.

What do I miss in here?

Thanks in advance for your support.

Regards,

Laurent

Parents
  • The request must have Content-Type=multipart/form-data and the attribute "file" that contains the file.

    The best way to get more information than presented in the documentation is, if you have access to a WS instance to inspect the interactions that the ui makes with the api (Developer Tools > Network in Chrome).

    In Java, using Spring it would look something like:
    public VMFile upload(Resource fileContent) throws RestAPIException {

    MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();
    parts.add("file", fileContent);


    ResponseEntity<VMFile> response = restTemplate.exchange(url, HttpMethod.POST,
    new HttpEntity<>(parts, context.getMultiPartHeaders()),
    new ParameterizedTypeReference<VMFile>() {
    });

    return response.getBody();
    }

    public HttpHeaders getMultiPartHeaders() {
    return new HttpHeaders() {
    {
    setContentType(MediaType.MULTIPART_FORM_DATA);
    setAccept(new ArrayList<>(Arrays.asList(MediaType.APPLICATION_JSON)));
    set("Token", token);
    }
    };
    }
  • Dear Stefan,

    Thank you for your quick reply.  Based on your JAVA code and searches on the internet, I managed to move forward but I am still not successful. At least my POST method runs to completion but it returns an error message:

    {"errors":[{"code":401,"type":"UNAUTHORIZED","message":"No session token provided."}]}

    Based on inspections I made, I suspect that the boundary is the reason of the problem but I can't find the reason why. All this is new land to me and I made a lot of tries before contacting you.

    Have you any hint/idea about the reason of the problem. Below is my code.

    Thanks in advance for your support.

    Regards,

    Laurent

    var client = new HttpClient();

    client.BaseAddress = new Uri(srvAddress);

    client.DefaultRequestHeaders.Accept.Clear();

    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");

    Stream rs = new MemoryStream();

    var endBoundaryBytes = System.Text.Encoding.UTF8.GetBytes("\r\n--" + boundary + "--");

    string headerTemplate = "--" + boundary + "\r\nContent-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";

    string header = string.Format(headerTemplate, "file", fileName, "application/octet-stream");

    byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);

    rs.Write(headerbytes, 0, headerbytes.Length);

    using (var fileStream = new FileStream(file, FileMode.Open, FileAccess.Read))

    {

    var buffer = new byte[1024];

    var bytesRead = 0;

    while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)

    {

    rs.Write(buffer, 0, bytesRead);

    }

    }

    rs.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);

    rs.Flush();

    rs.Position = 0;

    byte[] tempBuffer = new byte[rs.Length];

    rs.Read(tempBuffer, 0, tempBuffer.Length);

    rs.Close();

    MultipartFormDataContent formData = new MultipartFormDataContent();

    formData.Headers.Remove("Content-Type");

    formData.Headers.Add("Content-Type", "multipart/form-data; boundary=" + boundary);

    ByteArrayContent bac = new ByteArrayContent(tempBuffer);

    formData.Add(bac);

    HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, " /ws-api/v1/files?token=" + token);

    req.Content = formData;

    HttpResponseMessage response = await client.SendAsync(req);

    var jsonResponse = await response.Content.ReadAsStringAsync();

Reply
  • Dear Stefan,

    Thank you for your quick reply.  Based on your JAVA code and searches on the internet, I managed to move forward but I am still not successful. At least my POST method runs to completion but it returns an error message:

    {"errors":[{"code":401,"type":"UNAUTHORIZED","message":"No session token provided."}]}

    Based on inspections I made, I suspect that the boundary is the reason of the problem but I can't find the reason why. All this is new land to me and I made a lot of tries before contacting you.

    Have you any hint/idea about the reason of the problem. Below is my code.

    Thanks in advance for your support.

    Regards,

    Laurent

    var client = new HttpClient();

    client.BaseAddress = new Uri(srvAddress);

    client.DefaultRequestHeaders.Accept.Clear();

    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");

    Stream rs = new MemoryStream();

    var endBoundaryBytes = System.Text.Encoding.UTF8.GetBytes("\r\n--" + boundary + "--");

    string headerTemplate = "--" + boundary + "\r\nContent-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";

    string header = string.Format(headerTemplate, "file", fileName, "application/octet-stream");

    byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);

    rs.Write(headerbytes, 0, headerbytes.Length);

    using (var fileStream = new FileStream(file, FileMode.Open, FileAccess.Read))

    {

    var buffer = new byte[1024];

    var bytesRead = 0;

    while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)

    {

    rs.Write(buffer, 0, bytesRead);

    }

    }

    rs.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);

    rs.Flush();

    rs.Position = 0;

    byte[] tempBuffer = new byte[rs.Length];

    rs.Read(tempBuffer, 0, tempBuffer.Length);

    rs.Close();

    MultipartFormDataContent formData = new MultipartFormDataContent();

    formData.Headers.Remove("Content-Type");

    formData.Headers.Add("Content-Type", "multipart/form-data; boundary=" + boundary);

    ByteArrayContent bac = new ByteArrayContent(tempBuffer);

    formData.Add(bac);

    HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, " /ws-api/v1/files?token=" + token);

    req.Content = formData;

    HttpResponseMessage response = await client.SendAsync(req);

    var jsonResponse = await response.Content.ReadAsStringAsync();

Children