Hi,
I'm working on a little utility to migrate our content from SharePoint to Confluence.
It's all looking very slick, using the REST API, until I get to uploading images/attachments.
I'm constructing a multipart/form-data request
. This is my code (which is C#, I don't expect you to answer this, but for completeness)
string url = $"/rest/api/content/{id}/child/attachment"; using (MultipartFormDataContent multipartFormDataContent = new MultipartFormDataContent()) { ByteArrayContent byteArrayContent=new ByteArrayContent(fileBytes); byteArrayContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { FileName = $"\"{fileName}\"", Name = $"\"File\"" }; byteArrayContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); multipartFormDataContent.Add(byteArrayContent); multipartFormDataContent.Headers.Add("X-Atlassian-Token","nocheck"); HttpResponseMessage result=_httpClient.PostAsync(url, multipartFormDataContent).Result; if (result.IsSuccessStatusCode) { // YAY! } else { _log.ErrorFormat("POST {0} -> {1} {2}", url, result.StatusCode, result.ReasonPhrase); // BOO! } }
This generates a request as below:
POST http://xxxx.local:8090/rest/api/content/2326605/child/attachment HTTP/1.1 Authorization: Basic bnB3MDxxxxxxx2YXRhciM1Mw== Accept: application/json Content-Type: multipart/form-data; boundary="b1d733c1-c465-44bc-abe5-4ebf2e563eb5" X-Atlassian-Token: nocheck Host: iomvbuild2.inter.local:8090 Cookie: CONFLUENCESESSIONID=F19F135FDE0033B5762E262A4342A19F Content-Length: 21372 Expect: 100-continue --b1d733c1-c465-44bc-abe5-4ebf2e563eb5 Content-Disposition: form-data; filename="image_thumb_36465F59.png"; name="File" Content-Type: application/octet-stream PNG IHDR i sRGB gAMA a pHYs o d RAIDATx^ TT[ } 7 w } v } > c 9bT2 ( J d 9' $ $9眑 Z JEEѣm { ڻ * \s 9 Z mG.a q u ^ ϛ qPX MMMܫ ' L [q -,X bɊ5 Gww7 < --- truncated --> 2_B k֬ ݻ a z i& Zi& 2'_j -##[[[dffb . Dtt4 ** ;v` شi t ݻ c v :t S `M%llld 5 K q W ml v u CAA 9 `& "##QQQ cccLi[z L״lll3 ''' m|М ; cooo<~ yyyhmm 2 TԴ Naa!3 M-vFFsL srr 6 A e= l 2 ``` ?) { F6 IEND B` --b1d733c1-c465-44bc-abe5-4ebf2e563eb5--
But this doesn't work, I get the response below:
HTTP/1.1 400 Bad Request Server: Apache-Coyote/1.1 X-ASEN: SEN-8xxx7 X-Seraph-LoginReason: OK X-AUSERNAME: Nxxx2 Cache-Control: no-cache, must-revalidate Expires: Thu, 01 Jan 1970 00:00:00 GMT X-Content-Type-Options: nosniff Content-Type: application/json Transfer-Encoding: chunked Date: Tue, 01 Nov 2016 10:52:34 GMT Connection: close aa {"statusCode":400,"data":{"authorized":false,"valid":true,"errors":[],"successful":false,"notSuccessful":true},"message":"At least one attachment file must be included."} 0
Specifically, "At least one attachment file must be included". What is going wrong here?
Thanks
Nathan
Community moderators have prevented the ability to post new answers.
This is part of code behind the rest call you are doing:
@Consumes(MediaType.MULTIPART_FORM_DATA) @MultipartConfigClass(ConfluenceAttachmentMultipartConfig.class) @RequiresXsrfCheck public RestList<Content> createAttachments(@PathParam("id") ContentId containerId, @QueryParam("status") @DefaultValue("current") ContentStatus containerStatus, @MultipartFormParam("file") List<FilePart> fileParts, @Nullable @MultipartFormParam("comment") List<FilePart> comments, @Nullable @MultipartFormParam("minorEdit") List<FilePart> minorEdits) throws ServiceException { if (!attachmentService.validator().canCreateAttachments(containerId, containerStatus)) { throw new PermissionException("User not permitted to create attachments for content: " + containerId); } if (fileParts.isEmpty()) { throw new BadRequestException("At least one attachment file must be included."); }
It seems that the "File" should be "file"
That's it!
Thanks very much. Such a simple thing. The error message perhaps needs tweaking. I'd tried "File" previously but as a discrete field, clearly I'd missed that!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Glad I helped
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
My question would be - why would you want to do this in the first place? Confluence is not a document repository tool. I'm all for moving content from SharePoint to Confluence, but don't you want to make them pages in Confluence rather than attachments? By using just attachments you are missing out on the power of the wiki.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Many documents are not puretext. They contain illustrative images to assist in the communication of information. These images exist in the Confluence world as attachments outside the text document itself. Therefore, you upload a text document as a Confluence page, and upload its images as attachments. If you only upload the text of the document, you won't have access to the illustrative images.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.