如何使用 Rally REST .NET 将附件添加到用户故事

2023-12-10

我们正在将 .NET Rally 代码从 SOAP 移植到 REST .NET API。到目前为止,REST API 似乎更快并且更易于使用,因为每次工作产品自定义字段在 Rally 工作区中发生更改时都不会破坏 WSDL。

不过,当我们尝试复制上传附件的功能时,我遇到了一件事。我们正在遵循与这篇文章中概述的非常相似的程序:

Rally SOAP API - 如何向分层需求添加附件

由此图像被读入 System.Drawing.Image。我们使用 ImageToByteArray 函数将图像转换为字节数组,然后将其分配给首先创建的 AttachmentContent。

然后,创建附件,并将其连接到 AttachmentContent 和 HierarchicalRequirement。

所有的创作活动都进展顺利。内容对象创建得很好。然后,将创建名为“Image.png”的新附件并将其链接到故事。但是当我从 Rally 下载生成的附件时,Image.png 的字节为零!我已经用不同的图像、JPEG、PNG 等进行了尝试,结果都相同。

下面是显示我们流程的代码摘录。我是否缺少一些明显的东西?提前致谢。

    // .... Read content into a System.Drawing.Image called imageObject ....

    // Convert Image to byte array
    byte[] imageBytes = ImageToByteArray(imageObject, System.Drawing.Imaging.ImageFormat.Png);
    var imageLength = imageBytes.Length;

    // AttachmentContent
    DynamicJsonObject attachmentContent = new DynamicJsonObject();
    attachmentContent["Content"] = imageBytes ;

    CreateResult cr = restApi.Create("AttachmentContent", myAttachmentContent);
    String contentRef = cr.Reference;
    Console.WriteLine("Created: " + contentRef);

    // Set up attachment
    DynamicJsonObject newAttachment = new DynamicJsonObject();
    newAttachment["Artifact"] = story;
    newAttachment["Content"] = attachmentContent;
    newAttachment["Name"] = "Image.png";
    newAttachment["ContentType"] = "image/png";
    newAttachment["Size"] = imageLength;
    newAttachment["User"] = user;


    // Create the attachment in Rally
    cr = restApi.Create("Attachment", newAttachment);

    String attachRef = cr.Reference;
    Console.WriteLine("Created: " + attachRef);

}

public static byte[] ImageToByteArray(Image image, System.Drawing.Imaging.ImageFormat format)
{
    using (MemoryStream ms = new MemoryStream())
    {
        image.Save(ms, format);

        // Convert Image to byte[]                
        byte[] imageBytes = ms.ToArray();
        return imageBytes;
    }
}

这个问题也让我困惑了一段时间——大约一周前终于解决了。

两个观察结果:

  1. 虽然 Rally 的 SOAP API 会在后台将字节数组序列化为 Base64 字符串,但 REST 不会为您执行此步骤,并且会期望将 Base64 格式的字符串作为 AttachmentContent 对象的 Content 属性传递。
  2. 示例中所示的 System.Drawing.Image.Length 不会提供 Rally 的 WSAPI 期望的正确长度。您需要在转换回常规字符串后传递 Base64 格式字符串的长度。这也与字节数组的长度相同。

我提供了一个代码示例来说明:

// System Libraries
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing.Imaging;
using System.Drawing;
using System.IO;
using System.Web;

// Rally REST API Libraries
using Rally.RestApi;
using Rally.RestApi.Response;

namespace RestExample_CreateAttachment
{
    class Program
    {
        static void Main(string[] args)
        {
            // Set user parameters
            String userName = "[email protected]";
            String userPassword = "password";

            // Set Rally parameters
            String rallyURL = "https://rally1.rallydev.com";
            String rallyWSAPIVersion = "1.36";

            //Initialize the REST API
            RallyRestApi restApi;
            restApi = new RallyRestApi(userName,
                                       userPassword,
                                       rallyURL,
                                       rallyWSAPIVersion);

            // Create Request for User
            Request userRequest = new Request("user");
            userRequest.Fetch = new List<string>()
                {
                    "UserName",
                    "Subscription",
                    "DisplayName",
                };

            // Add a Query to the Request
            userRequest.Query = new Query("UserName",Query.Operator.Equals,userName);

            // Query Rally
            QueryResult queryUserResults = restApi.Query(userRequest);

            // Grab resulting User object and Ref
            DynamicJsonObject myUser = new DynamicJsonObject();
            myUser = queryUserResults.Results.First();
            String myUserRef = myUser["_ref"];

            //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 add attachment to

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

            // 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
            var storyObject = queryResult.Results.First();
            String storyReference = storyObject["_ref"];

            // Read In Image Content
            String imageFilePath = "C:\\Users\\username\\";
            String imageFileName = "image1.png";
            String fullImageFile = imageFilePath + imageFileName;
            Image myImage = Image.FromFile(fullImageFile);

            // Get length from Image.Length attribute - don't use this in REST though
            // REST expects the length of the image in number of bytes as converted to a byte array
            var imageFileLength = new FileInfo(fullImageFile).Length;
            Console.WriteLine("Image File Length from System.Drawing.Image: " + imageFileLength);

            // Convert Image to Base64 format
            string imageBase64String = ImageToBase64(myImage, System.Drawing.Imaging.ImageFormat.Png);           

            // Length calculated from Base64String converted back
            var imageNumberBytes = Convert.FromBase64String(imageBase64String).Length;

            // This differs from just the Length of the Base 64 String!
            Console.WriteLine("Image File Length from Convert.FromBase64String: " + imageNumberBytes);

            // DynamicJSONObject for AttachmentContent
            DynamicJsonObject myAttachmentContent = new DynamicJsonObject();
            myAttachmentContent["Content"] = imageBase64String;

            try
            {
                CreateResult myAttachmentContentCreateResult = restApi.Create("AttachmentContent", myAttachmentContent);
                String myAttachmentContentRef = myAttachmentContentCreateResult.Reference;
                Console.WriteLine("Created: " + myAttachmentContentRef);

                // DynamicJSONObject for Attachment Container
                DynamicJsonObject myAttachment = new DynamicJsonObject();
                myAttachment["Artifact"] = storyReference;
                myAttachment["Content"] = myAttachmentContentRef;
                myAttachment["Name"] = "AttachmentFromREST.png";
                myAttachment["Description"] = "Attachment Desc";
                myAttachment["ContentType"] = "image/png";
                myAttachment["Size"] = imageNumberBytes;
                myAttachment["User"] = myUserRef;

                CreateResult myAttachmentCreateResult = restApi.Create("Attachment", myAttachment);

                List<string> createErrors = myAttachmentContentCreateResult.Errors;
                for (int i = 0; i < createErrors.Count; i++)
                {
                    Console.WriteLine(createErrors[i]);
                }

                String myAttachmentRef = myAttachmentCreateResult.Reference;
                Console.WriteLine("Created: " + myAttachmentRef);

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

        // Converts image to Base 64 Encoded string
        public static string ImageToBase64(Image image, System.Drawing.Imaging.ImageFormat format)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                image.Save(ms, format);
                // Convert Image to byte[]                
                byte[] imageBytes = ms.ToArray();

                // Convert byte[] to Base64 String
                string base64String = Convert.ToBase64String(imageBytes);

                return base64String;
            }
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Rally REST .NET 将附件添加到用户故事 的相关文章

  • 提交后禁用按钮

    当用户提交付款表单并且发布表单的代码导致 Firefox 中出现重复发布时 我试图禁用按钮 去掉代码就不会出现这个问题 在firefox以外的任何浏览器中也不会出现这个问题 知道如何防止双重帖子吗 System Text StringBui
  • 在 DataView 的 RowFilter 中选择 DISTINCT

    我试图根据与另一个表的关系缩小 DataView 中的行范围 我使用的 RowFilter 如下 dv new DataView myDS myTable id IN SELECT DISTINCT parentID FROM myOthe
  • 错误:表达式不产生值

    我尝试将以下 C 代码转换为 VB NET 但在编译代码时出现 表达式不产生值 错误 C Code return Fluently Configure Mappings m gt m FluentMappings AddFromAssemb
  • 使用 LINQ2SQL 在 ASP.NET MVC 中的各种模型存储库之间共享数据上下文

    我的应用程序中有 2 个存储库 每个存储库都有自己的数据上下文对象 最终结果是我尝试将从一个存储库检索到的对象附加到从另一个存储库检索到的对象 这会导致异常 Use 构造函数注入将 DataContext 注入每个存储库 public cl
  • 如何创建包含 IPv4 地址的文本框? [复制]

    这个问题在这里已经有答案了 如何制作一个这样的文本框 我想所有的用户都见过这个并且知道它的功能 您可以使用带有 Mask 的 MaskedTestBox000 000 000 000 欲了解更多信息 请参阅文档 http msdn micr
  • 将 Word 文档另存为图像

    我正在使用下面的代码将 Word 文档转换为图像文件 但是图片显得太大 内容不适合 有没有办法渲染图片或将图片保存到合适的尺寸 private void btnConvert Click object sender EventArgs e
  • 在 C 中初始化变量

    我知道有时如果你不初始化int 如果打印整数 您将得到一个随机数 但将所有内容初始化为零似乎有点愚蠢 我问这个问题是因为我正在评论我的 C 项目 而且我对缩进非常直接 并且它可以完全编译 90 90 谢谢 Stackoverflow 但我想
  • qdbusxml2cpp 未知类型

    在使用 qdbusxml2cpp 程序将以下 xml 转换为 Qt 类时 我收到此错误 qdbusxml2cpp c ObjectManager a ObjectManager ObjectManager cpp xml object ma
  • 是否有实用的理由使用“if (0 == p)”而不是“if (!p)”?

    我倾向于使用逻辑非运算符来编写 if 语句 if p some code 我周围的一些人倾向于使用显式比较 因此代码如下所示 if FOO p some code 其中 FOO 是其中之一false FALSE 0 0 0 NULL etc
  • 如何在 Xaml 文本中添加电子邮件链接?

    我在 Windows Phone 8 应用程序中有一些大文本 我希望其中有电子邮件链接 例如 mailto 功能 这是代码的一部分
  • Azure 辅助角色“请求输入之一超出范围”的内部异常。

    我在辅助角色中调用 CloudTableClient CreateTableIfNotExist 方法 但收到一个异常 其中包含 请求输入之一超出范围 的内部异常 我做了一些研究 发现这是由于将表命名为非法表名引起的 但是 我尝试为我的表命
  • 如何禁用 fread() 中的缓冲?

    我正在使用 fread 和 fwrite 读取和写入套接字 我相信这些函数用于缓冲输入和输出 有什么方法可以在仍然使用这些功能的同时禁用缓冲吗 Edit 我正在构建一个远程桌面应用程序 远程客户端似乎 落后于服务器 我不知道可能是什么原因
  • 如何在 Laravel 中使用 PUT http 动词提交表单

    我知道这个问题可能已经提出 但我就是无法让它发挥作用 如果有人可以帮助我 我将非常感激 我安装了 colletive form 但答案也可以是 html 表单标签 现在列出我的表格 我的路线和我的例外情况 Form model array
  • 动态添加 ASP.Net 控件

    我有一个存储过程 它根据数据库中存储的记录数返回多行 现在我想有一种方法来创建 div 带有包含该行值的控件的标记 如果从数据库返回 10 行 则 10 div 必须创建标签 我有下面的代码来从数据库中获取结果 但我不知道如何从这里继续 S
  • 将 MQTTNet 服务器与 MQTT.js 客户端结合使用

    我已经启动了一个 MQTT 服务器 就像this https github com chkr1011 MQTTnet tree master例子 该代码托管在 ASP Net Core 2 0 应用程序中 但我尝试过控制台应用程序 但没有成
  • 如何在非控制台应用程序中查看 cout 输出?

    输出到调试窗口似乎相当繁琐 我在哪里可以找到cout如果我正在编写非控制台信息 则输出 Like double i a b cout lt lt b lt lt endl I want to check out whether b is z
  • 使用 %d 打印 unsigned long long

    为什么我打印以下内容时得到 1 unsigned long long int largestIntegerInC 18446744073709551615LL printf largestIntegerInC d n largestInte
  • 如果没有抽象成员,基类是否应该标记为抽象?

    如果一个类没有抽象成员 可以将其标记为抽象吗 即使没有实际理由直接实例化它 除了单元测试 是的 将不应该实例化的基类显式标记为抽象是合理且有益的 即使在没有抽象方法的情况下也是如此 它强制执行通用准则来使非叶类抽象 它阻止其他程序员创建该类
  • 如何部署“SQL Server Express + EF”应用程序

    这是我第一次部署使用 SQL Server Express 数据库的应用程序 我首先使用实体 框架模型来联系数据库 我使用 Install Shield 创建了一个安装向导来安装应用程序 这些是我在目标计算机中安装应用程序所执行的步骤 安装
  • WebSocket安全连接自签名证书

    目标是一个与用户电脑上安装的 C 应用程序交换信息的 Web 应用程序 客户端应用程序是 websocket 服务器 浏览器是 websocket 客户端 最后 用户浏览器中的 websocket 客户端通过 Angular 持久创建 并且

随机推荐

  • 如何在 Windows 上仅在批处理文件中设置一次 PATH 环境变量?

    我有一个设置用户路径的批处理文件 并作为 Visual Studio IDE 构建步骤的一部分运行 ECHO OFF ECHO PATH set COMSPEC VCINSTALLDIR vcvarsall bat amd64 setx P
  • pyclipper 安装错误:“tp_print 不是 _typeobject 的成员”

    我正在尝试安装 pyclipper 以与 nototools 一起使用 https github com googlefonts nototools但我无法安装 pyclipper 我认为 Visual Studio 构建工具有一些东西 C
  • NSMutableArray-removeObject 结果删除对象和 nil 元素

    首先 我是 Objective C 的新手 我的班级 Song 有一对属性 在我的主类中 我有一个变量 allSongs 它是一个 NSMutableArray 在这个数组中我添加了所有歌曲对象 我的问题出现在尝试调用 self allSo
  • 使用委托、操作和队列

    我正在使用AWS SDK用于 iOS 将文件上传到本地硬盘到 Amazon S3 存储以及从本地硬盘下载文件 我有能力完成这项工作 但我无法让 S3 委托做出正确响应 以便在操作完成或导致错误时提醒我 我有一系列要上传的文件 对于每个文件
  • 在 R (ggplot) 中注释公式(使用 bqoute 或替代)给出错误

    我想添加一个包含变量的公式作为我的 ggplot 上的注释 regline1 lt 0 00 slope1 lt 1 00 dat lt as data frame c 0 1 dat 2 lt c 0 1 names dat lt c f
  • 如何将 /Home 301 重定向到 root?

    这是我在 Global asax 中删除 Home 的路线 routes MapRoute Root action id new controller Home action Index id UrlParameter Optional 好
  • 如何通过降低特征维数来改进LBP算子

    我在用LBP用MATLAB提取特征但精度太低 如何减少LBP中的特征箱 非常感谢 Use the pcares函数来做到这一点 pcares代表主成分分析残差 residuals reconstructed pcares X ndim re
  • 无法使用 Bottomnavigationview 正确加载片段

    我已经遵循了下面的教程 但我一生都无法让它从收藏夹片段 底部导航视图上的中间图标 开始加载 我已经尝试了一切并到处寻找 我的应用程序将始终加载最喜欢的文本 但底部导航视图将始终突出显示主页图标 直到我选择一个图标 如何解决此问题 让应用程序
  • 对一组值进行排序

    我有这样的价值观 x set 0 000000000 0 009518000 10 277200999 0 030810999 0 018384000 4 918560000 y set 4 918859000 0 060758000 4
  • 如何使用 PHP 将 mysql 转换为 sqlite3

    我在 mysql 服务器上有一个数据库 我想将其转换为 sqlite3 数据库without使用 shell 或 perl 脚本 我需要一些使用 PHP 转换相同内容的帮助 任何帮助 将不胜感激 仅使用 PHP 会相当麻烦 您必须从 mys
  • 将带有位置、颜色等的 networkx 图写入 gexf

    我使用 networkx 构建了一个图表 并使用 spring 布局函数生成了一个漂亮的图 不幸的是 这没有传输到 gexf 文件 我认为networkx工具的重点是能够编写可读的图形文件 所以如果python中有一个简单的解决方案 我会犹
  • 无法在 CentOS 7 上安装 mpi4py

    我有 CentOS 7 并且已经安装了 mpicc 它可以在 C 语言中为 openmpi 工作和编译 我也有 python 2 7 5 并且刚刚安装了 pip 我正在运行此命令并收到以下错误 sudo pip install mpi4py
  • RestKit 核心数据 NSError dealloc 崩溃

    试图找出我在生产版本中看到的问题的根源 并最终能够在测试时重现它 使用 RestKit v0 23 1 当使用以下代码 插入仪器时 执行 RKManagedObjectRequestOperation 时 我收到 一条 Objective
  • 如何用C语言解析HTTP响应?

    我正在编写一个小项目 它使用 HTTP 1 1 GET 和 POST 与一组服务器进行交互 服务器在一些标题行后给了我响应 所以我想使用strtok 函数使用 n作为分隔符 但每当我尝试这样做时就会发生崩溃 有没有简单的方法可以用 C 语言
  • Android:无法在防火墙后面发出 httprequest

    当没有防火墙时 标准 getUrlContent 可以很好地工作 但当我尝试在防火墙后面执行此操作时 我遇到了例外 我尝试在 AVD 管理器中设置 http 代理服务器 但没有成功 知道如何正确设置它吗 顺便说一句 来自 android 文
  • 浮动比较给出不同的结果

    看下面两个代码 告诉我答案差异很大的原因 include
  • 将 cumsum 应用于二元向量

    我有一个简单的二元向量a我尝试将其转换为向量b使用 R 函数cumsum 然而 cumsum不完全返回向量b 这是一个例子 a lt c 1 0 0 0 1 1 1 1 0 0 1 0 0 0 1 1 b lt c 1 2 2 2 3 4
  • 在 Asp.net MVC 网站中生成 Excel XML 文档

    我有一个 ASP Net MVC 站点 可以生成 Microsoft Excel 2003 XML 格式的电子表格 电子表格看起来不错 控制器和视图都可以工作 但文件无法在 Excel 中打开 它在浏览器中打开 因为它是 XML 文档 我尝
  • 我在 Android studio 中找不到“图像资源”选项

    我开始使用 Flutter UI 工具包在 Android Studio 中学习应用程序开发 一切看起来都很好 但是当我想创建一个新图像资源要编辑我的应用程序的图标 我找不到它 当我右键单击安卓 应用程序 src main res文件夹 它
  • 如何使用 Rally REST .NET 将附件添加到用户故事

    我们正在将 NET Rally 代码从 SOAP 移植到 REST NET API 到目前为止 REST API 似乎更快并且更易于使用 因为每次工作产品自定义字段在 Rally 工作区中发生更改时都不会破坏 WSDL 不过 当我们尝试复制