Knowledge found and lost while working with Microsoft Dynamics CRM
RSS icon Home icon
  • Bulk Attribute Deletion Utility Updated

    Posted on July 28th, 2010 Mitch Milam Print Print 1 comment

    I’ve modified the Bulk Attribute Deletion Utility to support Internet Facing Deployment ( IFD ) for CRM 4.0.

    Download it here.

    Thanks to my friend George Doubinski I was able to connect to a CRM installation via IFD for testing.

    Please let me know if you run into any issues.

    Customization, Development, Dynamics CRM
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    236 views
  • Exception handling when working with the CRM Web Services

    Posted on July 26th, 2010 Mitch Milam Print Print 2 comments

    I just ran into something that I have never seen before related to a SoapException:

    I was updating my Export JavaScript utility when I received an error message that was blank.  Very odd, I thought.  After a bit of digging, I found the error:

    Server was unable to process request.
    —> Exception has been thrown by the target of an invocation.
    —> The type initializer for 'Microsoft.Crm.WebServices.CrmAuthenticationSoapExtensionBase' threw an exception.
    —> The server is not operational.

    Now at this point, I really don’t know what happened, but my development CRM 4.0 server was in some type of non-functional state that required me to perform an IISRESET to recover from.  That is not the interesting thing here today.

    The interesting thing is where the error message was found.  Here is an example the code that normally use to detect an error when using the CRM Web Service:

    catch (SoapException ex)
    {
        MessageBox.Show(ex.Detail.InnerText,
                        Properties.Resources.MSG_AN_ERROR_HAS_OCCURRED,
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Error);
    }

    Usually, the actual error message is found in the SoapException.Detail property and you can access it via the InnerText or InnerXml properties, depending on how you wish to handle it.

    Today, the error message was actually in the SoapException.Message property, which I find very odd.  As I said, I’ve never seen this before so I don’t know what happened, but in order to prevent a blank error message from appearing to the user, I created the following work around:

    catch (SoapException ex)
    {
        string errorMessage = ex.Detail.InnerText;
    
        if (string.IsNullOrEmpty(errorMessage))
        {
            errorMessage = ex.Message;
        }
    
        MessageBox.Show(errorMessage,
                        Properties.Resources.MSG_AN_ERROR_HAS_OCCURRED,
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Error);
    }

    As you can see, I just take into account the possibility that the Detail.InnerText property is blank and if so, just use the standard Message property to be safe.

    Customization, Development, Dynamics CRM
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    275 views
  • The Visual Studio 2010 Build Configuration Dropdown Missing

    Posted on July 13th, 2010 Mitch Milam Print Print 1 comment

    I have been noticing lately that the Build Configuration dropdown list that is normally found the the Standard Toolbar is missing from my Visual Studio 2010 installation.

    After a bit of digging around the Internet, I found a solution, which I’ll document further here.

    The Procedure

    1) Select Tools, Customize…

    2) Click the Commands tab

    3) Select the Toolbar radio button.

    4) Select Standard from the dropdown list.  The dialog should now look like this:

    image

    5) Scroll down to the bottom of the list and select the last item in the list.  In my case, unmodified, the last item is Error List.

    6) Click the Add Command button.

    7), Under Categories, select Build.  Under Commands, select Solution Configurations.  You should see this:

    image

    8) Click OK, the Close

    9) The Visual Studio 2010 main menu should now look something like this:

    image

     

    I hope that saves you a bit of searching and hand-wringing.

    Development
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    340 views
  • CRM JavaScript Export Tool Updated

    Posted on July 12th, 2010 Mitch Milam Print Print 1 comment

    I have updated the CRM JavaScript Export Tool to include the following major enhancements:

    1) Added support for CRM Online.

    2) Added support for the generation of a Visual Studio 2010 project.

    3) Changed the naming convention of the export folder so that it also contains the date and time of the export.

    Here is how the new user interface looks:

    image

    You can find it on the Free Utilities page.

    Customization, Development, Dynamics CRM
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    389 views
  • Learning how to query for Marketing List Members

    Posted on July 5th, 2010 Mitch Milam Print Print No comments

    This morning I was adding some functionality to my Dynamics Tutorials site and needed to determine if a user was a member of a specific marketing list.

    No problem, I thought.  I opened up the most excellent Stunnware Tools to create the query.

    The only problem is that the Marketing List Member entity, listmember, does not support the RetreiveMultiple message, which means I can’t use QueryExpression to perform the query.

    After digging around a while, I found that I could use QueryExpression but I would have to use the LinkEntity property to properly assemble the query.  Here is what I came up with:

    bool retVar = false;
    
    QueryExpression query = new QueryExpression { EntityName = EntityName.list.ToString()};
    
    LinkEntity linkEntity1 = new LinkEntity { JoinOperator = JoinOperator.Natural,
                                              LinkFromEntityName = "list",
                                              LinkFromAttributeName = "listid",
                                              LinkToEntityName = "listmember",
                                              LinkToAttributeName = "listid",
                                              LinkCriteria = new FilterExpression() };
    
    linkEntity1.LinkCriteria.FilterOperator = LogicalOperator.And;
    
    linkEntity1.LinkCriteria.AddCondition(new ConditionExpression { AttributeName = "listid",
                                                                    Operator = ConditionOperator.Equal,
                                                                    Values = new Object[] { marketingListId } });
    
    linkEntity1.LinkCriteria.AddCondition(new ConditionExpression { AttributeName = "entityid",
                                                                    Operator = ConditionOperator.Equal,
                                                                    Values = new Object[] { userId } });
    
    query.LinkEntities.Add(linkEntity1);
    
    RetrieveMultipleRequest request = new RetrieveMultipleRequest { ReturnDynamicEntities = true, Query = query };
    RetrieveMultipleResponse response = (RetrieveMultipleResponse)crmService.Execute(request);
    
    retVar = (response.BusinessEntityCollection.BusinessEntities.Count > 0);

    How It Works

    1)  We start by querying the Marketing List Entity ( list ).

    2) We create a link entity that joins the Marketing List Member Entity to the Marketing List Entity.

    3) The search criteria is actually specified on the linked, Marketing List Member Entity.  We’re asking for a specific userId and a specific marketingListId.

    4) Next we add the linked entity to the query.

    5) Finally we prepare and execute the request.

     

    Since I am only interested if the contact exists within the marketing list, I simple set a boolean variable to true or false depending if the number of records returned ( found in the BusinessEntityCollection ) is greater than zero.

     

    References

    Customization, Development, Dynamics CRM
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    292 views
  • Exploring the CRM Metabase and Those ‘Of’ Attributes

    Posted on June 21st, 2010 Mitch Milam Print Print 1 comment

    The CRM Metabase web service allows you to retrieve Entity and Attribute information. If you’ve ever retrieved Entity information you may have noticed some interesting things about the list of attributes returned.

    Some of the attributes you will see are not normally displayed in the list of attributes you see when viewing the Entity from within the CRM user interface.

    I call these attributes the ‘Of’ attributes because they have properties that end with ‘Of' and are related to, or based on, other attributes.

    If we explore the CRM AttributeMetadata class you will see the following three properties:

    AggregateOf
    Gets the name of the attribute that aggregates the value of this property.

    AttributeOf
    Gets the name of that attribute that this attribute extends.

    CalculationOf
    The SDK description says 'For internal use only, but attributes with this property typically contain currency data.

     

    Here are examples of ‘Of’ Attributes:

    From the Contact Entity:

    Attribute Name Attribute Of
    parentcustomeridname parentcustomerid
    donotbulkemailname donotbulkemail

     

    From the Account Entity:

    Attribute Name Calculation Of
    Aging60_Base Aging60
    Revenue_Base Revenue

     

    From the Contact Entity:

    Attribute Name Aggregate Of
    owningteam ownerid
    accountid parentcustomerid

     

    So why is this important to me?

    Well, that depends on what you are doing with the Metabase.  If you are producing documentation, these attributes may or may not me useful to you.

    If you are using the Metabase web services to delete attributes, then these attributes are of no use to you because they can’t be deleted since they are maintained internally by CRM.  If you delete the ‘parent’ attribute, the related attribute is also deleted.  If you attempt to delete the internally generated attribute, you’ll receive an error.

     

    Checking for ‘Of’ attributes

    Here is how you check for ‘Of’ attributes using code:

    AttributeMetadata attribute = entityResponse.EntityMetadata.Attributes[0];
    
    if (
    (attribute.AttributeOf == null) &&
    (attribute.AggregateOf == null) &&
    (attribute.CalculationOf == null)
    )
    {
        // do something interesting
    }

    Customization, Development, Dynamics CRM
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    436 views
  • CRM SDK 4.0.12 Is Availalble

    Posted on May 6th, 2010 Mitch Milam Print Print No comments

    Microsoft Dynamics CRM SDK 4.0.12 is now available for download! This update contains some very exciting additions:

    Advanced Developer Extensions

    Advanced Developer Extensions for Microsoft Dynamics CRM, also referred to as Microsoft xRM, is a new set of tools included in the Microsoft Dynamics CRM SDK that simplifies the development of Internet-enabled applications that interact with Microsoft Dynamics CRM 4.0. It uses well known ADO.NET technologies. This new toolkit makes it easy for you to build an agile, integrated Web solution!

    Advanced Developer Extensions for Microsoft Dynamics CRM supports all Microsoft Dynamics CRM deployment models: On-Premises, Internet-facing deployments (IFDs), and Microsoft Dynamics CRM Online. The SDK download contains everything you need to get started: binaries, tools, samples and documentation.

    Authentication for Microsoft Dynamics CRM Online

    We have added new authentication documentation and sample code for Microsoft Dynamics CRM Online that does not require using certificates, making it easier for you to write code for your online solutions.

    Customization, Development, Dynamics CRM
    1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 4.00 out of 5)
    Loading ... Loading ...
    522 views
  • Recording Visual Studio 2010 with Camtasia 7

    Posted on April 23rd, 2010 Mitch Milam Print Print No comments

    I ran into an issue last night while recording a screencast of Visual Studio 2010.  Basically, Camtasia was not recording the menus when I selected them.  You could see me move and click my cursor, but the pop-up menus were not being displayed.

     

    Mike @ TechSmith support provided me with the solution:

    In Camtasia Recorder:

    1. Select Effects, Options.
    2. Click the Cursor tab.
    3. Uncheck the box for Make cursor effects editable in Camtasia Studio.
    4. Click OK to save your options.

     

    1. Next, select Tools, Options.
    2. Click the General tab
    3. Make sure that Capture layered windows is checked.
    4. Click OK to save any changes.

    That should take care of the problem.

     

    Note: when you make this change, it “freezes” the cursor so you can’t use cursor effects inside of Camtasia Studio.

     

    Also, we noticed that setting the Zoom feature of the editing window to 150% makes your code extremely readable on playback:

    image

    Development
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    636 views
  • Interesting Visual Studio 2010 Message of the Day

    Posted on April 16th, 2010 Mitch Milam Print Print No comments

    I got this today:

    image

    Uh, what user?

    Development
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    751 views
  • Using the DeliverIncomingEmail Message

    Posted on March 31st, 2010 Mitch Milam Print Print No comments

    Every now and again, you find an absolute gem within the CRM SDK.  And I’m not talking about a diamond-in-the-rough, I’m talking about a bright, shiny, put it in a ring kind.

    The DeliverIncomingEmail message is one of those gems.  Let’s take a look:

     

    What does it do?

    First and foremost, it takes information that exists within an email message that you retrieved from somewhere and creates a CRM Email Activity. This process could be a custom application you wrote, or in my case, a Simple Email Router.  Regardless of where the email comes from, this message will do all of the heavy lifting required to create the Email Activity.

     

    Usage:

    DeliverIncomingEmailRequest request = new DeliverIncomingEmailRequest
    {
        Subject = subject,
        From = from,
        To = to,
        Cc = cc,
        Bcc = bcc,
        MessageId = Guid.NewGuid().ToString(),
        ReceivedOn = CrmTypes.CreateCrmDateTimeFromUser(timeReceived),
        Body = body,
        SubmittedBy = to,
        Importance = "Normal",
        Attachments = new BusinessEntityCollection()
    };
    
    request.Attachments.EntityName = EntityName.activitymimeattachment.ToString();
    request.Attachments.BusinessEntities.Add(new activitymimeattachment());

     

    How It Works

    You complete the parameters of the message with information from the inbound email; things like To, From, Subject, Body, etc. the use the CrmService.Execute method to deliver the mail.  That’s it.

     

    Caveats

    MessageId is a Guid that can be either the ID of the message or a new Guid you supply.

    Attachments are required, even if you don’t have attachments.  In the example above, we have created a BusinessEntityCollection to hold our attachments, but never actually added any.  This will keep the Message from failing to process.

    To, Cc, Bcc can contain multiple email addresses that are separated by a comma ( , ).

     

    So why is this such a big deal?

    Did you notice that we are only supplying the email addresses of the people involved in the conversation?  When CRM processes this message, it will perform an automatic lookup and attempt to associate people with those email addresses.

    This is actually one of the few messages within the CRM SDK that doesn’t require an ID to perform a lookup or an association and saves you, the developer, a tremendous amount of time and effort.

    Development, Dynamics CRM, Email
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    501 views