CRM 2013: Cannot specify child attribute retrieve – MergeRequest C#

Hello!

If you are working on code to merge two entity records and come across “Cannot specify child attribute retrieve” error; and you have referred SDK/MSDN documentation. You probably have kept UpdateContent property optional and havent set it. UpdateContent is a required property though the documentation says it is not.

This property is optional in case of merging incidents only.

You just have to set Entity object to UpdateContent property which has attributes to be updated to the merged record.

Entity contact = new Entity("contact");
contact["firstname"] = "Crm";
contact["lastname"] = "Xpress";
 
// merging contact records
MergeRequest merge = new MergeRequest
{
    // SubordinateId is the GUID of the contact merging.
    SubordinateId = contactId,
    Target = target,
    PerformParentingChecks = true,
    UpdateContent = contact // Entity Object to set the content you want updated on the merged contact
};

HTH!
Happy Merging!

CRM 2011, C#, v3.5: Type ‘OptionSetValue’ with data contract name ‘OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts’ is not expected

We already have discussed how to achieve connection of CRM 2011 through .net version 3.5 from below mentioned post. https://consultrikin.wordpress.com/2013/09/20/crm-2011-c-entity-class-redefined-with-net-framwork-3-5-to-connect-crm-2011/

Once this is achieved and you start working on CRUD operations, you will find some run time exceptions thrown like one I have described below.

Type ‘OptionSetValue’ with data contract name ‘OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts’ is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types – for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.’.  Please see InnerException for more details.

The same thing will be repeated for EntityReference and PicklistAttributeMetadata.

Resolution:

1. Explore the reference.cs from the project in Windows Explorer and open it.

2. Search for class Entity and class EntityReference

3. Add below lines to both partial classes.
     [System.Runtime.Serialization.KnownTypeAttribute(typeof(OptionSetValue))]
     [System.Runtime.Serialization.KnownTypeAttribute(typeof(EntityReference))]

4. Now search for “class OrganizationRequest”.
Add these lines above it:

     [System.Runtime.Serialization.KnownTypeAttribute(typeof(EntityReference))]
     [System.Runtime.Serialization.KnownTypeAttribute(typeof(PrincipalAccess))]
     [System.Runtime.Serialization.KnownTypeAttribute(typeof(OptionSetValue))]

5. Continue adding to classes for which you’re getting these exceptions.

6. Build the solution and run your code again.

Happy Programming! 🙂

CRM 2011, C#: OrganizationRequest and OrganizationResponse with .Net version 3.5

We already discussed how a CRM 2011 web service can help us create object of OrganizationServiceProxy or Instance of IOrganizationService in my previous posts. This is the case when we’re not using assemblies from SDK and thus several SDK request and response messages will not be available to you like RetrieveAttributeRequest/Response etc.

All we have is OrganizationRequest and OrganizationResponse and in this case you will have to use OrganizationRequest and OrganizationResponse to request data from CRM 2011. See below example which uses similar example for RetrieveAttributeRequest.

OrganizationRequest request = new OrganizationRequest();
request.RequestName = "RetrieveAttribute";
request.Parameters = new ParameterCollection();
request.Parameters.Add(new KeyValuePair<string, object>("EntityLogicalName", "salesorder"));
request.Parameters.Add(new KeyValuePair<string, object>("RetrieveAsIfPublished", true));
request.Parameters.Add(new KeyValuePair<string, object>("LogicalName", "new_cardtype"));

try
{
    OrganizationResponse response = (OrganizationResponse)CrmHelper.OrgService.Execute(request);
    PicklistAttributeMetadata picklist = (PicklistAttributeMetadata)response.Results[0].Value;
}
catch (FaultException<OrganizationServiceFault> ex)
{
    throw new Exception("Error details: " + ex.Message);
}

Happy Programming!

CRM 2011, C#: Entity Class redefined with .net framwork 3.5 to connect CRM 2011

Look at my previous post on connecting CRM 2011 using .net framework 3.5 without CRM 2011 SDK. https://consultrikin.wordpress.com/2013/09/19/crm-2011-c-connect-crm-2011-without-using-sdkusing-net-framework-3-5/

Here, if you use Entity Class to create Entity records the same way we create records in .net framework 4.0 with SDK in late bound; this requires following syntax.

Entity entity = new Entity();
entity.LogicalName = "contact";
entity.Attributes = new ServiceReference1.AttributeCollection();
entity.Attributes.Add(new KeyValuePair<string, object>("firstname", "test first name"));
entity.Attributes.Add(new KeyValuePair<string, object>("lastname", "test last name"));
OrgService.Create(entity);

Here, you must add an attribute value as a new KeyValuePair<string, object>. Or you need to access the attributes by their indexes like:

Entity entity = new Entity();
entity.LogicalName = "contact";
entity.Attributes = new ServiceReference1.AttributeCollection();
entity.Attributes[0] = "test first name";
entity.Attributes[1] = "test last name";
OrgService.Create(entity);

This code does not have readability as you need to find int index every time you access entity. While I found the same extended Entity Class from the posts I mentioned in my previous post. Here they are listed. Just add them to your project and you will be able to add attributes with string parameters.

/// <summary>
/// Entity Class
/// </summary>
partial class Entity
{
	/// <summary>
	/// Initializes a new instance of the <see cref="Entity" /> class.
	/// </summary>
	public Entity()
	{
		this.FormattedValuesField = new FormattedValueCollection();
		this.RelatedEntitiesField = new RelatedEntityCollection();
	}

	/// <summary>
	/// Gets the attribute value.
	/// </summary>
	/// <typeparam name="T"></typeparam>
	/// <param name="attributeLogicalName">Name of the attribute logical.</param>
	/// <returns></returns>
	public T GetAttributeValue<T>(string attributeLogicalName)
	{
		if (null == this.Attributes)
		{
			this.Attributes = new AttributeCollection();
		};
		object value;
		if (this.Attributes.TryGetValue(attributeLogicalName, out value))
		{
			return (T)value;
		}

		return default(T);
	}

	/// <summary>
	/// Gets or sets the <see cref="System.Object"/> with the specified attribute name.
	/// </summary>
	/// <value>
	/// The <see cref="System.Object"/>.
	/// </value>
	/// <param name="attributeName">Name of the attribute.</param>
	/// <returns></returns>
	public object this[string attributeName]
	{
		get
		{
			if (null == this.Attributes)
			{
				this.Attributes = new AttributeCollection();
			};

			return this.Attributes.GetItem(attributeName);
		}
		set
		{
			if (null == this.Attributes)
			{
				this.Attributes = new AttributeCollection();
			};

			this.Attributes.SetItem(attributeName, value);
		}
	}
}

And Add following Class-

/// <summary>
/// CollectionExtensions Class
/// </summary>
public static class CollectionExtensions
{
	/// <summary>
	/// Gets the item.
	/// </summary>
	/// <typeparam name="TKey">The type of the key.</typeparam>
	/// <typeparam name="TValue">The type of the value.</typeparam>
	/// <param name="collection">The collection.</param>
	/// <param name="key">The key.</param>
	/// <returns>returns TValue</returns>
	/// <exception cref="System.Collections.Generic.KeyNotFoundException">Key =  + key</exception>
	public static TValue GetItem<TKey, TValue>(this IList<KeyValuePair<TKey, TValue>> collection, TKey key)
	{
		TValue value;
		if (TryGetValue(collection, key, out value))
		{
			return value;
		}

		throw new System.Collections.Generic.KeyNotFoundException("Key = " + key);
	}

	/// <summary>
	/// Sets the item.
	/// </summary>
	/// <typeparam name="TKey">The type of the key.</typeparam>
	/// <typeparam name="TValue">The type of the value.</typeparam>
	/// <param name="collection">The collection.</param>
	/// <param name="key">The key.</param>
	/// <param name="value">The value.</param>
	public static void SetItem<TKey, TValue>(this IList<KeyValuePair<TKey, TValue>> collection, TKey key, TValue value)
	{
		int index;

		if (TryGetIndex<TKey, TValue>(collection, key, out index))
		{
			collection.RemoveAt(index);
		}

		//If the value is an array, it needs to be converted into a List. This is due to how Silverlight serializes
		//Arrays and IList<T> objects (they are both serialized with the same namespace). Any collection objects will
		//already add the KnownType for IList<T>, which means that any parameters that are arrays cannot be added
		//as a KnownType (or it will throw an exception).
		Array array = value as Array;
		if (null != array)
		{
			Type listType = typeof(List<>).GetGenericTypeDefinition().MakeGenericType(array.GetType().GetElementType());
			object list = Activator.CreateInstance(listType, array);
			try
			{
				value = (TValue)list;
			}
			catch (InvalidCastException)
			{
				//Don't do the conversion because the types are not compatible
			}
		}

		collection.Add(new KeyValuePair<TKey, TValue>(key, value));
	}

	/// <summary>
	/// Determines whether the specified collection contains key.
	/// </summary>
	/// <typeparam name="TKey">The type of the key.</typeparam>
	/// <typeparam name="TValue">The type of the value.</typeparam>
	/// <param name="collection">The collection.</param>
	/// <param name="key">The key.</param>
	/// <returns>returns true or false</returns>
	public static bool ContainsKey<TKey, TValue>(this IList<KeyValuePair<TKey, TValue>> collection, TKey key)
	{
		int index;
		return TryGetIndex<TKey, TValue>(collection, key, out index);
	}

	/// <summary>
	/// Tries the get value.
	/// </summary>
	/// <typeparam name="TKey">The type of the key.</typeparam>
	/// <typeparam name="TValue">The type of the value.</typeparam>
	/// <param name="collection">The collection.</param>
	/// <param name="key">The key.</param>
	/// <param name="value">The value.</param>
	/// <returns>returns true or false</returns>
	public static bool TryGetValue<TKey, TValue>(this IList<KeyValuePair<TKey, TValue>> collection, TKey key, out TValue value)
	{
		int index;
		if (TryGetIndex<TKey, TValue>(collection, key, out index))
		{
			value = collection[index].Value;
			return true;
		}

		value = default(TValue);
		return false;
	}

	/// <summary>
	/// Tries the index of the get.
	/// </summary>
	/// <typeparam name="TKey">The type of the key.</typeparam>
	/// <typeparam name="TValue">The type of the value.</typeparam>
	/// <param name="collection">The collection.</param>
	/// <param name="key">The key.</param>
	/// <param name="index">The index.</param>
	/// <returns>returns true or false</returns>
	private static bool TryGetIndex<TKey, TValue>(IList<KeyValuePair<TKey, TValue>> collection, TKey key, out int index)
	{
		if (null == collection || null == key)
		{
			index = -1;
			return false;
		}

		index = -1;
		for (int i = 0; i < collection.Count; i++)
		{
			if (key.Equals(collection[i].Key))
			{
				index = i;
				return true;
			}
		}

		return false;
	}
}

Happy Programming!!

Could not load file or assembly ‘microsoft.crm.sdk.proxy’ or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.

Hello!!

If you are getting below error when you have deployed your web application which connects to Microsoft Dynamics CRM 2011 online/on premise version.

Could not load file or assembly ‘microsoft.crm.sdk.proxy’ or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.

Then probably you have used wrong IIS Application Pool. You might want to change the .Net version of assigned Application Pool to 4.0. And re-run the site.

This should solve the error you were facing.

C#: Set Dictionary as a data source for Drop Down List

There are situations when you need to create a list of key pair values after fetching data from the database and attach them to some Web Controls on your web page. Unlike Windows Application where you can attach whole Data List of Class to the control and the controller will act as a container, Web Controls do not support the same way. Either you need to create a new class with two properties; one for Key and second for Value part.

In this case, you can go for using Disctionary<T key, T value>, T can be used as any datatype with standard .Net datatype. You can go through the loop and create a new Dictionary object and assign the Dictionary object to the web control. And set DataTextField to Key and DataValueField to Value.

Dictionary<string, string> list = new Dictionary<string, string>();
list.Add("item 1", "Item 1");
list.Add("item 2", "Item 2");
list.Add("item 3", "Item 3");
list.Add("item 4", "Item 4");

dropDownList.DataSource = list;
dropDownList.DataTextField = "Value";
dropDownList.DataValueField = "Key";
dropDownList.DataBind();

CRM 2011 Web Page Error: The server was unable to process the request due to an internal error either from ServiceBehaviorAttribute or from the configuration behavior

I was working with a web application which connects to the CRM 2011 Organization Web Service. While developing it through Visual Studio the application was working like a charm! And as soon as I published it to the IIS 7, it began showing me following error and stack trace.

The server was unable to process the request due to an internal error.  For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.ServiceModel.FaultException: The server was unable to process the request due to an internal error.  For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs.

Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[FaultException: The server was unable to process the request due to an internal error.  For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs.]
System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) +4767763
System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) +1725
Microsoft.Xrm.Sdk.IOrganizationService.Execute(OrganizationRequest request) +0
Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy.ExecuteCore(OrganizationRequest request) +892
xxxxxxxTool.xxxxxContacts.Page_Load(Object sender, EventArgs e) in C:\Users\Administrator\Desktop\xxxxxxxTool\xxxxxxxTool\xxxxxContacts.aspx.cs:173
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +25
System.Web.UI.Control.LoadRecursive() +71
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3048

Looking at the error details, I was not sure what was wrong with a piece of code I wrote! I didn’t even used .Net Framework 3.0 SDK?!? With some findings on net I found some attributes for ServiceBehaviors that should be added to web.config shown as below.

<behaviors>
  <serviceBehaviors>
    <behavior name="SecurityTokenServiceBehavior">
      <!--The serviceMetadata behavior allows one to enable metadata (endpoints, bindings, services) publishing.
This configuration enables publishing of such data over HTTP GET.
This does not include metadata about the STS itself such as Claim Types, Keys and other elements to establish a trust.-->
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true" />
      <!--Default WCF throttling limits are too low-->
      <serviceThrottling maxConcurrentCalls="65536" maxConcurrentSessions="65536" maxConcurrentInstances="65536" />
    </behavior>
  </serviceBehaviors>
</behaviors>

This was not sufficient as error was still there! I thought I had a problem with my IIS, I reinstalled it! Still there is same error. I checked to the other PCs but the issue persisted. Finally I got the solution by some R&D on IIS part.

Through MSDN I found that the Applications made for CRM or using any web services of CRM 2011 will need the same configuration as CRM App Pool. If the application will not consume more, you can use the same App Pool that CRM 2011 web application uses.

The Similar AppPool created for the application must be running on Classic mode and Identity should be Network Service.

And some authentication settings to the web application developed for the CRM will help the application run without issues on IIS 7. Follow this image for Authentication to web application to set.

Authentication Settings

Authentication Settings

Anonymous Authentication should be Disabled. CRM needs Windows Authentication, Enable it. And there is no need to have a Forms Authentication, Disable it.

After all these settings your application should work as expected.

Happy Troubleshooting!!

Telerik RadGrid: Get updated values from controls in Edit mode

Hello,

This is the most common issue when new comers can not find the values they have updated from the Telerik RadGrid when editing a Grid Row data. You might want to use the UpdateCommand event to capture the Update event bubble from the Telerik RadGrid.

Now, when you create a new event method from Visual Studio, you will get GridCommandEventArgs as the second parameter which will be used to Render all the columns.

Follow below code to get the idea how a value from the TextBox and a CheckBox will be retrieved from the Grid in the Edit mode when the update command is given.

You will need to go through each Column to check if the column is editable or not. For TextBoxes you will find GridTextColumnEditor and CheckBoxes you will find GridCheckBoxColumnEditor to fetch the updated data. Now once you have got the data, you can go ahead and update the DataSet and Rebind the grid to reflect the change of Data.

/// <summary>
/// Handles the UpdateCommand event of the AttributesRadGrid control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="GridCommandEventArgs"/> instance containing the event data.</param>
protected void AttributesRadGrid_UpdateCommand(object sender, GridCommandEventArgs e)
{
    string labelText = string.Empty;
    bool isDisabled = false;

    GridEditableItem editedItem = e.Item as GridEditableItem;
    GridEditManager editManager = editedItem.EditManager;
    foreach (GridColumn column in e.Item.OwnerTableView.RenderColumns)
    {
        if (column is IGridEditableColumn)
        {
            IGridEditableColumn editableCol = column as IGridEditableColumn;
            if (editableCol.IsEditable)
            {
                IGridColumnEditor editor = editManager.GetColumnEditor(editableCol);
                if (editor is GridTextColumnEditor)
                {
                    labelText = (editor as GridTextColumnEditor).Text;
                }

                if (editor is GridCheckBoxColumnEditor)
                {
                    isDisabled = (editor as GridCheckBoxColumnEditor).Value;
                }
            }
        }
    }

    // Load your DataSet to update the data
    // update the data from the DataSet

    this.something[index].Label = labelText;
    this.something[index].IsDisabled = isDisabled;

    // Rebind the RadGrid to show the updated data that is just updated to DataSet
    this.AttributesRadGrid.Rebind();
}

GridEditableItem: Represents the base class for any items that display and edit data in a Telerik.Web.UI.GridTableView of RadGrid. Inheritors has the capabilities to: Locate a table cell based on the column unique names Extract values from the cells of column editors Has a dictionary of saved-old-values that are necessary for optimistic concurency editing oprations Edit/browse mode EditManager instance, which is capable of locating the column editors.

Hope this helps! Happy Programming!!