Quality Center Support and News
Showing results for 
Search instead for 
Do you mean 

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

Highlighted
Occasional Collector

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?

4 REPLIES
Occasional Visitor

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)

 

Occasional Visitor

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

Occasional Visitor

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

Collector

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

using (var client = new WebClientEx(CookieContainer))
{

string url = HttpUtility.UrlDecode(uri);
client.Credentials = new NetworkCredential(this._connectionParams.Username, this._connectionParams.Password, this._connectionParams.Domain);


client.Headers.Add(HttpRequestHeader.Accept, "application/xml");
client.Headers.Add("Content-Type", "multipart/form-data; boundary=" + boundary);

List<byte> bytes = new List<byte>();
_request.ContentType = "multipart/form-data; boundary=" + boundary + ";";
StringBuilder sb = new StringBuilder();
sb.Append("--");
sb.Append(boundary);
sb.AppendLine();
sb.Append("Content-Disposition: form-data; name=\"filename\"");
sb.AppendLine(); sb.AppendLine();
sb.Append(attachementName);
sb.AppendLine();
sb.Append("--");
sb.Append(boundary);
sb.AppendLine();
sb.Append("Content-Disposition: form-data; name=\"ref-subtype\"");
sb.AppendLine();
sb.AppendLine();
sb.Append("1");
sb.AppendLine();
sb.Append("--");
sb.Append(boundary);
sb.AppendLine();
sb.Append("Content-Disposition: form-data; name=\"file\"; filename=\"" + attachementName + "\"");
sb.AppendLine();
sb.Append("Content-Type: text/plain");
sb.AppendLine(); sb.AppendLine();
string postHeader = sb.ToString();
byte[] postHeaderBytes = Encoding.UTF8.GetBytes(postHeader);
bytes.AddRange(postHeaderBytes);
bytes.AddRange(_attachmentContent);
sb = new StringBuilder();
sb.AppendLine();
sb.Append("--" + boundary + "--");


postHeader = sb.ToString();
postHeaderBytes = Encoding.UTF8.GetBytes(postHeader);
bytes.AddRange(postHeaderBytes);

byte[] _finalBytes = bytes.ToArray();
byte[] _respBytes = client.UploadData(url, _finalBytes);
if (_respBytes != null && _respBytes.Length > 0)
{
this.Response = Encoding.Default.GetString(_respBytes);
return true;
}
// string vvv = Encoding.UTF8.GetString(ddd);

}