using System.Web.Http; using System.Threading.Tasks; using Aspose.App.Models; using System.Collections.Generic; using System.IO; using System; using System.Reflection; using Aspose.Cells.Properties; using Aspose.Pdf; using Aspose.Slides; using Tools.Foundation.Models; using Aspose.Email.Mapi; using System.Text; using Aspose.App.LibraryHelpers; using System.Linq; namespace Aspose.App.Controllers { /// /// AsposeMetadataController class to get metadata properties /// public class AsposeMetadataController : ApiControllerBase { private List allowedTypes = new List { "Boolean", "DateTime", "Double", "Number", "Int32", "String" }; private Boolean IsAllowedType(string propertyType) { return allowedTypes.Contains(propertyType); } private void AddWordsCustomPropertyValue(Words.Properties.CustomDocumentProperties customDocumentProperties, AsposeMetadataObject metadataObj) { if (metadataObj.ValueType == "Boolean") { customDocumentProperties.Add(metadataObj.Property, Boolean.Parse(metadataObj.Value)); } else if (metadataObj.ValueType == "DateTime") { customDocumentProperties.Add(metadataObj.Property, DateTime.Parse(metadataObj.Value)); } else if (metadataObj.ValueType == "Double") { customDocumentProperties.Add(metadataObj.Property, Double.Parse(metadataObj.Value)); } else if (metadataObj.ValueType == "Number" || metadataObj.ValueType == "Int32") { customDocumentProperties.Add(metadataObj.Property, Int32.Parse(metadataObj.Value)); } else if (metadataObj.ValueType == "String") { customDocumentProperties.Add(metadataObj.Property, metadataObj.Value); } } private void AddCellsCustomPropertyValue(CustomDocumentPropertyCollection customDocumentProperties, AsposeMetadataObject metadataObj) { if (metadataObj.ValueType == "Boolean") { customDocumentProperties.Add(metadataObj.Property, Boolean.Parse(metadataObj.Value)); } else if (metadataObj.ValueType == "DateTime") { customDocumentProperties.Add(metadataObj.Property, DateTime.Parse(metadataObj.Value)); } else if (metadataObj.ValueType == "Double") { customDocumentProperties.Add(metadataObj.Property, Double.Parse(metadataObj.Value)); } else if (metadataObj.ValueType == "Number" || metadataObj.ValueType == "Int32") { customDocumentProperties.Add(metadataObj.Property, Int32.Parse(metadataObj.Value)); } else if (metadataObj.ValueType == "String") { customDocumentProperties.Add(metadataObj.Property, metadataObj.Value); } } private void AddPdfCustomPropertyValue(Metadata customDocumentProperties, AsposeMetadataObject metadataObj) { if (!metadataObj.Property.Contains(':')) { metadataObj.Property=metadataObj.Property.Insert(0, "pdfx:"); } if (metadataObj.ValueType == "Boolean") { customDocumentProperties.Add(new KeyValuePair(metadataObj.Property, metadataObj.Value)); } else if (metadataObj.ValueType == "DateTime") { customDocumentProperties.Add(new KeyValuePair(metadataObj.Property, DateTime.Parse(metadataObj.Value))); } else if (metadataObj.ValueType == "Double") { customDocumentProperties.Add(new KeyValuePair(metadataObj.Property, Double.Parse(metadataObj.Value))); } else if (metadataObj.ValueType == "Number" || metadataObj.ValueType == "Int32") { customDocumentProperties.Add(new KeyValuePair(metadataObj.Property, Int32.Parse(metadataObj.Value))); } else if (metadataObj.ValueType == "String") { customDocumentProperties.Add(metadataObj.Property, metadataObj.Value); } } private void AddSlidesCustomPropertyValue(IDocumentProperties customDocumentProperties, AsposeMetadataObject metadataObj) { if (metadataObj.ValueType == "Boolean") { customDocumentProperties.SetCustomPropertyValue(metadataObj.Property, Boolean.Parse(metadataObj.Value)); } else if (metadataObj.ValueType == "DateTime") { customDocumentProperties.SetCustomPropertyValue(metadataObj.Property, DateTime.Parse(metadataObj.Value)); } else if (metadataObj.ValueType == "Double") { customDocumentProperties.SetCustomPropertyValue(metadataObj.Property, Double.Parse(metadataObj.Value)); } else if (metadataObj.ValueType == "Number" || metadataObj.ValueType == "Int32") { customDocumentProperties.SetCustomPropertyValue(metadataObj.Property, Int32.Parse(metadataObj.Value)); } else if (metadataObj.ValueType == "String") { customDocumentProperties.SetCustomPropertyValue(metadataObj.Property, metadataObj.Value); } } private void SetBuiltInPropertyValue(PropertyInfo prop, Object props, string value) { try { Object obj = null; if (prop.PropertyType.Name == "Boolean") { obj = Boolean.Parse(value); } else if (prop.PropertyType.Name == "DateTime") { obj = DateTime.Parse(value); } else if (prop.PropertyType.Name == "Double") { obj = Double.Parse(value); } else if (prop.PropertyType.Name == "Number" || prop.PropertyType.Name == "Int32") { obj = Int32.Parse(value); } else if (prop.PropertyType.Name == "String") { obj = value; } prop.SetValue(props, obj); } catch (Exception) { } } /// /// GetAsposeMetadata method to get metadata /// [HttpGet] [ActionName("GetAsposeMetadata")] public async Task GetAsposeMetadata(string product, string fileNamePath) { string logMsg = "ControllerName = " + this.GetType().Name + ", " + "MethodName = " + "GetAsposeMetadata" + ", " + "Folder = " + Path.GetFileName(Path.GetDirectoryName(fileNamePath)); ProductFamilyNameKeysEnum productFamily = ProductFamilyNameKeysEnum.unassigned; string productName = ""; var productInLowerCase = product.ToLowerInvariant(); if (productInLowerCase == "words") { productName = AsposeWords; productFamily = ProductFamilyNameKeysEnum.words; } else if (productInLowerCase == "cells") { productName = AsposeCells; productFamily = ProductFamilyNameKeysEnum.cells; } else if (productInLowerCase == "slides") { productName = AsposeSlides; productFamily = ProductFamilyNameKeysEnum.slides; } else if (productInLowerCase == "pdf") { productName = AsposePDF; productFamily = ProductFamilyNameKeysEnum.pdf; } else if (productInLowerCase == "email") { productName = AsposeEmail; productFamily = ProductFamilyNameKeysEnum.email; } productName += MetadataApp; try { AsposeMetadataResponse response = null; if (productInLowerCase == "words") { response = GetAsposeWordsMetadata(fileNamePath); } else if (productInLowerCase == "cells") { response = GetAsposeCellsMetadata(fileNamePath); } else if (productInLowerCase == "slides") { response = GetAsposeSlidesMetadata(fileNamePath); } else if (productInLowerCase == "pdf") { response = GetAsposePdfMetadata(fileNamePath); } else if (productInLowerCase == "email") { response = GetAsposeEmailMetadata(fileNamePath); } NLogger.LogInfo(logMsg, productName, productFamily, Path.GetFileName(fileNamePath)); return await Task.FromResult(response); } catch (Exception e) { NLogger.LogError(e, logMsg, productName, productFamily, Path.GetFileName(fileNamePath)); AsposeMetadataResponse response = new AsposeMetadataResponse { Status = e.Message, StatusCode = 500 }; return response; } } private string GetValueString(object objValue) { string retVal = ""; if(objValue != null) { retVal = objValue.ToString(); } return retVal; } private AsposeMetadataResponse GetAsposeWordsMetadata(string fileNamePath) { Words.Document doc = new Aspose.Words.Document(fileNamePath); int i = 0; List builtInMetadataList = new List(); Words.Properties.BuiltInDocumentProperties props = doc.BuiltInDocumentProperties; Type t = props.GetType(); foreach(var prop in t.GetProperties()) { if (prop.CanWrite && IsAllowedType(prop.PropertyType.Name)) { AsposeMetadataObject metadataObject = new AsposeMetadataObject { PropertyId = i++, Property = prop.Name, Value = GetValueString(prop.GetValue(props)), ValueType = prop.PropertyType.Name }; builtInMetadataList.Add(metadataObject); } } i = 0; List customMetadataList = new List(); foreach (Aspose.Words.Properties.DocumentProperty obj in doc.CustomDocumentProperties) { AsposeMetadataObject metadataObject = new AsposeMetadataObject { PropertyId = i++, Property = obj.Name, Value = GetValueString(obj.Value), ValueType = obj.Type.ToString() }; customMetadataList.Add(metadataObject); } AsposeMetadataResponse response = new AsposeMetadataResponse { BuiltInMetadataList = builtInMetadataList, CustomMetadataList = customMetadataList, Status = "OK", StatusCode = 200 }; return response; } private AsposeMetadataResponse GetAsposeCellsMetadata(string fileNamePath) { Aspose.Cells.Workbook doc = new Aspose.Cells.Workbook(fileNamePath); int i = 0; List builtInMetadataList = new List(); Cells.Properties.BuiltInDocumentPropertyCollection props = doc.BuiltInDocumentProperties; Type t = props.GetType(); foreach (var prop in t.GetProperties()) { if (prop.CanWrite && IsAllowedType(prop.PropertyType.Name)) { AsposeMetadataObject metadataObject = new AsposeMetadataObject { PropertyId = i++, Property = prop.Name, Value = GetValueString(prop.GetValue(props)), ValueType = prop.PropertyType.Name }; builtInMetadataList.Add(metadataObject); } } i = 0; List customMetadataList = new List(); foreach (Aspose.Cells.Properties.DocumentProperty obj in doc.CustomDocumentProperties) { AsposeMetadataObject metadataObject = new AsposeMetadataObject { PropertyId = i++, Property = obj.Name, Value = GetValueString(obj.Value), ValueType = obj.Type.ToString() }; customMetadataList.Add(metadataObject); } AsposeMetadataResponse response = new AsposeMetadataResponse { BuiltInMetadataList = builtInMetadataList, CustomMetadataList = customMetadataList, Status = "OK", StatusCode = 200 }; return response; } private AsposeMetadataResponse GetAsposePdfMetadata(string fileNamePath) { Aspose.Pdf.Document doc = new Aspose.Pdf.Document(fileNamePath); int i = 0; List builtInMetadataList = new List(); Pdf.DocumentInfo props = doc.Info; Type t = props.GetType(); foreach (var prop in t.GetProperties()) { if (IsPdfBuiltInProperty(prop.Name) && IsAllowedType((prop.PropertyType.Name))) { object obj = null; try { obj = prop.GetValue(props); } catch (Exception) { } AsposeMetadataObject metadataObject = new AsposeMetadataObject { PropertyId = i++, Property = prop.Name, Value = GetValueString(obj), ValueType = prop.PropertyType.Name }; builtInMetadataList.Add(metadataObject); } } i = 0; List customMetadataList = new List(); foreach (string key in doc.Metadata.Keys) { AsposeMetadataObject metadataObject = new AsposeMetadataObject { PropertyId = i++, Property = key, Value = GetValueString(doc.Metadata[key]), ValueType = "String" }; customMetadataList.Add(metadataObject); } AsposeMetadataResponse response = new AsposeMetadataResponse { BuiltInMetadataList = builtInMetadataList, CustomMetadataList = customMetadataList, Status = "OK", StatusCode = 200 }; return response; } private bool IsPdfBuiltInProperty(string name) { var allowedProperties = new HashSet {"Author","CreationDate","Creator","Keywords","ModDate","Subject", "Title","Trapped" }; return allowedProperties.Contains(name); } private AsposeMetadataResponse GetAsposeSlidesMetadata(string fileNamePath) { Aspose.Slides.Presentation doc = new Aspose.Slides.Presentation(fileNamePath); int i = 0; List builtInMetadataList = new List(); var props = doc.DocumentProperties; Type t = props.GetType(); foreach (var prop in t.GetProperties()) { if (prop.CanWrite && IsAllowedType(prop.PropertyType.Name)) { AsposeMetadataObject metadataObject = new AsposeMetadataObject { PropertyId = i++, Property = prop.Name, Value = GetValueString(prop.GetValue(props)), ValueType = prop.PropertyType.Name }; builtInMetadataList.Add(metadataObject); } } i = 0; List customMetadataList = new List(); for (int j=0; j < doc.DocumentProperties.CountOfCustomProperties; j++) { string propName = doc.DocumentProperties.GetCustomPropertyName(j); var prop = doc.DocumentProperties[propName]; AsposeMetadataObject metadataObject = new AsposeMetadataObject { PropertyId = i++, Property = propName, Value = GetValueString(prop), ValueType = prop.GetType().ToString() }; customMetadataList.Add(metadataObject); } AsposeMetadataResponse response = new AsposeMetadataResponse { BuiltInMetadataList = builtInMetadataList, CustomMetadataList = customMetadataList, Status = "OK", StatusCode = 200 }; return response; } private AsposeMetadataResponse GetAsposeEmailMetadata(string fileNamePath) { var formatInfo = Email.Tools.FileFormatUtil.DetectFileFormat(fileNamePath); Aspose.Email.Mapi.MapiMessage mail; if (formatInfo.FileFormatType == Email.FileFormatType.Eml) mail = Aspose.Email.Mapi.MapiMessage.Load(fileNamePath, new Email.EmlLoadOptions()); else if (formatInfo.FileFormatType == Email.FileFormatType.Msg) mail = Aspose.Email.Mapi.MapiMessage.Load(fileNamePath, new Email.MsgLoadOptions()); else return new AsposeMetadataResponse() { StatusCode = 400, Status = "Invalid file format" }; int i = 0; List builtInMetadataList = new List(); Type t = mail.GetType(); foreach (var prop in t.GetProperties()) { if (prop.CanWrite && IsAllowedType(prop.PropertyType.Name)) { AsposeMetadataObject metadataObject = new AsposeMetadataObject { PropertyId = i++, Property = prop.Name, Value = GetValueString(prop.GetValue(mail)), ValueType = prop.PropertyType.Name }; builtInMetadataList.Add(metadataObject); } } i = 0; List customMetadataList = new List(); foreach (var pair in mail.GetCustomProperties()) { var name = pair.Value.Name; var prop = pair.Value.Property; var value = prop.GetValue(); AsposeMetadataObject metadataObject = new AsposeMetadataObject { PropertyId = i++, Property = name, Value = GetValueString(prop.Data, value, (MapiPropertyType)prop.DataType), ValueType = ConvertMailPropertyType((MapiPropertyType)prop.DataType) }; customMetadataList.Add(metadataObject); } AsposeMetadataResponse response = new AsposeMetadataResponse { BuiltInMetadataList = builtInMetadataList, CustomMetadataList = customMetadataList, Status = "OK", StatusCode = 200 }; return response; } private string ConvertMailPropertyType(MapiPropertyType type) { switch (type) { case MapiPropertyType.PT_BOOLEAN: return "Boolean"; case MapiPropertyType.PT_DOUBLE: return "Double"; case MapiPropertyType.PT_LONG: return "Number"; case MapiPropertyType.PT_SYSTIME: return "DateTime"; case MapiPropertyType.PT_UNICODE: return "String"; default: return type.ToString(); } } private string GetValueString(byte[] bytesValue, object objValue, MapiPropertyType type) { string retVal = ""; if (objValue != null) { switch (type) { case MapiPropertyType.PT_LONG: retVal = Convert.ToInt64(objValue).ToString(); break; case MapiPropertyType.PT_BOOLEAN: retVal = Convert.ToBoolean(objValue).ToString(); break; case MapiPropertyType.PT_DOUBLE: retVal = Convert.ToDouble(objValue).ToString("F2"); break; case MapiPropertyType.PT_SYSTIME: retVal = Convert.ToDateTime(objValue).ToString(); break; case MapiPropertyType.PT_UNICODE: retVal = objValue.ToString(); break; default: retVal = Encoding.Unicode.GetString(bytesValue); break; } } return retVal; } /////////////////////////////////////////////////////////////////////// /// /// SaveAsposeMetadata method to save metadata properties /// [HttpPost] [ActionName("SaveAsposeMetadata")] public Task SaveAsposeMetadata(AsposeMetadataSaveRequest request) { string guid = Guid.NewGuid().ToString(); //string logMsg = "Product: " + request.Product + " FileNamePath: " + request.FileNamePath; string logMsg = "ControllerName = " + "AsposeMetadataController" + ", " + "MethodName = " + "SaveAsposeMetadata" + ", " + "Folder = " + guid; ProductFamilyNameKeysEnum productFamily = ProductFamilyNameKeysEnum.unassigned; string productName = ""; var productInLowerCase = request.Product.ToLowerInvariant(); if (productInLowerCase == "words") { productName = AsposeWords; productFamily = ProductFamilyNameKeysEnum.words; } else if (productInLowerCase == "cells") { productName = AsposeCells; productFamily = ProductFamilyNameKeysEnum.cells; } else if (productInLowerCase == "slides") { productName = AsposeSlides; productFamily = ProductFamilyNameKeysEnum.slides; } else if (productInLowerCase == "pdf") { productName = AsposePDF; productFamily = ProductFamilyNameKeysEnum.pdf; } else if (productInLowerCase == "email") { productName = AsposeEmail; productFamily = ProductFamilyNameKeysEnum.email; } productName += MetadataApp; string outfileName = Path.GetFileName(request.FileNamePath); try { AsposeMetadataSaveResponse response = null; string outPath = AppSettings.OutputDirectory + guid; if (!Directory.Exists(outPath)) { Directory.CreateDirectory(outPath); outPath += "/" + outfileName; } System.IO.File.Copy(request.FileNamePath, outPath, true); string fileNamePath = outPath; if (productInLowerCase == "words") { Aspose.App.Models.License.SetAsposeWordsLicense(); response = SaveAsposeWordsMetadata(fileNamePath, request); } else if (productInLowerCase == "cells") { Aspose.App.Models.License.SetAsposeCellsLicense(); response = SaveAsposeCellsMetadata(fileNamePath, request); } else if (productInLowerCase == "slides") { Aspose.App.Models.License.SetAsposeSlidesLicense(); response = SaveAsposeSlidesMetadata(fileNamePath, request); } else if (productInLowerCase == "pdf") { Aspose.App.Models.License.SetAsposePdfLicense(); response = SaveAsposePdfMetadata(fileNamePath, request); } else if (productInLowerCase == "email") { Aspose.App.Models.License.SetAsposeEmailLicense(); response = SaveAsposeEmailMetadata(fileNamePath, request); } response.FileName = outfileName; response.FolderName = guid; NLogger.LogInfo(logMsg,productName , productFamily, outfileName); return Task.FromResult(response); } catch (Exception e) { NLogger.LogError(e, logMsg, productName, productFamily, outfileName); return Task.FromResult(new AsposeMetadataSaveResponse { Status = e.ToString(), StatusCode = 500, }); } } private AsposeMetadataSaveResponse SaveAsposeWordsMetadata(string fileNamePath, AsposeMetadataSaveRequest request) { Words.Document doc = new Words.Document(fileNamePath); Words.Properties.BuiltInDocumentProperties props = doc.BuiltInDocumentProperties; Type t = props.GetType(); foreach (var metadataObj in request.BuiltInMetadataList) { var prop = t.GetProperty(metadataObj.Property); SetBuiltInPropertyValue(prop, props, metadataObj.Value); } doc.CustomDocumentProperties.Clear(); foreach (var metadataObj in request.CustomMetadataList) { AddWordsCustomPropertyValue(doc.CustomDocumentProperties, metadataObj); } doc.Save(fileNamePath); return (new AsposeMetadataSaveResponse { Status = "OK", StatusCode = 200, }); } private AsposeMetadataSaveResponse SaveAsposeCellsMetadata(string fileNamePath, AsposeMetadataSaveRequest request) { Aspose.Cells.Workbook doc = new Aspose.Cells.Workbook(fileNamePath); Cells.Properties.BuiltInDocumentPropertyCollection props = doc.BuiltInDocumentProperties; Type t = props.GetType(); foreach (var metadataObj in request.BuiltInMetadataList) { var prop = t.GetProperty(metadataObj.Property); SetBuiltInPropertyValue(prop, props, metadataObj.Value); } doc.CustomDocumentProperties.Clear(); foreach (var metadataObj in request.CustomMetadataList) { AddCellsCustomPropertyValue(doc.CustomDocumentProperties, metadataObj); } doc.Save(fileNamePath); return (new AsposeMetadataSaveResponse { Status = "OK", StatusCode = 200, }); } private AsposeMetadataSaveResponse SaveAsposePdfMetadata(string fileNamePath, AsposeMetadataSaveRequest request) { Pdf.Document doc = new Aspose.Pdf.Document(fileNamePath); Pdf.DocumentInfo props = doc.Info; Type t = props.GetType(); foreach (var metadataObj in request.BuiltInMetadataList) { try { switch (metadataObj.Property) { case "Author": doc.Info.Author = metadataObj.Value; break; case "CreationDate": doc.Info.CreationDate = DateTime.Parse(metadataObj.Value); break; case "Keywords": doc.Info.Keywords = metadataObj.Value; break; case "ModDate": doc.Info.ModDate = DateTime.Parse(metadataObj.Value); break; case "Subject": doc.Info.Subject = metadataObj.Value; break; case "Title": doc.Info.Title = metadataObj.Value; break; case "Trapped": if (!string.IsNullOrWhiteSpace(metadataObj.Value)) { var str = metadataObj.Value.ToUpper(); if ((str=="TRUE") || (str == "FALSE")) doc.Info.Trapped = metadataObj.Value; } break; } } catch (Exception) { throw; } } //doc.Metadata.Clear(); foreach (var metadataObj in request.CustomMetadataList) { AddPdfCustomPropertyValue(doc.Metadata, metadataObj); } doc.Save(fileNamePath); return (new AsposeMetadataSaveResponse { Status = "OK", StatusCode = 200, }); } private AsposeMetadataSaveResponse SaveAsposeEmailMetadata(string fileNamePath, AsposeMetadataSaveRequest request) { var mail = MapiHelper.GetMapiMessageFromFile(fileNamePath); if (mail == null) return new AsposeMetadataSaveResponse() { StatusCode = 400, Status = "Invalid file format" }; Type t = mail.GetType(); foreach (var metadataObj in request.BuiltInMetadataList) { if (metadataObj.Property != "Item") { var prop = t.GetProperty(metadataObj.Property); SetBuiltInPropertyValue(prop, mail, metadataObj.Value); } } var customProps = mail.GetCustomProperties(); foreach (var item in customProps) mail.RemoveProperty(item.Key); foreach (var metadataObj in request.CustomMetadataList) { var name = metadataObj.Property; switch (metadataObj.ValueType) { case "Double": mail.AddCustomProperty(name, Convert.ToDouble(metadataObj.Value)); break; case "Boolean": mail.AddCustomProperty(name, Convert.ToBoolean(metadataObj.Value)); break; case "Number": mail.AddCustomProperty(name, Convert.ToInt64(metadataObj.Value)); break; case "DateTime": mail.AddCustomProperty(name, Convert.ToDateTime(metadataObj.Value)); break; case "String": mail.AddCustomProperty(name, metadataObj.Value); break; default: mail.AddCustomProperty(name, (MapiPropertyType)Enum.Parse(typeof(MapiPropertyType), metadataObj.ValueType), Encoding.Unicode.GetBytes(metadataObj.Value)); break; } } mail.Save(fileNamePath); return new AsposeMetadataSaveResponse() { Status = "OK", StatusCode = 200 }; } private AsposeMetadataSaveResponse SaveAsposeSlidesMetadata(string fileNamePath, AsposeMetadataSaveRequest request) { var doc = new Aspose.Slides.Presentation(fileNamePath); var props = doc.DocumentProperties; Type t = props.GetType(); foreach (var metadataObj in request.BuiltInMetadataList) { var prop = t.GetProperty(metadataObj.Property); SetBuiltInPropertyValue(prop, props, metadataObj.Value); } doc.DocumentProperties.ClearCustomProperties(); foreach (var metadataObj in request.CustomMetadataList) { AddSlidesCustomPropertyValue(doc.DocumentProperties, metadataObj); } string ext = Path.GetExtension(fileNamePath).ToLower(); Aspose.Slides.Export.SaveFormat saveFormat = Aspose.Slides.Export.SaveFormat.Pptx; switch (ext) { case "ppt": saveFormat = Aspose.Slides.Export.SaveFormat.Ppt; break; case "pptx": saveFormat = Aspose.Slides.Export.SaveFormat.Pptx; break; case "odp": saveFormat = Aspose.Slides.Export.SaveFormat.Odp; break; } doc.Save(fileNamePath, saveFormat); return (new AsposeMetadataSaveResponse { Status = "OK", StatusCode = 200, }); } } }