Quality Center / ALM Practitioners Forum
cancel

Upload Attachment to ALM REST API using multiplepart/form-data header with C# code

Highlighted
pcpaukm
New Member.

Upload Attachment to ALM REST API using multiplepart/form-data header with C# code

From the documentation to upload attachment with content-type: multipart/form-data header, I know the following is needed:

 

Header:
Content-Type: multipart/form-data; boundary=exampleboundary;

 

Data:

--exampleboundary
Content-Disposition: form-data; name="filename"

example.txt

--exampleboundary
Content-Disposition: form-data; name="file"; filename="example.txt"
Content-Type: text/plain

[Content of file]
--exampleboundary--

 

I wrote the following test code:

public HttpResponseMessage UploadFile(HttpRequestMessage request, Stream stream, string fileName)
        {
            using (HttpClient httpClient = new HttpClient {BaseAddress = new Uri("MY URL")})
            {
                using (var content = new MultipartFormDataContent())
                {
                    var mutipleFormData1 = new StringContent(fileName);
                    mutipleFormData1.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
                    {
                        Name = "\"filename\"",
                    };
                    mutipleFormData1.Headers.ContentType = null;
 
                    content.Add(mutipleFormData1);
 
                    var mutipleFormData2 = new StreamContent(stream);
                    mutipleFormData2.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
                    {
                        Name = "\"file\"",
                        FileName = "\"" + fileName + "\""
                    };
                    mutipleFormData2.Headers.ContentType = new MediaTypeHeaderValue("text/plain");
                    content.Add(mutipleFormData2);
 
                    request.Content = content;
                    return httpClient.PostAsync(request.RequestUri, content).Result;
                }
            }
        }

 

 

In fiddler, I could see it populated properly:

Content-Disposition: form-data; name="file"; filename="hello.txt"
Content-Type: text/plain hi hi Content-Disposition: form-data; name="filename" hello.txt

 

But the response from the REST API returns:

HP Application Lifecycle Management
String index out of range: -1
Exception Id: qccore.general-error 
Show Details
Exception Properties:
 
Stack Trace:
 

 

I tested with a 3rd party browser-based REST client sending the same request and it works prefectly, could someone tell me what is wrong with my C# code?

6 REPLIES
Rembaldi
New Member.

Re: Upload Attachment to ALM REST API using multiplepart/form-data header with C# code

Did you ever figure this out?  I have the same issue but the attachment appears to get added.

 

<QCRestException><Id>qccore.general-error</Id><Title>String index out of range: -1</Title><StackTrace>java.lang.StringIndexOutOfBoundsException: String index out of range: -1&#xD;
at java.lang.String.substring(String.java:1937)&#xD;
at org.apache.wink.common.internal.providers.multipart.MultiPartParser.parseHeaders

 

From fiddler:

 

POST http://tlvqc:8080/qcbin/rest/domains/WAS/projects/IMPACT360/defects/130450/attachments HTTP/1.1
Content-Type: multipart/form-data; boundary=--8d19a63e4b94f27
Host: tlvqc:8080
Content-Length: 678
Expect: 100-continue

 

----8d19a63e4b94f27
Content-Disposition: form-data; name="filename"

1402019845_status.png

 

----8d19a63e4b94f27
Content-Disposition: form-data; name="file"; filename="1402019845_status.png"
Content-Type: image/png

 

..(continued)

 

PieceOfChum
Contributor.

Re: Upload Attachment to ALM REST API using multiplepart/form-data header with C# code

I am also trying to upload attachment using C# and HP ALM REST API. I have tried everything I know how to do but I have not gotten it to work. If you have code that works that you can share it would be very helpful to me. It would be nice if HP provided examples of using their api.

 

Thanks

skbp
New Member.

Re: Upload Attachment to ALM REST API using multiplepart/form-data header with C# code

Hi,

 

Were able to make it work send attachment through API if so could you pleas elet me know.

 

Thanks,

SKBP

GaneshPatil
Contributor.

Re: Upload Attachment to ALM REST API using multiplepart/form-data header with C# code

I got the solution after doing lots of struggle in code..

solution is that we need to write the byte array of attachment on request stream using the MemoryStream. below is the code snnipest.

 string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
     byte[] boundaryBytes = System.Text.Encoding.ASCII.GetBytes("--" + boundary + "\r\n");

     HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.Create(MyUrl);

     webRequest.ContentType = "multipart/form-data; boundary=" + boundary;
     webRequest.Method = "POST";


     using (Stream requestStream = webRequest.GetRequestStream())
     {
              // write boundary bytes
              requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);

              // write header bytes.
              string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
              string header = string.Format(headerTemplate, "MyName", "MyFileName", "content type");
              byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
              requestStream.Write(headerbytes, 0, headerbytes.Length);

              using (MemoryStream memoryStream = new MemoryStream(imageBytes))
              {
                      byte[] buffer = new byte[4096];
                      int bytesRead = 0;
                      while ((bytesRead = memoryStream.Read(buffer, 0, buffer.Length)) != 0)
                      {
                              requestStream.Write(buffer, 0, bytesRead);
                      }
               }

               // write trailing boundary bytes.
               byte[] trailerBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
               requestStream.Write(trailerBytes, 0, trailerBytes.Length);

       }

       using (HttpWebResponse wr = (HttpWebResponse)webRequest.GetResponse())
       {
               using (Stream response = wr.GetResponseStream())
               {
                    // handle response stream.
               }
       }

 

 

All the best..

BerndP
Regular Contributor.

Re: Upload Attachment to ALM REST API using multiplepart/form-data header with C# code

Hi Ganesh,

what's the endpoint?

only /attachments would not be enough.

MyUrl??

KR

Bernd

GaneshPatil
Contributor.

Re: Upload Attachment to ALM REST API using multiplepart/form-data header with C# code

Hi Bernd,

i have use below URL to post the attachments

http://MYIPADDRESS/qcbin/rest/domains/WAS/projects/IMPACT360/attachments

are you able to get the response from GET Request on same URL  ???

Thanks 

Ganesh.