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();

  • I see that your token is already in the url, so it should be ok. The only way to get that error when you set the Token in the url or headers is that the token is empty.

    Can you intercept the HTTP request that is sent to the server? (you can use Membrane Monitor for this) That would give us a better image of the request.
Reply Children