So I am trying to create my own logic for moving a Quote Annotation to a SharePoint location. After multiple trial-and-errors I am now at a point which I cannot seem to solve.
The objective of the custom Workflow is simple;
- A user creates a Quote and activate it.
- When the quote is activated a word template is generated, this is being done in a Workflow with SetWordTemplate Entity (Quote), this all works fine, a word document based on the Quote is being created and is added as annotation to the quote.
- The next step in this same workflow should be as following: Get the created annotation and move/copy it to the customer his (online) SharePoint location.
For step 3 I created a Custom Workflow plugin with the following tutorials as references:
vikramxrm.blogspot.nl/.../copy-ms-crm-2011-attached-documents-in.html
https://github.com/jlattimer/CRM-Note-Workflow-Utilities
The code I have so far is:
public class MoveQuoteToSharepoint : CodeActivity { [Input("SourceQuote")] [ReferenceTarget("quote")] public InArgument<EntityReference> SourceQuote { get; set; } private String _fileName; protected override void Execute(CodeActivityContext executionContext) { //Create the context IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>(); IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>(); IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId); // Get the target entity from the context Entity regQuote = (Entity)service.Retrieve("quote", context.PrimaryEntityId, new ColumnSet(new string[] { "name", "ownerid" })); string quoteName = (string)regQuote.Attributes["name"]; //Get the notes from the Quote (context) QueryExpression _quoteAttachmentQuery = new QueryExpression { EntityName = "annotation", ColumnSet = new ColumnSet ( "subject", "filename", "documentbody" ), Criteria = new FilterExpression { Conditions = { new ConditionExpression { AttributeName = "objectid", Operator = ConditionOperator.Equal, Values = { context.PrimaryEntityId } }, new ConditionExpression { AttributeName = "isdocument", Operator = ConditionOperator.Equal, Values = {true} } } } }; EntityCollection results = service.RetrieveMultiple(_quoteAttachmentQuery); //Annotation found if (results.Entities.Count > 0) { //Fetch first annotation Entity retrievedAnnotation = results.Entities.First(); _fileName = retrievedAnnotation.GetAttributeValue<string>("filename"); using (FileStream fileStream = new FileStream(_fileName, FileMode.OpenOrCreate)) { byte[] fileContent = Convert.FromBase64String(retrievedAnnotation.GetAttributeValue<string>("documentbody")); //fileStream.Write(fileContent, 0, fileContent.Length); CopyToSharePoint2013(retrievedAnnotation.Id, service, quoteName, fileContent, _fileName); } } else { throw new Exception("There are no annotations found for this Quote."); } } public static void CopyToSharePoint2013(Guid _CaseId, IOrganizationService _service, string _FolderName, byte[] fileContent, string filename) { try { string _SharePointServer = @"mydomain.sharepoint.com/.../xxx"; using (ClientContext _clientContext = new ClientContext(_SharePointServer)) { SecureString passWord = new SecureString(); foreach (char c in "xxxx".ToCharArray()) passWord.AppendChar(c); _clientContext.Credentials = new SharePointOnlineCredentials("me@loginemail.com", passWord); //create web object Web web = _clientContext.Web; List oList = web.Lists.GetByTitle("Quote"); if (oList != null) { //Create Folder var folders = oList.RootFolder.Folders; _clientContext.Load(folders); _clientContext.ExecuteQuery(); var newFolder = folders.Add(_FolderName); _clientContext.ExecuteQuery(); //Copy file into created folder FileCreationInformation oFileCreationInformation = new FileCreationInformation(); oFileCreationInformation.Content = fileContent; oFileCreationInformation.Url = @_SharePointServer + "/quote/" + _FolderName + "/" + filename; oFileCreationInformation.Overwrite = true; oList.RootFolder.Files.Add(oFileCreationInformation); _clientContext.Load(oList); _clientContext.ExecuteQuery(); //Create SharePoint Location record if (!AlreadyExistDocumentLocationRecord(_CaseId, _service)) { CreateDocumentLocationRecord(_service, _FolderName, oFileCreationInformation.Url, _CaseId); } } } } catch (Exception Ex) { Console.Write(Ex.Message); if (Ex.InnerException != null) { Console.WriteLine(Ex.InnerException.Message); Console.ReadLine(); } } } private static void CreateDocumentLocationRecord(IOrganizationService service, string _locationName, string _locationURL, Guid _regarding) { try { // Instantiate an account object. Entity DocumentLocation = new Entity("sharepointdocumentlocation"); //set the fields values DocumentLocation["name"] = _locationName; DocumentLocation["regardingobjectid"] = new EntityReference("quote", _regarding); DocumentLocation["relativeurl"] = _locationName; if ((GetParentSiteUrl(service)) != Guid.Empty) { DocumentLocation["parentsiteorlocation"] = new EntityReference("sharepointdocumentlocation", GetParentSiteUrl(service)); } //create the record Guid DocumentLocationid = service.Create(DocumentLocation); } catch (Exception Ex) { Console.Write(Ex.Message); if (Ex.InnerException != null) { Console.WriteLine(Ex.InnerException.Message); Console.ReadLine(); } } } private static Guid GetParentSiteUrl(IOrganizationService service) { Guid _Id = Guid.Empty; try { QueryExpression _Query = new QueryExpression { EntityName = "sharepointdocumentlocation", ColumnSet = new ColumnSet("relativeurl"), Criteria = new FilterExpression { FilterOperator = LogicalOperator.And, Conditions = { new ConditionExpression { AttributeName = "relativeurl", Operator = ConditionOperator.Equal, Values = { "quote" } }, } } }; EntityCollection _EntityLocation = service.RetrieveMultiple(_Query); if (_EntityLocation.Entities.Count > 0) { _Id = _EntityLocation.Entities[0].Id; } } catch (Exception Ex) { Console.Write(Ex.Message); if (Ex.InnerException != null) { Console.WriteLine(Ex.InnerException.Message); Console.ReadLine(); } } return _Id; } private static bool AlreadyExistDocumentLocationRecord(Guid CaseId, IOrganizationService _service) { QueryExpression _Query = new QueryExpression { EntityName = "sharepointdocumentlocation", ColumnSet = new ColumnSet("regardingobjectid"), Criteria = new FilterExpression { FilterOperator = LogicalOperator.And, Conditions = { new ConditionExpression { AttributeName = "regardingobjectid", Operator = ConditionOperator.Equal, Values = { CaseId } }, } } }; EntityCollection _EntityLocation = _service.RetrieveMultiple(_Query); if (_EntityLocation.Entities.Count > 0) return true; else return false; } }
After some testing I am getting the following error:
![]() |
Unexpected exception from plug-in (Execute): MyNameSpace.MoveQuoteToSharepoint: System.Security.SecurityException: Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed. |
I guess it is being caused by the following bit of code, but I am not sure:
using (FileStream fileStream = new FileStream(_fileName, FileMode.OpenOrCreate)) { byte[] fileContent = Convert.FromBase64String(retrievedAnnotation.GetAttributeValue<string>("documentbody")); //fileStream.Write(fileContent, 0, fileContent.Length); CopyToSharePoint2013(retrievedAnnotation.Id, service, quoteName, fileContent, _fileName); }
Anyone have a clue how to fix this? I am also not sure if the SharePoint bits of code will work, not even got there because of the previous error. Does anyone think I should program it differently?
Thank you in advance!
*This post is locked for comments