2

我正在编写的脚本的最终目标是下载所有附件。我能够成功连接到服务器,对工作区中的所有附件发出请求,最后,遍历以检索每个附件的内容。这会产生“AttachmentContent”的 dynamicJsonObject。作为任何 API 以及 C# 和 .NET 的新手,我现在陷入困境。我想不出一种方法来访问该对象的内容并将其下载到我计算机上的文件中。我在下面评论的那一行是我目前遇到错误并被卡住的地方。任何帮助将不胜感激。先感谢您!

PS这是我的主要方法:

static void Main(string[] args)
    {
        RallyRestApi restApi = new RallyRestApi("user@company.com", "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();
    }
4

3 回答 3

2

这是一个简单地将内容字节写入文件并跳过 mime 类型检查的示例:

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 = "user@company.com";
            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();
        }
    }
}
于 2013-06-24T21:16:46.373 回答
2

以下是一个简要示例,说明下载附件内容的过程。它的类型处理仅限于几种常见的图像类型,但它说明了这个想法:

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 = "user@company.com";
            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, "US43");

            // 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"];

            // Specify Image format
            System.Drawing.Imaging.ImageFormat attachmentImageFormat;

            try
            {
                attachmentImageFormat = getImageFormat(attachmentContentType);
            }
            catch (System.ArgumentException e)
            {
                Console.WriteLine("Invalid attachment file format:" + e.StackTrace);
                Console.WriteLine("Don't know how to handle: " + attachmentContentType);
                return;
            }

            try {

                // Convert base64 content to Image
                Console.WriteLine("Converting base64 AttachmentContent String to Image.");

                // Convert Base64 string to bytes
                byte[] bytes = Convert.FromBase64String(base64EncodedContent);

                Image myAttachmentImage;
                using (MemoryStream ms = new MemoryStream(bytes))
                {
                    myAttachmentImage = Image.FromStream(ms);
                    // Save the image
                    Console.WriteLine("Saving Image: " + fullAttachmentFile);
                    myAttachmentImage.Save(fullAttachmentFile, System.Drawing.Imaging.ImageFormat.Jpeg);

                    Console.WriteLine("Finished Saving Attachment: " + fullAttachmentFile);
                }

            }
            catch (Exception e)
            {
                Console.WriteLine("Unhandled exception occurred: " + e.StackTrace);
                Console.WriteLine(e.Message);
            }

            Console.ReadKey();
        }

        // Returns an ImageFormat type based on Rally contentType / mime-type
        public static System.Drawing.Imaging.ImageFormat getImageFormat(String contentType)
        {
            // Save Image format
            System.Drawing.Imaging.ImageFormat attachmentImageFormat;

            switch (contentType)
            {
                case "image/png":
                    attachmentImageFormat = System.Drawing.Imaging.ImageFormat.Png;
                    break;
                case "image/jpeg":
                    attachmentImageFormat = System.Drawing.Imaging.ImageFormat.Jpeg;
                    break;
                case "image/tiff":
                    attachmentImageFormat = System.Drawing.Imaging.ImageFormat.Tiff;
                    break;
                default:
                    Console.WriteLine("Invalid image file format.");
                    throw new System.ArgumentException("Invalid attachment file format.");
            };

            return attachmentImageFormat;
        }
    }
}
于 2013-06-24T14:12:08.533 回答
1

这是来自 user984832 的相同示例,但经过修改以使用 WS API 的 v2.0 和.NET 的 Rally REST 工具包的2.0.1 dll 。

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 DownloadAttachment
{
    class Program
    {
        static void Main(string[] args)
        {
            RallyRestApi restApi;

            String userName = "user@co.com";
            String userPassword = "secret";

            String rallyURL = "https://rally1.rallydev.com";
            String wsapiVersion = "v2.0";

            restApi = new RallyRestApi(
                userName,
                userPassword,
                rallyURL,
                wsapiVersion
            );

            String workspaceRef = "/workspace/12352608129";
            String projectRef = "/project/12352608219";
            bool projectScopingUp = false;
            bool projectScopingDown = true;

            Request storyRequest = new Request("hierarchicalrequirement");
            storyRequest.Workspace = workspaceRef;
            storyRequest.Project = projectRef;
            storyRequest.ProjectScopeDown = projectScopingDown;
            storyRequest.ProjectScopeUp = projectScopingUp;

            storyRequest.Fetch = new List<string>()
                {
                    "Name",
                    "FormattedID",
                    "Attachments"
                };

            storyRequest.Query = new Query("FormattedID", Query.Operator.Equals, "US20");
            QueryResult queryResult = restApi.Query(storyRequest);
            DynamicJsonObject story = queryResult.Results.First();

            // Grab the Attachments collection
            Request attachmentsRequest = new Request(story["Attachments"]);
            QueryResult attachmentsResult = restApi.Query(attachmentsRequest);

            //Download the first attachment

            var myAttachmentFromStory = attachmentsResult.Results.First();
            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\\nmusaelian\\NewFolder";
            String attachmentFileName = attachmentObject["Name"];
            String fullAttachmentFile = attachmentSavePath + attachmentFileName;

            // Determine attachment Content mime-type
            String attachmentContentType = attachmentObject["ContentType"];

            // Specify Image format
            System.Drawing.Imaging.ImageFormat attachmentImageFormat;

            try
            {
                attachmentImageFormat = getImageFormat(attachmentContentType);
            }
            catch (System.ArgumentException e)
            {
                Console.WriteLine("Invalid attachment file format:" + e.StackTrace);
            }

            try
            {

                // Convert base64 content to Image
                Console.WriteLine("Converting base64 AttachmentContent String to Image.");

                // Convert Base64 string to bytes
                byte[] bytes = Convert.FromBase64String(base64EncodedContent);

                Image myAttachmentImage;
                using (MemoryStream ms = new MemoryStream(bytes))
                {
                    myAttachmentImage = Image.FromStream(ms);
                    // Save the image
                    Console.WriteLine("Saving Image: " + fullAttachmentFile);
                    myAttachmentImage.Save(fullAttachmentFile, System.Drawing.Imaging.ImageFormat.Jpeg);

                    Console.WriteLine("Finished Saving Attachment: " + fullAttachmentFile);
                }

            }
            catch (Exception e)
            {
                Console.WriteLine("Unhandled exception occurred: " + e.StackTrace);
                Console.WriteLine(e.Message);
            }

            Console.ReadKey();
        }

        // Returns an ImageFormat type based on Rally contentType / mime-type
        public static System.Drawing.Imaging.ImageFormat getImageFormat(String contentType)
        {
            // Save Image format
            System.Drawing.Imaging.ImageFormat attachmentImageFormat;

            switch (contentType)
            {
                case "image/png":
                    attachmentImageFormat = System.Drawing.Imaging.ImageFormat.Png;
                    break;
                case "image/jpeg":
                    attachmentImageFormat = System.Drawing.Imaging.ImageFormat.Jpeg;
                    break;
                case "image/tiff":
                    attachmentImageFormat = System.Drawing.Imaging.ImageFormat.Tiff;
                    break;
                default:
                    Console.WriteLine("Invalid image file format.");
                    throw new System.ArgumentException("Invalid attachment file format.");
            };

            return attachmentImageFormat;
        }
    }
}
于 2014-11-06T16:49:13.900 回答