From bbb3e2096860ad7a24421fba0a1fc54e3bacff2c Mon Sep 17 00:00:00 2001 From: Randy Date: Wed, 26 Jul 2017 22:03:27 -0500 Subject: [PATCH 1/3] Issue #30: SaveAttachment sets the Attachment Filename to the Full Path of the File Added an optional argument to the SaveAttachment method: useAbsolutePathAsFileName = true --- APIClient.IntegrationTests/IntegrationTests.cs | 2 +- APIClient/Services/IServices.cs | 3 ++- APIClient/Services/Services.cs | 5 ++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/APIClient.IntegrationTests/IntegrationTests.cs b/APIClient.IntegrationTests/IntegrationTests.cs index 0922ffd..beea38a 100644 --- a/APIClient.IntegrationTests/IntegrationTests.cs +++ b/APIClient.IntegrationTests/IntegrationTests.cs @@ -426,7 +426,7 @@ public void CreateDefectWithAttachment() newDefect.SetAttributeValue(nameAttribute, name); services.Save(newDefect); - services.SaveAttachment(file, newDefect, "Test Attachment on " + newDefect.Oid); + services.SaveAttachment(file, newDefect, "Test Attachment on " + newDefect.Oid, false); var query = new Query(newDefect.Oid.Momentless); query.Selection.Add(attachmentsAttribute); diff --git a/APIClient/Services/IServices.cs b/APIClient/Services/IServices.cs index fafdcb4..c5f093a 100644 --- a/APIClient/Services/IServices.cs +++ b/APIClient/Services/IServices.cs @@ -32,8 +32,9 @@ public interface IServices /// Path and name of the attachment file. /// Asset to save the attachment to. /// The name of the attachment. + /// Option to use the Ansolute Path as the FileName. Defaults to true. /// Oid - Oid SaveAttachment(string filePath, Asset asset, string attachmentName); + Oid SaveAttachment(string filePath, Asset asset, string attachmentName, bool useAbsolutePathAsFileName = true); /// /// Saves an embedded image to the specified asset. diff --git a/APIClient/Services/Services.cs b/APIClient/Services/Services.cs index fbbf536..0b65837 100644 --- a/APIClient/Services/Services.cs +++ b/APIClient/Services/Services.cs @@ -375,13 +375,16 @@ public string ExecutePassThroughQuery(string query) return _v1Connector.StringSendData(data: query, contentType: "application/json"); } - public Oid SaveAttachment(string filePath, Asset asset, string attachmentName) + public Oid SaveAttachment(string filePath, Asset asset, string attachmentName, bool useAbsolutePathAsFileName = true) { if (string.IsNullOrWhiteSpace(filePath)) throw new ArgumentNullException("filePath"); if (!File.Exists(filePath)) throw new APIException(string.Format("File \"{0}\" does not exist.", filePath)); + if (!useAbsolutePathAsFileName) + filePath = Path.GetFileName(filePath); + var mimeType = MimeType.Resolve(filePath); IAssetType attachmentType = Meta.GetAssetType("Attachment"); IAttributeDefinition attachmentAssetDef = attachmentType.GetAttributeDefinition("Asset"); From 34cde346e03145e8b0091b764439ff4396989bbb Mon Sep 17 00:00:00 2001 From: Randy Date: Thu, 27 Jul 2017 21:50:32 -0500 Subject: [PATCH 2/3] Swapped Optional Argument to an Overload Used spazmodius's adviceto avoid breaking the interface. Also fixed my mistake that caused the Mime type to be always be se to the same value. --- .../IntegrationTests.cs | 2 +- APIClient/Services/IServices.cs | 13 +++- APIClient/Services/Services.cs | 64 +++++++++++++++++-- 3 files changed, 72 insertions(+), 7 deletions(-) diff --git a/APIClient.IntegrationTests/IntegrationTests.cs b/APIClient.IntegrationTests/IntegrationTests.cs index beea38a..983876c 100644 --- a/APIClient.IntegrationTests/IntegrationTests.cs +++ b/APIClient.IntegrationTests/IntegrationTests.cs @@ -426,7 +426,7 @@ public void CreateDefectWithAttachment() newDefect.SetAttributeValue(nameAttribute, name); services.Save(newDefect); - services.SaveAttachment(file, newDefect, "Test Attachment on " + newDefect.Oid, false); + services.SaveAttachment(file, newDefect, "Test Attachment on " + newDefect.Oid, true); var query = new Query(newDefect.Oid.Momentless); query.Selection.Add(attachmentsAttribute); diff --git a/APIClient/Services/IServices.cs b/APIClient/Services/IServices.cs index c5f093a..69628db 100644 --- a/APIClient/Services/IServices.cs +++ b/APIClient/Services/IServices.cs @@ -32,9 +32,18 @@ public interface IServices /// Path and name of the attachment file. /// Asset to save the attachment to. /// The name of the attachment. - /// Option to use the Ansolute Path as the FileName. Defaults to true. /// Oid - Oid SaveAttachment(string filePath, Asset asset, string attachmentName, bool useAbsolutePathAsFileName = true); + Oid SaveAttachment(string filePath, Asset asset, string attachmentName); + + /// + /// Saves an attachment to the specified asset. + /// + /// Path and name of the attachment file. + /// Asset to save the attachment to. + /// The name of the attachment. + /// Sets file name as the file name rather than full path. + /// Oid + Oid SaveAttachment(string filePath, Asset asset, string attachmentName, bool useFileNameAsFileName); /// /// Saves an embedded image to the specified asset. diff --git a/APIClient/Services/Services.cs b/APIClient/Services/Services.cs index 0b65837..9635989 100644 --- a/APIClient/Services/Services.cs +++ b/APIClient/Services/Services.cs @@ -375,16 +375,13 @@ public string ExecutePassThroughQuery(string query) return _v1Connector.StringSendData(data: query, contentType: "application/json"); } - public Oid SaveAttachment(string filePath, Asset asset, string attachmentName, bool useAbsolutePathAsFileName = true) + public Oid SaveAttachment(string filePath, Asset asset, string attachmentName) { if (string.IsNullOrWhiteSpace(filePath)) throw new ArgumentNullException("filePath"); if (!File.Exists(filePath)) throw new APIException(string.Format("File \"{0}\" does not exist.", filePath)); - if (!useAbsolutePathAsFileName) - filePath = Path.GetFileName(filePath); - var mimeType = MimeType.Resolve(filePath); IAssetType attachmentType = Meta.GetAssetType("Attachment"); IAttributeDefinition attachmentAssetDef = attachmentType.GetAttributeDefinition("Asset"); @@ -429,6 +426,65 @@ public Oid SaveAttachment(string filePath, Asset asset, string attachmentName, b return attachment.Oid; } + + public Oid SaveAttachment(string filePath, Asset asset, string attachmentName, bool useFileNameAsFileName) + { + if (string.IsNullOrWhiteSpace(filePath)) + throw new ArgumentNullException("filePath"); + if (!File.Exists(filePath)) + throw new APIException(string.Format("File \"{0}\" does not exist.", filePath)); + + string fileName; + + if (useFileNameAsFileName) + fileName = Path.GetFileName(filePath); + else + fileName = filePath; + + var mimeType = MimeType.Resolve(filePath); + IAssetType attachmentType = Meta.GetAssetType("Attachment"); + IAttributeDefinition attachmentAssetDef = attachmentType.GetAttributeDefinition("Asset"); + IAttributeDefinition attachmentContent = attachmentType.GetAttributeDefinition("Content"); + IAttributeDefinition attachmentContentType = attachmentType.GetAttributeDefinition("ContentType"); + IAttributeDefinition attachmentFileName = attachmentType.GetAttributeDefinition("Filename"); + IAttributeDefinition attachmentNameAttr = attachmentType.GetAttributeDefinition("Name"); + Asset attachment = New(attachmentType, Oid.Null); + attachment.SetAttributeValue(attachmentNameAttr, attachmentName); + attachment.SetAttributeValue(attachmentFileName, fileName); + attachment.SetAttributeValue(attachmentContentType, mimeType); + attachment.SetAttributeValue(attachmentContent, string.Empty); + attachment.SetAttributeValue(attachmentAssetDef, asset.Oid); + Save(attachment); + + string key = attachment.Oid.Key.ToString(); + + using (Stream input = new FileStream(filePath, FileMode.Open, FileAccess.Read)) + { + using (Stream output = _connector != null ? _connector.BeginRequest(key.Substring(key.LastIndexOf('/') + 1)) : _v1Connector.BeginRequest(key.Substring(key.LastIndexOf('/') + 1))) + { + byte[] buffer = new byte[input.Length + 1]; + while (true) + { + int read = input.Read(buffer, 0, buffer.Length); + if (read <= 0) + break; + + output.Write(buffer, 0, read); + } + } + } + if (_connector != null) + { + _connector.EndRequest(key.Substring(key.LastIndexOf('/') + 1), mimeType); + } + else + { + _v1Connector.UseAttachmentApi(); + _v1Connector.EndRequest(key.Substring(key.LastIndexOf('/') + 1), mimeType); + } + + return attachment.Oid; + } public Stream GetAttachment(Oid attachmentOid) { From cd2366ef3673af9392d051a5d2dfeb39f5f5b0e0 Mon Sep 17 00:00:00 2001 From: Randy Date: Mon, 31 Jul 2017 23:33:29 -0500 Subject: [PATCH 3/3] Simplified the original method - DRY Based on Spazmodius's advice, I applied the DRY prinicple: don't repeat yourself. --- APIClient/Services/Services.cs | 49 +--------------------------------- 1 file changed, 1 insertion(+), 48 deletions(-) diff --git a/APIClient/Services/Services.cs b/APIClient/Services/Services.cs index 9635989..6624e8d 100644 --- a/APIClient/Services/Services.cs +++ b/APIClient/Services/Services.cs @@ -377,54 +377,7 @@ public string ExecutePassThroughQuery(string query) public Oid SaveAttachment(string filePath, Asset asset, string attachmentName) { - if (string.IsNullOrWhiteSpace(filePath)) - throw new ArgumentNullException("filePath"); - if (!File.Exists(filePath)) - throw new APIException(string.Format("File \"{0}\" does not exist.", filePath)); - - var mimeType = MimeType.Resolve(filePath); - IAssetType attachmentType = Meta.GetAssetType("Attachment"); - IAttributeDefinition attachmentAssetDef = attachmentType.GetAttributeDefinition("Asset"); - IAttributeDefinition attachmentContent = attachmentType.GetAttributeDefinition("Content"); - IAttributeDefinition attachmentContentType = attachmentType.GetAttributeDefinition("ContentType"); - IAttributeDefinition attachmentFileName = attachmentType.GetAttributeDefinition("Filename"); - IAttributeDefinition attachmentNameAttr = attachmentType.GetAttributeDefinition("Name"); - Asset attachment = New(attachmentType, Oid.Null); - attachment.SetAttributeValue(attachmentNameAttr, attachmentName); - attachment.SetAttributeValue(attachmentFileName, filePath); - attachment.SetAttributeValue(attachmentContentType, mimeType); - attachment.SetAttributeValue(attachmentContent, string.Empty); - attachment.SetAttributeValue(attachmentAssetDef, asset.Oid); - Save(attachment); - - string key = attachment.Oid.Key.ToString(); - - using (Stream input = new FileStream(filePath, FileMode.Open, FileAccess.Read)) - { - using (Stream output = _connector != null ? _connector.BeginRequest(key.Substring(key.LastIndexOf('/') + 1)) : _v1Connector.BeginRequest(key.Substring(key.LastIndexOf('/') + 1))) - { - byte[] buffer = new byte[input.Length + 1]; - while (true) - { - int read = input.Read(buffer, 0, buffer.Length); - if (read <= 0) - break; - - output.Write(buffer, 0, read); - } - } - } - if (_connector != null) - { - _connector.EndRequest(key.Substring(key.LastIndexOf('/') + 1), mimeType); - } - else - { - _v1Connector.UseAttachmentApi(); - _v1Connector.EndRequest(key.Substring(key.LastIndexOf('/') + 1), mimeType); - } - - return attachment.Oid; + return SaveAttachment(filePath, asset, attachmentName, false); } public Oid SaveAttachment(string filePath, Asset asset, string attachmentName, bool useFileNameAsFileName)