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!!
Pingback: CRM 2011, C#: Connect CRM 2011 without using SDK/using .Net Framework 3.5 | Consult Rikin
For Native fields this works correctly but when i tried to create an entity record with Option set values, the response says that i have a namespaces problem.
How can i solve this problem?
Hi,
In your reference.cs , search “class Entity”, “class EntityReference”
Above these two partial classes, add these two lines
[System.Runtime.Serialization.KnownTypeAttribute(typeof(OptionSetValue))]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(EntityReference))]
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))]
Now, go to your actual code and for lookup field use like this:
myAttColl.Add(new KeyValuePair(“parentcustomerid”, new EntityReference() {Id = t.Id, LogicalName= t.LogicalName}));
Build the solution and it should work now.
Excellent @Rikin it worked perfectly, the only thing to get in mind is that the update of the web reference can undo all the changes over the reference.cs file, Tanks a lot
Pingback: CRM 2011, C#, v3.5: Type ‘OptionSetValue’ with data contract name ‘OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts’ is not expected | Consult Rikin
Hi, thanks for this helpful blog,
this if for creation, what if i want to update an entity from a custom aspx page?
Hi,
The update entity record will be similar to CRM SDK.
Thanks,
Rikin
Hi Expert ,
Awesome post , but i got stuck with Activity party field ,
I am currently trying to create Email record i could not able to set value for “From ” & “To” field .
Kindly provide me some sample on how to set value for “Activityparty”. (late bound)
Hi Expert ,
Awesome post , but i got stuck with Activity party field ,
I am currently trying to create Email record i could not able to set value for “From ” & “To” field .
Kindly provide me some sample on how to set value for “Activityparty”. (late bound)
Hi,
They are available everywhere…
Entity from1 = new Entity(“activityparty”);
Entity to1 = new Entity(“activityparty”);
Entity to2 = new Entity(“activityparty”); // two contacts inside the to field
from1[“partyid”]= new EntityReference(“systemuser”, userId);
to1[“partyid”]= new EntityReference(“contact”, contact1Id);
to2[“partyid”]= new EntityReference(“contact”, contact2Id);
Regards,
Rikin
Hi adding to your point ,
once i added KnownType of EntityCollection , it get worked.
[System.Runtime.Serialization.KnownTypeAttribute(typeof(EntityCollection))]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(OptionSetValue))]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(EntityReference))]
public partial class Entity { }
Thanks ,