使用C#和.NET从集会下载附件

本文关键字:下载 NET 使用 | 更新日期: 2023-09-27 18:19:50

我编写的脚本的最终目标是从rally下载所有附件。我能够成功地连接到服务器,请求工作区中的所有附件,最后,迭代以检索每个附件的内容。这将产生一个"AttachmentContent"的dynamicJsonObject。作为API以及C#和.NET的新手,我现在陷入了困境。我无法找到访问此对象的内容并将其下载到计算机上的文件的方法。我在下面评论的这一行是我目前遇到错误并陷入困境的地方。如有任何帮助,我们将不胜感激。提前谢谢!

附言:这是我的主要方法:

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();
    }

使用C#和.NET从集会下载附件

以下是一个简单地将内容字节写入文件并跳过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();
        }
    }
}

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

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;
        }
    }
}

这是用户984832中的相同示例,但已修改为与WS-neneneba 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;
        }
    }
}