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!

Advertisements

C#: Security accessibility of the overriding method must match the security accessibility of the method being overriden

I was porting a .Net 2.0 assembly to .Net 4.0 plugin assembly and faced this particular challenge.

The project had a test app(A WinForm app) and it worked fine on the desktop but when I deployed the logic on server to run as a plugin it gave the following error

xyz..GetObjectData(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext) Security accessibility of the overriding method must match the security accessibility of the method being overriden.
Just notice, the spelling for “overridden” is also not correct. But this is what .Net framework threw.
After some research I found that this behavior is “By Design” i.e. as per security transparency model defined in .Net v4.0. It basically has two models:
1. Level1 (High Level) for v2.0
2. Level2 for v4.0
Here is a a list of critical operations:

1. Call native code

2. Contain unverifiable code

3. Call critical code

4. Perform security asserts

5. Satisfy link demands

6. Derive from non-transparent types

7. Override security critical virtuals

And only full trust code can be security critical.

Hence an overridden member should have the same security accessibility (Critical, Safe Critical or Transparent).
To resolve this error take the following step:
Go to the AssemblyInfo.cs class to your project and add following attributes to it. And this should resolve the exception.

[assembly: SecurityRules(SecurityRuleSet.Level1)] 
[assembly: AllowPartiallyTrustedCallers]

I believe it might be helpful to many as there are lot of Dynamics CRM implementations being upgraded.

Reference links to the differences between both and transparency rules:
http://blogs.msdn.com/b/shawnfa/archive/2009/11/12/differences-between-the-security-rule-sets.aspx
http://blogs.msdn.com/b/shawnfa/archive/2009/11/03/transparency-101-basic-transparency-rules.aspx

C#: Get Current Month Name and Short Name

We had a requirement to get the current month name and its short name (example- November|Nov). While DateTime class does not provide these methods out of .net framework, we had to create methods which gives the similar output.. We have created similar methods through Extension Methods supported with recent .net framework.

Extension methods can be used as instance methods and it uses “this” keyword as a parameter. They are static and they must be defined on static class.

Here is the solution:

using System;
using System.Globalization;

namespace TestConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(DateTime.Today.Day + "." + DateTime.Today.Month + "." + DateTime.Today.Year);
            Console.WriteLine(DateTime.Now.AddMonths(-2).ToMonthName());
            Console.WriteLine(DateTime.Now.ToShortMonthName());
            
            // Update: Similar functionality can be achieved through below statements also.
            // Thanks Michael for inputs.
            Console.WriteLine(String.Format("{0:MMMM}", DateTime.Now));
            Console.WriteLine(String.Format("{0:MMM}", DateTime.Now));
            Console.WriteLine(DateTime.Now.ToString("MMMM"));
            Console.WriteLine(DateTime.Now.ToString("MMM"));
        }
    }

    static class DateTimeExtensions
    {
        public static string ToMonthName(this DateTime dateTime)
        {
            return CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(dateTime.Month);
        }

        public static string ToShortMonthName(this DateTime dateTime)
        {
            return CultureInfo.CurrentCulture.DateTimeFormat.GetAbbreviatedMonthName(dateTime.Month);
        }
    }
}

Output:
28.11.2014
September
Nov

Extension Methods in Visual Studio appears with special symbol:

Extension Methods

Extension Methods

Reference: http://www.dotnetperls.com/extension

C#: The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log or use the command-line sxstrace.exe tool for more detail.

Hello guys,

Before some time I had a situation where my console application would not run and without showing any screen/anything else it gave me this alert mentioned below:

The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log or use the command-line sxstrace.exe tool for more detail.

Most of the google links will guide you to check your VC++ runtime and their versions. I checked everything and everything was as expected as other applications were working smooth without any error.

Also, I checked with a simple “Hello world!” console application but the output was same. And with no clue to my mind I removed the .config file from the directory.

If same is your situation then, suggested solution would be to rename the extension of the .config file to .xml file and run/parse it to any browser. In my case the .xml file did not meet with the standards as an value contained & (ampersand) and it was breaking the it to be well formed xml document.

Check with the standard list of invalid xml characters so that you can avoid this kind of situation in future. Check this link – http://www.w3.org/TR/2000/REC-xml-20001006#charsets to see well-formed xml document rules.

C#: Converting from Generic List to CSV and CSV to Generic List

CSV from List

public string GetCsvFromList(List<string> list)
{
    return String.Join(",", list.Select(x => x.ToString()).ToArray());
}

List from CSV

public List<T> GetListFromCsv<T>(string commaSplited)
{
    return (from e in commaSplited.Split(',')
            select (T)Convert.ChangeType(e.Trim(), typeof(T))).ToList();
}

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&#8217; 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#: 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!!

CRM 2011, C#: Connect CRM 2011 without using SDK/using .Net Framework 3.5

Recently I had a situation where I was already done with coding with C# 4.0 and CRM 2011 SDK. The issue was the project was built on Visual Studio 2008 with .Net framework 3.5. Now the client did not mention that they do not want to move to .Net framework 4.0. But to use CRM 2011 SDK assemblies I had to convert it to 4.0. I had to convert the project back to .Net framework 3.5.

I searched for solution to this issue and found an interesting posts on MSDN and  this post just follow these steps and connect CRM 2011 with .net framework 3.5:

Steps:

1. Create a .Net project with framework 3.5.

2. Add a web service reference of your organization service – (i.e. http://<server >:<port>/<Organization Name>/XRMServices/2011/Organization.svc?wsdl)

3. You will get all the methods offered by OrganizationService. Check the screenshot.

CRM 2011 Service Reference

CRM 2011 Service Reference

4. Finally Add the following method so that you can get CRM 2011 Service Object.

/// <summary>
/// Gets or sets the org service.
/// </summary>
/// <value>
/// The org service.
/// </value>
public static IOrganizationService OrgService { get; set; }

/// <summary>
/// Gets the CRM service.
/// </summary>
/// <param name="serverHost">The server host.</param>
/// <param name="organizationName">Name of the organization.</param>
/// <param name="userName">Name of the user.</param>
/// <param name="domain">The domain.</param>
/// <param name="password">The password.</param>
public static void GetCRMService(string serverHost, string organizationName, string userName, string domain, string password)
{
    Uri OrgUri = new Uri(string.Format("{0}/{1}/XRMServices/2011/Organization.svc", serverHost, organizationName));

    SymmetricSecurityBindingElement symmetricSecurityBindingElement = new SymmetricSecurityBindingElement();
    symmetricSecurityBindingElement.ProtectionTokenParameters = new SspiSecurityTokenParameters();

    HttpTransportBindingElement httpTransportBindingElement = new HttpTransportBindingElement();
    httpTransportBindingElement.MaxReceivedMessageSize = 1000000000;

    CustomBinding customBinding = new CustomBinding();
    customBinding.Elements.Add(symmetricSecurityBindingElement);

    TextMessageEncodingBindingElement textMessageEncodingBindingElement = new TextMessageEncodingBindingElement(
        MessageVersion.Soap12WSAddressing10, Encoding.UTF8);
    customBinding.Elements.Add(textMessageEncodingBindingElement);
    customBinding.Elements.Add(httpTransportBindingElement);

    EndpointAddress endpointAddress = new EndpointAddress(OrgUri);

    OrganizationServiceClient organizationServiceClient = new OrganizationServiceClient(customBinding, endpointAddress);
    organizationServiceClient.ClientCredentials.Windows.ClientCredential = new NetworkCredential(userName, password, domain);

    OrgService = (IOrganizationService)organizationServiceClient;
}

You now have IOrganizationService instance with all required methods available with CRM 2011 SDK.

Find more about this on my next blog post: https://consultrikin.wordpress.com/2013/09/20/crm-2011-c-entity-class-redefined-with-net-framwork-3-5-to-connect-crm-2011/

CRM 2011, C# Error: The given key was not found in the dictionary.

Many a times unexpected things happen while programming. And in case of Dynamics CRM it “does” happen. Similar issue happened with me today. The subject of the blog post was the annoying error I wanted to get rid off.

The given key was not found in the dictionary.

The first thing comes into the programmers’ mind is that there is nothing in this error and they just need to cross check with the attribute logical names they have used in coding.

To solve this I cross checked each and every attributes from Dynamics CRM and my C# code and not for single but 3-4 times. Finally, I got the idea that all my code is working absolutely correct with nothing wrong in it.

The real issue was not my code but a plugin/workflow activity developed by some other programmer which was registered on the same entity which I was working on. I disabled the step of the workflow activity and the program worked like a charm.

Check for the Plugins or Workflow Activities registered on the same entity to drill down with your issue.

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.