Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

Uploading attachment into Confluence

Nathan Pledger November 1, 2016

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

2 answers

1 accepted

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

2 votes
Answer accepted
Panos
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 1, 2016

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"

Nathan Pledger November 2, 2016

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!

 

Panos
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 2, 2016

Glad I helped smile

0 votes
Sandy Johnson November 1, 2016

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.

Helen OBoyle June 29, 2017

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.

Anna Sosnowski January 8, 2019

How do you upload an attachment? I am getting an error.

Anna Sosnowski January 8, 2019

Also, I am using Google Docs.

TAGS
AUG Leaders

Atlassian Community Events