AuthenticationResult.AcquireToken deprecated in ADAL 3.x and how to fix.

AuthenticationResult.AcquireToken deprecated in ADAL 3.x and how to fix.

When authenticating to Dyn 365 with S2S the following is a simple program using the S2S authentication which core I think I got originally got from my pal George Doubinski. I like to use it to test S2S. Very clean and easy to build on.

string organizationUrl = “<org url>”;string clientId = “<client id in Azure>”;string appKey = “<secret for the clientid>”;string aadInstance = “https://login.microsoftonline.com/”;string tenantID = “<contoso or whateveryouhave>.onmicrosoft.com”;

ClientCredential clientcred = new ClientCredential(clientId, appKey);AuthenticationContext authenticationContext = new AuthenticationContext(aadInstance + tenantID);AuthenticationResult authenticationResult = authenticationContext.AcquireToken(organizationUrl, clientcred);var requestedToken = authenticationResult.AccessToken;

using (OrganizationWebProxyClient sdkService = new OrganizationWebProxyClient(GetServiceUrl(organizationUrl), false)){sdkService.HeaderToken = requestedToken;OrganizationRequest request = new OrganizationRequest();
WhoAmIResponse response = sdkService.Execute(new WhoAmIRequest()) as WhoAmIResponse;

Console.WriteLine($”UserID:{response.UserId}”);Console.WriteLine(“Press any key to continue…”);Console.ReadKey();

}

However, the line:
AuthenticationResult authenticationResult = authenticationContext.AcquireToken(organizationUrl, clientcred);

Cloud computing – isn’t it great?

Requires ADAL version 2.x and the method AquireToken has been removed in the later version of that library.

If you look around the net, many advocate staying on 2.x version of the library but I didn’t have that option as I was integrating with Dyn 365 Operations and that was using the ver 3.x.

So, to make this work in version 3.x you just have to make a simple fix:

AuthenticationResult authenticationResult = authenticationContext.AcquireTokenAsync(ClientConfig.CRMOrgUrl, clientcred).Result;


Gustaf Westerlund
MVP, Founder and CTO at CRM-konsulterna AB
www.crmkonsulterna.se

How to get the URL to the reportserver programmatically

I was searching the net the other day to try to find a way to programmatically get the reporting server url from CRM. I thought that there must be some way to find it using the standard CRM webservice and I really looked throught the SDK and all the blogs I could find to see if anyone knew.

Finally I gave up and tried to find some other way to get it and I remembered that it is set in the registry so I wrote some code to get it from there and here it is in all it’s simple glory:

RegistryKey regkey = Registry.LocalMachine.OpenSubKey(@”SOFTWAREMicrosoftMSCRM”);
string reportserver = regkey.GetValue(“SQLRSServerURL”).ToString();

And it worked but only just since it uses the server name and my VPN connection to the customers environment didn’t bother with sending it to me why I have to manually add it to the hosts file.

The host file can be found at the path: C:WINDOWSsystem32driversetchosts

and I added the row:

192.168.0.100 CRMTESTSRV

Now my button which point to my aspx that redirects to a the report in pdf-format works just fine and is independant of the CRM server it is installed on.

The solution isn’t supported as far as I know since you never know if they might change the registry value in the future (not very likely in an update but might happen in an upgrade). If anyone has any supported way of getting this URL, please comment this post.

This could also be done using javascripts but I find it easier to manage server side code and it doesn’t add that much overhead considering the report has to be generated independantly of if I use aspx or javascript to open the report.

Gustaf Westerlund
Microsoft Dynamics CRM Architect

Logica
www.logica.com

Inactivating custom entities in code

I am currently working with as a sub consultant for what I beleive is Swedens foremost MS CRM supplier, Cybernetics, and ran into some problems when trying to deactivate a custom entity using code. I was unable to find any documentation at all in the latest version of the SDK but after a little searching, I found that Jonas Deibe at Microsoft Sweden, had the solution. Please have a look if you want to know how to do it:
http://blogs.msdn.com/jonasd/archive/2007/04/04/setting-status-with-setstatedynamicentityrequest.aspx

I’ll just give you some code my self:

SetStateDynamicEntityRequest req = new SetStateDynamicEntityRequest();
req.Entity = new Moniker();
req.Entity.Id = yfid;
req.Entity.Name = EntityName.cyb_yearlybusiness.ToString();
req.State = “inactive”; // = Deactivation
req.Status = -1;
service.Execute(req);

I have seen some very interesting “fake lookups” here at Cybernetics aswell, and I will soon be writing about how to create them.

Gustaf Westerlund
CRM and SharePoint Consultant

Humandata AB
www.humandata.se

Creating CRM-emails in C# code

I have in a previuos post described how to programmatically download a SQL RS report, create a CRM email and attach the report as a pdf to it and send it. This is quite many steps and sometimes it will just be good enough to send mails, for instance when developing addons for workflows.

email em = new email();

activityparty fromparty = new activityparty();
fromparty.partyid = new Lookup();
fromparty.partyid.type = EntityName.systemuser.ToString(); //Change to some other entity if needed.
fromparty.partyid.Value = FROM-SYSTEMUSER-GUID;
em.from = new activityparty[] { fromparty };

activityparty toparty = new activityparty();
toparty.partyid = new Lookup();
toparty.partyid.type = EntityName.contact.ToString(); //Change to some other entity if needed

toparty.partyid.Value = TO-CONTACT-GUID;
em.to = new activityparty[] { toparty };

em.subject = SUBJECT-STRING;
em.sender = “crm@example.com“;

em.regardingobjectid = new Lookup();
em.regardingobjectid.type = EntityName.REGARDING ENTITY TYPE.ToString();
em.regardingobjectid.Value = REGARDING OBJECT GUID;
em.description = BODY-STRING;

em.ownerid = new Owner();
em.ownerid.type = EntityName.systemuser.ToString();
em.ownerid.Value = OWNER-SYSTEMUSER-GUID;
Guid createdEmailGuid = service.Create(em);

SendEmailRequest req = new SendEmailRequest();
req.EmailId = createdEmailGuid;
req.TrackingToken = “”;
req.IssueSend = true;

// Send the email message.
SendEmailResponse res = (SendEmailResponse)service.Execute(req);

I find this code very helpfull. It can probably be generalized by using BusinessEntity object and so forth but I am usually quite satisfied with this.

Gustaf Westerlund
CRM and SharePoint Consultant

Humandata AB
www.humandata.se