MS CRM 2016: organization service not working

I was trying to access on-premise MS CRM 2016 organization service through Visual Studio. But it seems be not working when we use the format like we had before:

http://Name_Of_Crm_Tenant/XRMServices/2011/Organization.svc

I could add this as Service Reference as well as Web service in my visual studio 2013 projects, but it was not giving me the OrganizationService methods.

Searched a lot, and finally found that in order to access the OrganizationService and its methods/ classes, you will need to twist a little bit to the service URL. There is an extra parameter needs to be added to the end of the current format, which is the SDK version:

http://Name_Of_Crm_Tenant/XRMServices/2011/Organization.svc?singleWSDL&sdkversion=8.0

till example:

http://myCrmTenant:5555/XRMServices/2011/Organization.svc?singleWSDL&sdkversion=8.0

And here you go, you have all the methods available as it is. We find a link that says a little about this: https://msdn.microsoft.com/en-us/library/gg309401.aspx

Towards the end of this link, you will read : “Using the WSDL: To add a service reference for these services to a Microsoft Visual Studio project, you must append ?WSDL to the service URL when specifying the address in the Add Service Reference dialog box. For example, the discovery service Web Services Description Language (WSDL) address ishttp[s]://servername/xrmservices/2011/discovery.svc?wsdl.

The web services support SDK versioning. Specifying an SDK version in the WSDL URL indicates a scope for the amount of data to be returned in the WSDL. The syntax for web service SDK versioning ends the URL in ?singleWSDL&sdkversion=X.X. For example, the URL would behttps://mydomain.crm.dynamics.com/xrmservices/2011/discovery.svc?singleWSDL&sdkversion=8.0. In this example, you would have built your application using the Microsoft Dynamics CRM SDK v8.0 assemblies.”

Hope this will save some time for others.

 

Note: if you want to use MS CRM 2016 XRM dlls, and Visual Studio 2013 for development, and if you face issues while accessing the methods of XRM dlls, check your Visual Studio Framework.

For Visual Studio 2013, you must have “.Net Framework 4.5.2” installed, else you cannot access the XRM dlls. And go for “Microsoft .NET Framework 4.5.2 Developer Pack”.

Rest everything seem to be same as of MS CRM 2011/ 2013. I tried the same crude operations with/ without XRM dlls, and they work pretty much same(same code that I used in other parts of this blog).

 

regards

joon

GeoCode data retrieve(Latitude, Longitude) for Maps application (C# with third party APIs)

Recently we had a project which was related to show items on google map embedded inside CRM interface(MS CRM) based on the address of the items, e.g. show nearest accounts to my current location and some other details. We had the address of the items from a source system.

Challenges faced :

1. embedd google map to CRM interface

2. get latitude, longitude of the items based on address

3. fetch and display the items based on the geocode data

On the top of it, this was needed to support mobility(CRM Mobile apps) where it should support both Online and Offline(after synchronising to local device and working without network connection). This was taken care of a third party apps.

In short, our main aim is to get longitude, latitude based on address fields. We tried 3 different ways, google api, bing api and mapquest api. These companies provide an api which can be accessed through codes(C#, JSon, JavsScript etc, both server side and client side).

Google Api:

This is pretty good, only thing a premium account is needed to make regular updates. If you have fixed budget, this is not a good option, as per google they provide approx 2500 hits per day but they have blocked us since we were doing it again and again for quite a few days 🙂 (https://developers.google.com/maps/documentation/geocoding/ ). Below is the code sample to access latitude, longitude based on address available. We passed the request to the Google api and in return accepted the response in XML format(there are other response type also, say JSon).

Pre requisites:

Based on your need, either in corporate level or personal level and number of data to be retrieved, you have to order separate types of keys from Google. Basically there are two keys that are important:

1. Cryptographic key

2. Client Id

Once you have ordered and receive those above two keys, here is the simple piece of code to use an address to retrieve longitude and latitude values. In my case, I have used the address in this format : “Street Number” + “Street Name” + “City” + “Country”; you can provide zip code or second street name etc. also. I would say, it is preferable to replace the spaces in the address string by “+”.

CODE SECTION FOR C#:
——————————————————————————————————————————————-
XmlDocument doc = new XmlDocument();
string clientId = "your-ordered-clientid-from-Google"; //replace this with your client id              
string key = "cryptokey-ordered-from-Google"; //replace this with your cryptographic key
string address ="StrretNumber+Streetname,+CityName,+Country"; //replace this with your addess
 
var urlRequest = "/maps/api/geocode/xml?address=" + address + "&client=" + clientId;
System.Security.Cryptography.HMACSHA1 myhmacsha1 = new System.Security.Cryptography.HMACSHA1();
myhmacsha1.Key = Convert.FromBase64String(key);
var hash = myhmacsha1.ComputeHash(System.Text.Encoding.ASCII.GetBytes(urlRequest));
string signature = Convert.ToBase64String(hash).Replace("+", "-").Replace("/", "_");
 
WebRequest.DefaultWebProxy.Credentials = CredentialCache.DefaultNetworkCredentials;
 
doc.Load("https://maps.googleapis.com/maps/api/geocode/xml?address= " + address + "&client=" + clientId +"&signature=" + signature);
 
string longitude = doc.SelectSingleNode("//GeocodeResponse/result/geometry/location/lng").InnerText;
string latitude = doc.SelectSingleNode("//GeocodeResponse/result/geometry/location/lat").InnerText;

——————————————————————————————————————————————-

The detailed instructions can be found on this link:https://developers.google.com/maps/documentation/business/webservices/auth

regards

bhaskar jyoti

CRM 2011 : RetrieveAllColumns all rows ::: The maximum message size quota for incoming messages (524288) has been exceeded. To increase the quota, use the MaxReceivedMessageSize

To solve the above issue while retrieving all columns, all rows in CRM 2011, if you are using pure OrganizationServiceClient object, you can try either modifying in the app.config file OR using a line of code.

1. Increase the “maxReceivedMessageSize” and “maxBufferSize” in the app.config file to some large integer values such as “2147483647”. Note that both values should be same.

<httpTransport maxReceivedMessageSize=2147483647maxBufferSize=2147483647..“”>

2. Now, you can either use app.config change or use one line of code :

 

App.Config file change: add below section inside <system.serviceModel> section in your app.config file <behaviors><endpointBehaviors><behaviorname=ClientBehavior><dataContractSerializer maxItemsInObjectGraph=2147483647/></behavior></endpointBehaviors></behaviors>

 Then add the behaviorConfiguration=”ClientBehavior” in <client> section in the same config file as shown below. Here name of the behaviourConfiguration “ClientBehaviour” is the same as we have added above.

<client><endpointaddress=http://../XRMServices/2011/Organization.svcbinding=..bindingConfiguration=..contract=name=behaviorConfiguration=ClientBehavior>

 

Use of code: Use the below line of code before RetrieveMulitple line.

(OrganizationServiceClient object).Endpoint.Contract.Operations.Find(“RetrieveMultiple”).Behaviors.Find<System.ServiceModel.Description.DataContractSerializerOperationBehavior>().MaxItemsInObjectGraph = int.MaxValue;

 

 Thats it. It will let you have upto 20 Mb of data with the paging of 5000 rows depending on size at one CRM call.

Reference : http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.maxitemsinobjectgraph.aspx

regards

joon

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

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