My ultimate goal in the script I am writing is to download all attachments from rally. I was able to successfully connect to the server, make a request for all attachments in a workspace, and finally, iterate through to retrieve the content of each attachment. This yields a dynamicJsonObject
of the AttachmentContent
. Being new to any API as well C# and .NET, I am now stuck. I cannot figure out a way to access and download the content of this object to a file on my computer. The line I have commented below is where I am currently getting an error and I am stuck. Any help would be greatly appreciated.
P.S. Here is my main method:
static void Main(string[] args)
{
RallyRestApi restApi = new RallyRestApi("[email protected]", "password", "https://rally1.rallydev.com", "1.43");
Request request = new Request("attachment");
request.Workspace = "/workspace/186282018";
request.Fetch = new List<string>() { "Name", "Artifact", "Content", "ContentType" };
request.Query = new Query("");
QueryResult queryResult = restApi.Query(request);
int count = 0;
foreach (var result in queryResult.Results)
{
DynamicJsonObject content = result["Content"];
//var binContent = content["Content"];
count++;
}
Console.WriteLine(count);
Console.ReadLine();
}
Here's an example that simply writes the content bytes to a File and skips the mime-type checking:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using Rally.RestApi;
using Rally.RestApi.Response;
namespace RestExample_DownloadAttachment
{
class Program
{
static void Main(string[] args)
{
//Initialize the REST API
RallyRestApi restApi;
// Rally parameters
String userName = "[email protected]";
String userPassword = "topsecret";
String rallyURL = "https://rally1.rallydev.com";
String wsapiVersion = "1.43";
restApi = new RallyRestApi(
userName,
userPassword,
rallyURL,
wsapiVersion
);
//Set our Workspace and Project scopings
String workspaceRef = "/workspace/12345678910";
String projectRef = "/project/12345678911";
bool projectScopingUp = false;
bool projectScopingDown = true;
// Find User Story that we want to pull attachment from
// Tee up Story Request
Request storyRequest = new Request("hierarchicalrequirement");
storyRequest.Workspace = workspaceRef;
storyRequest.Project = projectRef;
storyRequest.ProjectScopeDown = projectScopingDown;
storyRequest.ProjectScopeUp = projectScopingUp;
// Fields to Fetch
storyRequest.Fetch = new List<string>()
{
"Name",
"FormattedID",
"Attachments"
};
// Add a query
storyRequest.Query = new Query("FormattedID", Query.Operator.Equals, "US163");
// Query Rally for the Story
QueryResult queryResult = restApi.Query(storyRequest);
// Pull reference off of Story fetch
DynamicJsonObject storyObject = queryResult.Results.First();
String storyReference = storyObject["_ref"];
Console.WriteLine("Looking for attachments off of Story: " + storyReference);
// Grab the Attachments collection
var storyAttachments = storyObject["Attachments"];
// Let's download the first attachment for starters
var myAttachmentFromStory = storyAttachments[0];
// Pull the ref
String myAttachmentRef = myAttachmentFromStory["_ref"];
Console.WriteLine("Found Attachment: " + myAttachmentRef);
// Fetch fields for the Attachment
string[] attachmentFetch = { "ObjectID", "Name", "Content", "ContentType", "Size"};
// Now query for the attachment
DynamicJsonObject attachmentObject = restApi.GetByReference(myAttachmentRef, "true");
// Grab the AttachmentContent
DynamicJsonObject attachmentContentFromAttachment = attachmentObject["Content"];
String attachmentContentRef = attachmentContentFromAttachment["_ref"];
// Lastly pull the content
// Fetch fields for the Attachment
string[] attachmentContentFetch = { "ObjectID", "Content" };
// Now query for the attachment
Console.WriteLine("Querying for Content...");
DynamicJsonObject attachmentContentObject = restApi.GetByReference(attachmentContentRef, "true");
Console.WriteLine("AttachmentContent: " + attachmentObject["_ref"]);
String base64EncodedContent = attachmentContentObject["Content"];
// File information
String attachmentSavePath = "C:\\Users\\username\\";
String attachmentFileName = attachmentObject["Name"];
String fullAttachmentFile = attachmentSavePath + attachmentFileName;
// Determine attachment Content mime-type
String attachmentContentType = attachmentObject["ContentType"];
try {
// Output base64 content to File
Console.WriteLine("Saving base64 AttachmentContent String to File.");
File.WriteAllBytes(@fullAttachmentFile, Convert.FromBase64String(base64EncodedContent));
}
catch (Exception e)
{
Console.WriteLine("Unhandled exception occurred while writing file: " + e.StackTrace);
Console.WriteLine(e.Message);
}
Console.ReadKey();
}
}
}