未加星标

Azure DevOps API, Embed images into html

字体大小 | |
[系统(windows) 所属分类 系统(windows) | 发布者 店小二05 | 时间 2019 | 作者 红领巾 ] 0人收藏点击收藏

Post in the series:

1) APIConnection

2) Retrieve Work Items Information

Before going to generate a Word File from Work Item Data we need to solve a little problem with HTML content in Work Item fields. As you know Azure DevOps has a rich web editor that allows you to create complex text in some fields, like Description, the problem is: whenever you copy and paste images inside the Web Editor, those images were added as Work Item attachments and the real HTML content is just a reference to the attachmen Url. If you want to generate a consistent Word or export to whatever destination you want, you should manipulate html to embed the image, or the html will be not consistent.

Focus of this article will be: how I can download attachment of Work Items and how I can embed image attachment directly in HTML code.

Html content in Work Item support images, but images are usually a reference to attachment of the Work Item itself, thus it is not consistent because it refers protected resources.

Here is an example, I have a work item, I embedded an image in the description and the HTML content of System.Description field is an <img> tag with this src value: https://gianmariaricci.visualstudio.com/3a600197-fa66-4389-aebd-620186063db0/_apis/wit/attachments?FileID=481805&amp;FileName=System.Description.0.png . Actually this could be seen as a no-problem, because if you copy this url into a browser the image will be correctly downloaded, but the problem rely in authentication. If you are going to embed this HTML into a Word Document no one will be able to visualize the image, because word is not authenticated to Azure DevOps, thus you need to download locally and embed into the html document.

A possible approach is reference the HtmlAgilityToolkit library, then build a routine that programmatically download every attachment, and finally embeds the image in src attribute value using Base64 encoding, here is the code.

public static String EmbedHtmlContent(this WorkItem workItem, String htmlContent) { HtmlDocument doc = new HtmlDocument(); doc.LoadHtml(htmlContent); var images = doc.DocumentNode.SelectNodes("//img"); if (images != null) { foreach (var image in images) { //need to understand if it is in base 64 or no, if the answer is no, we need to embed image var src = image.GetAttributeValue("src", ""); if (!String.IsNullOrEmpty(src)) { if (src.Contains("base64")) // data:image/jpeg;base64, { //image already embedded Log.Debug("found image in html content that was already in base64"); } else { Log.Debug("found image in html content that point to external image {src}", src); //is it a internal attached images? var match = Regex.Match(src, @"FileID=(?\d*)"); if (match.Success) { var attachment = workItem.Attachments .OfType() .FirstOrDefault(_ => _.Id.ToString() == match.Groups["id"].Value); if (attachment != null) { //ok we can embed in the image as base64 WorkItemServer wise = workItem.Store.TeamProjectCollection.GetService(); var downloadedAttachment = wise.DownloadFile(attachment.Id); byte[] byteContent = File.ReadAllBytes(downloadedAttachment); String base64Encoded = Convert.ToBase64String(byteContent); var newSrcValue = $"data:image/{attachment.Extension.Trim('.')};base64,{base64Encoded}"; image.SetAttributeValue("src", newSrcValue); } } } } } } return doc.DocumentNode.OuterHtml; }

This code is really simple, it is an extension method of the WorkItem type so you can simply use whenever you have a reference to a Work Item. The code will simply search in all HTML text img tags, for each img tag it will verify if it already contains string base64 (because the image could be already embedded), if the answer is no, we need to download the image locally and embed.

If you look at the attachment url you can notice a FileID=xxxx that points to the attachment of the work item. With a simple regex I can find if the url conform to this pattern, and if the answer is yes, I’ll search into WorkItem.Attachments collection for the right attachment .

Work Item object in C# library has a nice Attachments collection that allows you to iterate through all attachments to find any information you need

Having a reference to the Attachment is crucial, because I need to know the extension of the file.Once the attachment object is found, I can use Store property of the work item to grab a reference to the TfsTeamProjectCollection object that allows me to grab a reference to the WorkItemServer object, that is needed to download the file locally. Thanks to C# object model, if I have a simple reference to a Work Item I can still traverse properties to grab a reference to the original collection object that was still authenticated to the server.

Using Store property of Work Item allows you to access the original Collection object that is authenticated to the server, thus you can ignore authentication problems

Once I have a reference to WorkItemServer, its method DownloadFile will simply download attachment by id to a temp local file, then a simple conversion to Base64 will perform the trick. The result is a src attribute that embed the image.


Azure DevOps API, Embed images into html

Figure 1: Src attribute with image embedded

Now I can simply change the attribute of the image thanks to HtmlAgilityToolkit library, and finally return modified HTML to the caller.

Now I have html code that embed all images and has no reference to external resources in Azure DevOps, so I can embed it everywhere I want without any problem.

Gian Maria.

本文系统(windows)相关术语:三级网络技术 计算机三级网络技术 网络技术基础 计算机网络技术

代码区博客精选文章
分页:12
转载请注明
本文标题:Azure DevOps API, Embed images into html
本站链接:https://www.codesec.net/view/628210.html


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 系统(windows) | 评论(0) | 阅读(128)