0
votes

I am working on a custom activity workflow in CRM 2013. My workflowaccesses a xml file. when I deploy my workflow and run it is throwing an error as;

Unhandled Exception: Microsoft.Crm.CrmException: Unexpected exception from plug-in (Execute): MyProj.WorkFlows.ReadXML: System.Security.SecurityException: Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.

The code I have written is as;

public string GetBookAuthor(string key, string bookId)
        {
            string fileName = @"books.xml";
            XmlTextReader reader = new XmlTextReader(fileName);
            XmlDocument doc = new XmlDocument();
            doc.Load(reader);
            reader.Close();

            XmlNode bookAuthor;
            if (doc != null)
            {
                XmlElement root = doc.DocumentElement;
                if (root != null)
                {
                    bookAuthor= root.SelectSingleNode("/books/book[@key='" + key + "']/Author[@bookId='" + bookId + "']");
                    if (bookAuthor!= null)
                        return bookAuthor.InnerText;
                    return string.Empty;
                }
                return string.Empty;
            }
            return string.Empty;
        }
2

2 Answers

1
votes

Custom Workflow Activities can access to the file system only if they are registered outside the sandbox.

Also it's not a best practice to allow custom workflow activities or plugins to use the file system, better to use Web Resources or Web Services to store/handle files.

0
votes

(Note that the following is true for any assembly: custom activities, plugins...)

If you want to follow a 100% supported approach so you can stay inside the sandbox, you mustn't ever leave the CRM "environment". That means: no file system access, no calls to external web services (more on that below), no SQL queries etc.

To achieve this in your case, it's easy:

  1. Store your XML file inside CRM as a Web Resource (keep note of the unique name, you'll need it)
  2. In your code, change the part where you access the file system to a QueryExpression on the WebResource entity. The contents of the webresource are going to be Base64-encoded, so you have an additional hoop to jump through to obtain the original text.
    var filename = "your_web_resource_unique_name_here";
    XmlDocument doc = new XmlDocument();

    var xmlQuery = new QueryExpression("WebResource")
    {
        ColumnSet = new ColumnSet("Content"),
        Criteria = new FilterExpression(LogicalOperator.And)
        {
            Conditions = { 
                new ConditionExpression("Name", ConditionOperator.Equal, filename)
            }
        }
    };
    var xmlEncoded = organizationService.RetrieveMultiple(xmlQuery).First().GetAttributeValue("Content");
    var xmlPlain = Encoding.UTF8.GetString(Convert.FromBase64String(xmlEncoded));

    doc.LoadXml(xmlPlain);
  1. doc is filled up and ready

About external web services, it's allegedly supported but data transfers are very easily mistaken as overloads (and the platform kills the worker process). This could lead to random failures in the plugin executions, leading customers to "nothing works!" support tickets ...