Hi, I am having a custom entity as Employee. En each record of the Employee entity, I have notes as attachments.
So, I want to download all the attachments of all the entity records. While downloading, I want to rename the filename of the attachments as "Employee Record name" + "Attachment name".
Say, I have a Employee record as Surya. The employee record Surya has an attachment named submission.txt .
So, While getting downloaded in a specified path, it should be renamed as Surya - Submission.txt (as per the business requirement).
So, I have created a field named new_downloadflag (two options field). By default it is set as No.
While it is set as Yes, I have created a pre-validation plugin on Update of the Employee entity and all the Employee entity records's all attachments should be downloaded in a specified path.
So,I have written the plugin and I have used for-each loop to get all the records of the employee's attachments to fetch all those in a specified local drive folder.
My plugin code is given below:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Threading.Tasks; using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Client; using System.ServiceModel; using Microsoft.Xrm.Sdk.Query; using System.ComponentModel.DataAnnotations; namespace Microsoft.Crm.Sdk.Samples { [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")] public class DownloadAttachment : IPlugin { //Guid _annotationId; //Guid empid; //EntityReference obj = new EntityReference(); String NoteText; String recordid; bool downflagg; String documentbody; //String resultname; public void Execute(IServiceProvider serviceprovider) { try { IPluginExecutionContext context = (IPluginExecutionContext)serviceprovider.GetService(typeof(IPluginExecutionContext)); // context is the place where all the fields and columnset is present with all the values IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceprovider.GetService(typeof(IOrganizationServiceFactory)); IOrganizationService service = (IOrganizationService)factory.CreateOrganizationService(context.UserId); if (context.Depth > 1) // to avoid infinite loop return; if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity) { Entity entity = (Entity)context.InputParameters["Target"]; if (entity.LogicalName != "new_employee") return; //download flag field if (entity.Attributes.Contains("new_downloadflag")) { downflagg = (bool)entity.Attributes["new_downloadflag"]; } var downflag = entity.GetAttributeValue<bool?>("new_downloadflag").GetValueOrDefault(); if (downflag == true) //Code will run only when this flag is true or yes { QueryExpression emplo = new QueryExpression(); //Getting records which have status as active emplo.EntityName = "new_employee"; emplo.ColumnSet = new ColumnSet(true); emplo.Criteria.AddCondition(new ConditionExpression { AttributeName = "statecode", Operator = ConditionOperator.Equal, Values = { 0 } }); EntityCollection encol = service.RetrieveMultiple(emplo); //retrieve them and save it as entity collection if (encol.Entities.Count > 0) //To check the Employee entity has atleast one record { foreach (var xy in encol.Entities) //Fetching the records one by one using foreach loop's attributes { if (xy.Attributes.Contains("new_name")) { recordid = (string)xy.Attributes["new_name"]; } Guid emprecid = xy.Id; // record's id QueryExpression qe = new QueryExpression(); qe.EntityName = "annotation"; qe.ColumnSet = new ColumnSet(true); qe.Criteria.AddCondition(new ConditionExpression // to check the condition this expression has been used here { AttributeName = "objectid", //lookup name Operator = ConditionOperator.Equal, Values = { emprecid } }); EntityCollection ec = service.RetrieveMultiple(qe); foreach (Entity output in ec.Entities) { if (output.Attributes.Contains("filename")) { NoteText = (string)output.Attributes["filename"]; } if (output.Attributes.Contains("documentbody")) { documentbody = (string)output.Attributes["documentbody"]; } byte[] fileContent = Convert.FromBase64String(output.Attributes["documentbody"].ToString()); using (FileStream file = new FileStream(@"D:\" + recordid + NoteText + ".txt", FileMode.Create)) { using (BinaryWriter writer = new BinaryWriter(file)) { writer.Write(fileContent,0,fileContent.Length); writer.Close(); } file.Close(); } //using (FileStream fileStream = new FileStream(@"D:\" + recordid + NoteText + ".txt", FileMode.OpenOrCreate)) //{ // byte[] fileContent = Convert.FromBase64String(output.Attributes["documentbody"].ToString()); // fileStream.Write(fileContent, 0, fileContent.Length); // //Response.OutputStream.Write(fileContent , 0, fileContent .Length); //} //string outputFileName = @"C:\temp\recordid.txt"; //string noteBody = "gdgsdgdsgsdgsdgs"; //if (!string.IsNullOrEmpty(noteBody)) //{ // // Download the attachment in the current execution folder. // byte[] fileContent = Convert.FromBase64String(noteBody); // System.IO.File.WriteAllBytes(outputFileName, fileContent); //} //else //{ // throw new InvalidPluginExecutionException("File content is empty or cannot be retrieved"); //} //Entity notentity = (Entity)context.InputParameters["Target"]; //TextWriter tw = new StreamWriter(@"D:\" + recordid + NoteText + ".txt",true); //tw.WriteLine("The next line!"); //tw.Close(); //System.IO.File.WriteAllText(@"D:\" + recordid + NoteText + ".txt", ""); } } } } } } catch (Exception ex) { throw ex; } } } }
Now, When i tried to debug or see the results, I have got this error as
Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
Let me know where I am wrong or what should be done.!
Need your suggestions!
Thanks!