Thursday, April 21, 2011

Storing any File Type in a Microsoft Dynamics CRM 2011 Solution as a Web Resource

I ran into a situation the other day where I had to store an oddball file type in a CRM solution that was to be reconstituted and used by code within a plugin from CRM Online.  My thought was to store the file as a web resource but quickly realized that there wasn't a file type for my file.  But I still got it in there.

Here's how:

1. Rename the file extension to .xml and choose the XML file type.  

2. It seems that the application doesn't actually check to see if the file type matches within the file and just blindly uploads it.

3. You can now reconstitute the file from a byte array in code by examining the content attribute of that particular webresource entity.  It is base64 encoded (probably to avoid having to use escape sequences), but that is an easy thing to deal with in .NET.  If I spit the byte array out to a file using a stream reader I can verify that the SHA-1 hash of the reconstituted file matches that of the original file, and it does.

Here is what the code looks like to retrieve your file using C#.  In this example we will spit it out to a file.  This code just uses a retrievemultiple to call to get the webresource, decodes the content attribute into an array of bytes and spits it out to a file.

RetrieveMultipleRequest rmr = new RetrieveMultipleRequest();
      RetrieveMultipleResponse resp = new RetrieveMultipleResponse();
      WebResource wr = new WebResource();

      QueryExpression query = new QueryExpression()
      {
          EntityName = "webresource",
          ColumnSet = new ColumnSet("content"),
          Criteria = new FilterExpression
          {
              FilterOperator = LogicalOperator.And,
              Conditions = 
                {
                    new ConditionExpression
                    {
                        AttributeName = "name",
                        Operator = ConditionOperator.Equal,
                        Values = { "new_testwebresource" }
                    }
                }
          }
      };

      rmr.Query = query;
      resp = (RetrieveMultipleResponse)service.Execute(rmr);
      wr = (WebResource)resp.EntityCollection.Entities[0];
      byte[] filebytes = Convert.FromBase64String(wr.Content);
      FileStream fs = new FileStream(@"c:\testfiles\randomfile.ext",FileMode.Create);
      foreach (byte b in filebytes)
      {
          fs.WriteByte(b);
      }
      fs.Close();

I hope this helps!

 

 

6 comments:

  1. Hello Jamie!

    My name is Evgeniy I'm from Kiev, Ukraine. I hope you can help me with some issue. Maybe it can be a topic for your blog.

    I'm working with PHP and trying to connect to CRM Online version from PHP. I'm using a script written by some good guy http://sourceforge.net/projects/php2dynamics/files/webclient/. The script can get a list of any entity. SOAP request body looks like this:






    Query

    <fetch mapping="logical" count="50" version="1.0">

    <entity name="account">

    <attribute name="name" />

    <attribute name="address1_city" />

    <attribute name="telephone1" />

    <order attribute="name" descending="false" />

    </entity>

    </fetch>




    RetrieveMultiple




    Please advise what request body should I use for creating and updating entities (using Create and Update methods)

    Thank you!
    Hope for your answer.

    ReplyDelete
  2. You can get an idea on what the soap envelopes need to look like if you look at these posts, in particular the jscript samples in the posts.
    http://mileyja.blogspot.com/2011/04/create-requests-in-net-and-jscript-in.html
    http://mileyja.blogspot.com/2011/04/how-to-use-update-requests-in-net-and.html

    You can also figure out the envelopes by using the soap logger solution that comes with the CRM 2011 SDK:
    http://www.microsoft.com/downloads/en/details.aspx?FamilyID=420f0f05-c226-4194-b7e1-f23ceaa83b69

    Here is some more info on the soaplogger:
    http://msdn.microsoft.com/en-us/library/gg594434.aspx

    ReplyDelete
  3. Dear Jamie,

    Thanks a lot!

    You really helped me!!!!

    Thank you!

    ReplyDelete
  4. Jamie, I'm new in .NET and it little bit difficult to use VS and check requests. Please advice request body for simple Retreive action. Not Multiple retreive, just Retreive. The server says that I need to specify ColumnSet. I searched Internet but there is big difference between XML syntax of Online and stand alone CRM versions.

    ReplyDelete
  5. Here you to Eugene, this should help.
    http://mileyja.blogspot.com/2011/04/how-to-use-retrieve-messages-in-jscript.html

    ReplyDelete