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

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

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