CRM 2011 : all operations with pure OrganizationServiceClient call

After working with CRM 2011 for all kinds of crude operations(create, update, delete, share, unshare, activate, inactivate, owner assignment, retrieve) without using any external dll or class files(XRM.dll or early bound class generated by utiltool from sdk), it is quite visible to me that actually all the operations can be done using pure WCF call with the method “OrganizationRequest”. Also, to achieve this, we need to modify a few class definations in the Reference.cs class file auto generated by the WCF(.svc) call. I will summarize some earier ways to achieve this without making changes in Reference.cs file or any other external modifications:

1. Add CRM 2011 WCF Service Reference(.svc) to your ASP.NET project.

2. Add an external class file with the exact namespace of the Reference.cs file(this namespace consists of the namespace of the ASP.NET project with namespace of the Service Reference that you have added to above).

3. Add these below 3 partial classes without any definations to get rid of all unnecessary serialization errors with pure WCF calls to CRM 2011:

[System.Runtime.Serialization.KnownTypeAttribute(typeof(OptionSetValue))] // for AllColumns in Retrieve() / ColumnSet

 [System.Runtime.Serialization.KnownTypeAttribute(typeof(EntityReference))] // for AllColumns in Retrieve() / ColumnSet

 public partial class Entity{ }

 

[System.Runtime.Serialization.KnownTypeAttribute(typeof(OptionSetValue))]// for AllColumns in RetrieveMultiple() / ColumnSet

 [System.Runtime.Serialization.KnownTypeAttribute(typeof(EntityReference))] // for AllColumns in RetrieveMultiple() / ColumnSet

 public partial class EntityCollection{ }

 

[System.Runtime.Serialization.KnownTypeAttribute(typeof(EntityReference))] // for update owner, Share, Unshare

[System.Runtime.Serialization.KnownTypeAttribute(typeof(PrincipalAccess))] // update owner, Share, Unshare

[System.Runtime.Serialization.KnownTypeAttribute(typeof(OptionSetValue))] // inactivate, activate

 public partial class OrganizationRequest{ }

 

4. Below are the details for each type of crude operation to CRM(for details, please check the other blogs present in this site):

 CREATE/ UDATE/ DELETE: with pure  OrganizationServiceClient object 

(OrganizationServiceClient object).Create(Entity)/Update(Entity)/Delete(Entity, Entity id);

ACTIVATE/INACTIVATE : with the help of “OrganizationRequest” object.

OrganizationRequest _objInactivate = new OrganizationRequest() { Parameters = new ParameterCollection(), RequestName = “SetState” };

 SHARE/ UNSHARE: with the help of “OrganizationRequest” object.

OrganizationRequest _objShare = new OrganizationRequest() { Parameters = new ParameterCollection(), RequestName = “GrantAccess”/”RevokeAccess”};

 OWNER UPDATE(ASSIGNMENT) : with the help of “OrganizationRequest” object-

OrganizationRequest _objUpdateOwner = new OrganizationRequest(){ RequestName = “Assign”, Parameters = new ParameterCollection() };

 RETRIEVE/ RETRIEVEMULTPLE: with the help of “OrganizationRequest” object.

(OrganizationRequest object).RetrieveMultiple(Query object) / Retrieve(“entity”,”entity id”,”columnset”);

 

note: details of each operation type can be found on other blogs in this same site under my user id.

 

regards

joon

Advertisements

Inactivate, Activate in CRM 2011: using pure OrganizationRequest

Samething here, you need to add the below line to the  class “public partial class OrganizationRequest” in your Reference.cs file.

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

Then you can use the below code to activate, inactive with pure “OrganizationServiceClient” call.

 

Inactivate :

OrganizationRequest _objInactivate = newOrganizationRequest() { Parameters = newParameterCollection(), RequestName = “SetState”};

_objInactivate.Parameters.Add(new KeyValuePair<string, object>(“EntityMoniker”, newEntityReference() { Id = “guid of the account record”, LogicalName = “account”}));

_objInactivate.Parameters.Add(new KeyValuePair<string, object>(“State”, newOptionSetValue() { Value = 1 } ));

_objInactivate.Parameters.Add(new KeyValuePair<string, object>(“Status”, newOptionSetValue() { Value = 2 }));

(OrganizationServiceClient object).Execute(_objInactivate);

 

Activate:

OrganizationRequest _objActivate = new OrganizationRequest() { Parameters = new ParameterCollection(), RequestName = “SetState”};

_objActivate.Parameters.Add(new KeyValuePair<string, object>(“EntityMoniker”, new EntityReference() { Id = “guid of the account record”, LogicalName = “account”}));

_objActivate.Parameters.Add(new KeyValuePair<string, object>(“State”, newOptionSetValue() { Value = 0 }));

_objActivate.Parameters.Add(new KeyValuePair<string, object>(“Status”, newOptionSetValue() { Value = 1 }));

(OrganizationServiceClient object).Execute(_objActivate);

 

regards

joon

CRM 2011: using OrganizationServiceClient to RetrieveMultiple AllColumns (retrieve all columns using pure WCF call)

First of all, it must be said that CRM 2011 .svc file does not give you all the things that you need for all kinds of operations with CRM 2011. The Reference.cs is missing lots of things related to CRM only(like OptionSetValue, EntityReference etc.). Either you can have your own custom class file with partial classes to those from Reference.cs classes OR you can add some additional lines in your Reference.cs to make it work.

Here we are adding the additional lines to the Reference.cs file(to view this, click on “Show All Files” button at the top of Solution Explorer in Visual Studio, then click on “Service References” -> “your Service reference to CRM” -> “Reference.svcmap” -> “Reference.cs“). Add these below two lines to the class “public partial class EntityCollection” in your “Reference.cs” file generated by the WFC service call file.

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

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

 

Then you can use the below code to retrieve all the columns value with pure OrganizationServiceClient object.

QueryExpression query = new QueryExpression(){ EntityName = “systemuser” };

 query.Criteria = new FilterExpression();

query.Criteria.FilterOperator = LogicalOperator.And;

query.Criteria.Conditions = new ConditionExpression[] { new ConditionExpression() { AttributeName = “fullname”, Operator = ConditionOperator.Equal, Values = newstring[] { “name of the user” } } };

query.ColumnSet = new ColumnSet() { AllColumns = true, Columns = newstring[] { “”} };

 EntityCollection _entities = OrganizationServiceClient_Object.RetrieveMultiple(query);

 

Tricky part is : you have to set “Columns” to your QueryExpression columnset, even if you have set the “AllColums” to “true” to any dummy value. I have passed here “”. Then you have to let the EntityCollection class to know that there are something called “OptionSetValue” and “EntityReference” that it may need to talk with.

regards

joon

CRM 2011 : Using OrganizationServiceClient to Update owner, Share/ Unshare record (OrganizationRequest, Grant Access, Revoke Access)

I was trying to execute all kinds of operation using pure WCF call to CRM 2011, without adding any xrm dll or early bound class. To make the whole piece of code dynamic and free of any externsal source, it can be achieved by adding the WCF service end point(.svc end point) and using two methods provided by this call (“OrganizationServiceClient” and “OrganizationRequest”). In this section, I will try to update owner of newly created Account record and shaer/unshare that record to a system user.

Update owner :

OrganizationRequest _objIR = new OrganizationRequest(){ RequestName = “Assign”, Parameters = newParameterCollection() };

_objIR.Parameters.Add(newKeyValuePair<string, object>( “Assignee”, newEntityReference() { Id = newGuid(“system user id of new owner”), LogicalName = “systemuser”} ));

_objIR.Parameters.Add(new KeyValuePair<string, object>( “Target”, newEntityReference() { Id = “guid of account record”, LogicalName = “account”} ));

OrganizationServiceClient_object.Execute(_objIR1);

Share record:

OrganizationRequest _objIR1 = newOrganizationRequest() { Parameters = newParameterCollection(), RequestName = “GrantAccess”};

_objIR1.Parameters.Add(newKeyValuePair<string, object>( “Target”, newEntityReference(){ Id = “guid of account record”, LogicalName = “account”} ) );

_objIR1.Parameters.Add(newKeyValuePair<string, object>( “PrincipalAccess”newPrincipalAccess()

{ Principal =new EntityReference() { Id = newGuid(“system user id”), LogicalName = “systemuser”} , AccessMask = AccessRights.AppendAccess | AccessRights.AppendToAccess | AccessRights.CreateAccess | AccessRights.DeleteAccess |AccessRights.WriteAccess }  ) );

 OrganizationServiceClient_object.Execute(_objIR1);

 

UnShare record:

OrganizationRequest _objUnShare = new OrganizationRequest() { Parameters = newParameterCollection(), RequestName = “RevokeAccess”};

_objUnShare.Parameters.Add(newKeyValuePair<string, object>(“Target”, newEntityReference() { Id = _accCreated, LogicalName = “account”}));

_objUnShare.Parameters.Add(newKeyValuePair<string, object>(“Revokee”, newEntityReference(){Id =

 new Guid(“system user id of the revokee”),LogicalName =“systemuser” } ) );

OrganizationServiceClient_objectt.Execute(_objUnShare);

 Note: you may face the serialization error while trying to perform these operations, since in the current WCF call there is no specific methods to serialize objects of “EntityReference” and “PrincipalAccess”(since they are specific to CRM only). One way to solve is to add an defination for these methods that will serialize their objects.

This can be achieved by adding beloe lines to “public partialclass OrganizationRequest” in Reference.cs class file of the WFC service file :: 

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

There should be some way to solve this issue without adding these two definations. I will post as soon as I find it.

regards

joon

WHAT IS COM, ODBC, OLEDB, ADO

While communicating among various systems from different platforms/technologies(say it ASP.NET or Java), we always come across some basic terms such as ODBC or OLEDB. More importantly COM components. For Microsoft technologies, ADO.NET(ActiveX) or OLEDB is more prominent. Though the basic aim for all these terms are about to be same, there are some differences present among them.

Hierarchical flow for these techniques as per usability restriction and availability for other systems(among heterogeneous systems), from highest to lowest

COM -> OLEDB -> ODBC -> ADO

COM(Component Object Model) : developed by Microsoft. It is not an interface, not methods, not technique. But an idea you can say to enable communication among different heterogeneous systems. Components(commonly known as COM component) can be created in any language based on neccessity and can be used across platforms and technologies.

ODBC(Open Database Connectivity) : developed by “SQL Access Group” which later modified by “Microsoft” and “Simba Tehcnologies” to term it as ODBC. Main use is to access Relational databases(DBMS). This is an interface between the other interfaces and the DBMS. It is based on COM logic.

OLEDB(Object Linking and Embedding Database) : Developed by Microsoft. Successor of ODBC with the additional capability to communicate with non-relational databases such as file system, exchange server file, email etc. It sits purely on the top of COM, actually OLEDB are set of methods(routines) to use COM for communication among various systems. Hence we can say, [ OLEDB = ( ODBC + Non Relational DB Access) ].

ADO(ActiveX Data Object) : Microsoft developed ADO specific to Microsoft related technologies to talk with systems. It is an API that Microsoft allows developer to use and access Relational/ Non-relational DBMS. Bsically ADO uses OLEDB which in turns uses COM logic.

ClickOnce common bugs

Common ClickOnce errors and how to resolve them:

1. Increase the “Publish version” and “publish”
2. Copy all the contents from folder “Application Files”, not the single updated version folder and replace the whole folder in the server completely
3. If error comes, remove contents from folder : “C:\Documents and Settings\UserName\Local Settings\Apps”
4. Check the “Installation Folder URL (if different than above)”. Its should contain path upto the folder name, not the “publish.htm” page

links for reference:

http://stackoverflow.com/questions/1059340/clickonce-error-missing-files-need-to-get-missing-filename
http://msdn.microsoft.com/en-us/library/ms229001.aspx

Get Language specific Month Name from SQL

Since you cannot use data modified scripts inside funcations in SQL server, you cannot use SET LANGUAGE inside a fucntion. Here is the way to get the month name in particular language in SQL server. You can use this function anywhere you want, anywhere you want to call.

Create a scalar valued function with any name, here I am using “fn_GetMonthName”.

Call this function with two parameters passd : “select dbo.fn_GetMonthName ( ‘2012-12-12’, ‘French’)” i.e. first parameter is the datetime value and secod parameter is the language that you want the month in from the date mentioned here.

For example, to get the name of current date in Spanish, you can use :

select dbo.fn_GetMonthName ( GetDate(), ‘Spanish)”

output : Febrero

====================================

CREATE FUNCTION [dbo].[fn_GetMonthName]
( @Date DateTime, @Language NvarChar(100))
RETURNS nvarchar(400)
AS

BEGIN
declare @i int, @m int,@mlist NVARCHAR(1000)

set @m = month(@Date)
set @mlist = (SELECT months FROM sys.syslanguages where alias = @language)
set @i = 1

while(@i < @m)
begin
           set @mlist = replace(@mlist, substring(@mlist,1,charindex(‘,’,@mlist)) ,”)
           set @i = @i + 1
end

set @mlist = (case charindex(‘,’,@mlist) when 0 then @mlist else substring(@mlist,0,charindex(‘,’,@mlist) ) end )
return @mlist
END
GO

====================================