Browsing SharePoint server from Word not possible

Quite puzzled today when I tried to save a file from Word to SharePoint. I got the message “You can’t open this location using this program. Please try a different location”. After googling a little bit I found a solution for my problem. This only seems to be happening when you try to open or save files to SharePoint from office application on a Windows Server OS. In my case the OS was Windows Server 2008 R2 so that checked out correctly.

To solve the problem you need to install the feature “Desktop Experience”.

- Go to Server Manager
- Click on “Features”
- Click on “Add Features”
- Select “Desktop Experience” and install additional required components if Windows asks you to

image

- Click “Next”
- Click “Install”
- Restart the server

Get optionset text from value or value from text

Here are two functions I use on a regular base when working with optionsets in CRM 2011 development projects. When you request an optionset attribute you will get an object of the type “OptionSetValue”. This object contains the value of the selected item. Sometimes this is enough but sometimes you want to retrieve the textual value behind this numeric value. Or sometimes you need to set a certain value in an optionset based on a value. If you then only have the text value, then you need a way to retrieve the numeric value behind that text value. For these common problems I have two methods:

/// <summary>
/// This function is used to retrieve the optionset value using the optionset text label
/// </summary>
/// <param name="service"></param>
/// <param name="entityName"></param>
/// <param name="attributeName"></param>
/// <param name="selectedLabel"></param>
/// <returns></returns>
private int GetOptionsSetValueForLabel(IOrganizationService service, string entityName, string attributeName, string selectedLabel)
{

    RetrieveAttributeRequest retrieveAttributeRequest = new
    RetrieveAttributeRequest
    {
        EntityLogicalName = entityName,
        LogicalName = attributeName,
        RetrieveAsIfPublished = true
    };
    // Execute the request.
    RetrieveAttributeResponse retrieveAttributeResponse = (RetrieveAttributeResponse)service.Execute(retrieveAttributeRequest);
    // Access the retrieved attribute.
    Microsoft.Xrm.Sdk.Metadata.PicklistAttributeMetadata retrievedPicklistAttributeMetadata = (Microsoft.Xrm.Sdk.Metadata.PicklistAttributeMetadata)
    retrieveAttributeResponse.AttributeMetadata;// Get the current options list for the retrieved attribute.
    OptionMetadata[] optionList = retrievedPicklistAttributeMetadata.OptionSet.Options.ToArray();
    int selectedOptionValue = 0;
    foreach (OptionMetadata oMD in optionList)
    {
        if (oMD.Label.LocalizedLabels[0].Label.ToString().ToLower() == selectedLabel.ToLower())
        {
            selectedOptionValue = oMD.Value.Value;
            break;
        }
    }
    return selectedOptionValue;
}
/// <summary>
/// This function is used to retrieve the optionset labek using the optionset value
/// </summary>
/// <param name="service"></param>
/// <param name="entityName"></param>
/// <param name="attributeName"></param>
/// <param name="selectedValue"></param>
/// <returns></returns>
private string GetOptionsSetTextForValue(IOrganizationService service, string entityName, string attributeName, int selectedValue)
{

    RetrieveAttributeRequest retrieveAttributeRequest = new
    RetrieveAttributeRequest
    {
        EntityLogicalName = entityName,
        LogicalName = attributeName,
        RetrieveAsIfPublished = true
    };
    // Execute the request.
    RetrieveAttributeResponse retrieveAttributeResponse = (RetrieveAttributeResponse)service.Execute(retrieveAttributeRequest);
    // Access the retrieved attribute.
    Microsoft.Xrm.Sdk.Metadata.PicklistAttributeMetadata retrievedPicklistAttributeMetadata = (Microsoft.Xrm.Sdk.Metadata.PicklistAttributeMetadata)
    retrieveAttributeResponse.AttributeMetadata;// Get the current options list for the retrieved attribute.
    OptionMetadata[] optionList = retrievedPicklistAttributeMetadata.OptionSet.Options.ToArray();
    string selectedOptionLabel = null;
    foreach (OptionMetadata oMD in optionList)
    {
        if (oMD.Value == selectedValue)
        {
            selectedOptionLabel = oMD.Label.LocalizedLabels[0].Label.ToString();
            break;
        }
    }
    return selectedOptionLabel;
}

Iterating over requiredattendees in an appointment

In this sample code I will show you how to iterate over the requiredattandees attribute of an appointment. This  attribute is a list of activityparty records. An activityparty record can contain many different entity types, for example contacts and accounts:

proxy.EnableProxyTypes();
//If you want to iterate over every appointment use a RetrieveMumltipleRequest
var appointment = proxy.Retrieve(Appointment.EntityLogicalName,new Guid("FC8C427B-26AE-E111-ADAD-000C29CBD80B"),new ColumnSet(true));
List<ActivityParty> party = ((Appointment)appointment).RequiredAttendees.ToList<ActivityParty>();
foreach (ActivityParty ap in party)
{
    //You can retrieve metadata about a contact or an account by performing a new request
    if(ap.PartyId.LogicalName == Contact.EntityLogicalName)
        Console.WriteLine(string.Format("It's a contact with id {0}",ap.PartyId.Id));
    else if (ap.PartyId.LogicalName == Account.EntityLogicalName)
        Console.WriteLine(string.Format("It's an account with id {0}", ap.PartyId.Id));
}

General exception while creating an appointment in CRM 2011

Some time ago I had a serious problem when I tried to add the apppool user to CRM 2011. When I did that, not a single user could access CRM2011 anymore. I think, not sure, that it had something to do with the AD groups where the apppool user is a member of. I think that when I added that user to CRM2011 something changed and it messed up the windows permissions of that user. The trick was to delete every record manually from the CRM 2011 database where that user’s GUID was linked to. I know it’s not supported but it solved my problem.

Today I was trying to create an appointment and this resulted in a General Exception. Pretty weird but immediately I thought it had something to do with that same user from a couple of weeks ago because the GUID showed up in the errorlog:

Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: Pointer record exists but referenced record of type 8 not found: aa60799f-49a3-e111-8444-000c29cbd80b

Scratching my head I was thinking: what can I do now? I thought I went through every table in CRM 2011 looking for that systemuserid.

I enabled tracing to see what exactly was going on. In the log I found the following query:

SELECT TOP 1000 [DisplayInServiceViews]
      ,[ObjectTypeCode]
      ,[BusinessUnitId]
      ,[CalendarId]
      ,[IsDisabled]
      ,[ResourceId]
      ,[VersionNumber]
      ,[OrganizationId]
      ,[Name]
      ,[SiteId]
  FROM [LRMDEPLOYMENT_MSCRM].[dbo].[ResourceBase]

This is the point where the error was returned. Now I knew that I missed a table. When an appointment is created CRM2011 probably tries to lookup all the available resources for scheduling. In this table there was still a reference to that “bad” userid and it resulted in an error. I removed this record and I could create my appointment.