Skip to main content
1-Visitor
April 22, 2020
Question

Upload file in a WindChill document - OData REST API

  • April 22, 2020
  • 2 replies
  • 9712 views

I want to upload a file in WindChill. They give to us an REST API with the services to do this. They split an upload of file in 3 stages.

  • Stage 1 - We call a service where we give the number of files to upload. In this case only one.
  • Stage 2 - A multipart/formdata where we give the file to upload.
  • Stage 3 - The last stage where we give the file name, the file size etc...

I think my problem is on stage 2. All the stages run successfully but when i try to open the uploaded file, in this case a pdf, the file is blank, but with the same number of pages of the original one. I compare the content of the uploaded file with the original one and the content inside is the same with a big difference. The original is with an ANSI encoding while the uploaded one is with the UTF-8 encoding. So, I think my problem is on the stage 2.

I'm with some doubts on this stage. In C# I get the bytes[] of file, but in the end I need to pass this bytes to a string to send in a multipart form. What is the encoding that i should use to get string? I tested with default, UTF-8, UNICODE, ASCII encoding but nothing. Here is the example of the Post request body. In a C# I use the HTTPWebRequest to make a request.

------boundary
Content-Disposition: form-data; name="Master_URL"

https://MyUrl/Windchill/servlet/WindchillGW
------boundary
Content-Disposition: form-data; name="CacheDescriptor_array"

844032:844032:844032;
------boundary
Content-Disposition: form-data; name="844032"; filename="newDoc.pdf"
Content-Type: application/pdf

%PDF-1.7 //// The content of the file starts here
%µµµµ
1 0 obj
........

------boundary--

Before this approach I tried to convert the bytes[] ToBase64String and send an body like this:

------boundary
Content-Disposition: form-data; name="Master_URL"

https://MyUrl/Windchill/servlet/WindchillGW
------boundary
Content-Disposition: form-data; name="CacheDescriptor_array"

844033:844033:844033;
------boundary
Content-Disposition: form-data; name="844033"; filename="newDoc.pdf"
Content-Type: application/pdf
Content-Transfer-Encoding: base64

JVBERi0xLjcNCiW1tbW1DQox ........ //// The content of the file starts here 
------boundary--

In this case, when I try to open the file i get the error "Failed to load PDF document". The file is corrupt.

I think the problem is on the stage 2, but I will share the body that i send in last stage for your understanding.

{"ContentInfo":[{"StreamId":844034,"EncodedInfo": "844034%3A40384%3A9276564%3A844034","FileName": "newDoc.pdf","PrimaryContent": true,"MimeType" : "application/pdf","FileSize" : 40384}]}

The StreamId and the EncodedInfo are returns of the stage 2 that I need to provide in the stage 3.

Anyone can see what I'm doing wrong? Anyone have some tips to help me to solve this issue?

Many thanks.

2 replies

5-Regular Member
April 23, 2020

Hello Marco,

 

There is exists one interesting fact, that order of entities in form-data is important!

 

From java doc

 

 * <br>For regular upload, client needs to send the data in following format and order:
 * <br>-----------------------------boundary
 * <br>Content-Disposition: form-data; name="Master_URL"
 * <br>&lt;Master WindchillGW URL&gt;
 * <br>-----------------------------boundary
 * <br>Content-Disposition: form-data; name="CacheDescriptor_array"
 * <br>&lt;streamid&gt;:&lt;filename&gt;:&lt;contentid&gt;:&lt;filesize&gt;;&lt;streamid&gt;:&lt;filename&gt;:&lt;contentid&gt;:&lt;filesize&gt;;...
 * <br>-----------------------------boundary
 * <br>Content-Disposition: form-data; name="streamContentFromURL"
 * <br>&lt;file download URL&gt;
 * <br>-----------------------------boundary
 * <br>Content-Disposition: form-data; name="&lt;filename&gt;"; filename="&lt;filepath&gt;"
 * <br>&lt;actual content file&gt;
 * <br>-----------------------------boundary
 * <br>Content-Disposition: form-data; name="&lt;filename&gt;"; filename="&lt;filepath&gt;"
 * <br>&lt;actual content file&gt;
 * <br>-----------------------------boundary
 * <br>...
 * <br>
 * <br>For multi-chapter upload, client needs to send the data in following format:
 * <br>-----------------------------boundary
 * <br>Content-Disposition: form-data; name="Master_URL"
 * <br>&lt;Master WindchillGW URL&gt;
 * <br>-----------------------------boundary
 * <br>Content-Disposition: form-data; name="ChapteredCacheDescriptor_array"
 * <br>&lt;streamid&gt;:&lt;filename&gt;:&lt;contentid&gt;:&lt;filesize&gt;;&lt;streamid&gt;:&lt;filename&gt;:&lt;contentid&gt;:&lt;filesize&gt;;...
 * <br>-----------------------------boundary
 * <br>Content-Disposition: form-data; name="chaptered-upload-info"
 * <br>upload-chapters-count=&lt;Number of chapters to upload&gt;
 * <br>delegate=&lt;Delegate Name&gt; <nbsp/><nbsp/><nbsp/><nbsp/> (Optional)
 * <br>prev-content-data=&lt;Previous content data&gt; <nbsp/><nbsp/><nbsp/><nbsp/> (Required if you need to copy chapters)
 * <br>copyChapters=&lt;chaptername&gt;:&lt;chapter filesize&gt;:&lt;checksum&gt;
 * <br>copyChapters=&lt;chaptername&gt;:&lt;chapter filesize&gt;:&lt;checksum&gt;
 * <br>copyChapters=&lt;chaptername&gt;:&lt;chapter filesize&gt;:&lt;checksum&gt;
 * <br>...
 * <br>-----------------------------boundary
 * <br>Content-Disposition: form-data; name="Chapter";
 * <br>x-ptc-chapter-name:&lt;Chapter Name&gt;
 * <br>x-ptc-chapter-size:&lt;Chapter Size&gt;
 * <br>x-ptc-chapter-checksum:&lt;Check sum&gt; <nbsp/><nbsp/><nbsp/><nbsp/>(optional pass 0 if no value is available)
 * <br>x-ptc-stream-id:&lt;Stream Id&gt;
 * <br>&lt;actual content file&gt;
 * <br>-----------------------------boundary
 * <br>Content-Disposition: form-data; name="Chapter";
 * <br>x-ptc-chapter-name:&lt;Chapter Name&gt;
 * <br>x-ptc-chapter-size:&lt;Chapter Size&gt;
 * <br>x-ptc-chapter-checksum:&lt;Check sum&gt; <nbsp/><nbsp/><nbsp/><nbsp/>(optional pass 0 if no value is available)
 * <br>x-ptc-stream-id:&lt;Stream Id&gt;
 * <br>&lt;actual content file&gt;
 * <br>-----------------------------boundary
12-Amethyst
November 13, 2020

Hello,

 

Did you have finally solve your issue?

 

I try also to use those api rest to upload documents, but I struggle with PDF files.

 

It's working perfectly in case of simple ascii files, but I c'ant upload a pdf file: at the end, the file uploaded in windchill is corrupted.

I don't know how to create the body of the stage 2 for pdf or other binary files.

 

Thank you very much for your feedback

 

Thierry

5-Regular Member
November 13, 2020

Could you post the MethodServer log exception?

12-Amethyst
November 13, 2020

Hello,

 

No, I'm not admin of the system so I've no acces on the Methodserver.

 

In fact, when I use the stage 2, I've no error message: at the end, I'm able to do stage 1, 2 and 3, the content of the WTDocument is created but in case of PDF, the file created in windchill is corrupted when I try to open it.

 

When I do that for a simple ascii file, it's working perfectly: file is created in Windchill and I can open it.

 

My issue is how created the body for the stage2 to be able to upload a pdf, and especially, the third part like this one: 

------boundary
Content-Disposition: form-data; name="844032"; filename="newDoc.pdf"
Content-Type: application/pdf

%PDF-1.7 //// The content of the file starts here
%µµµµ
1 0 obj
........

------boundary--

 

Thank you for your help