However, there is a problem with this function, it returns the base server URL which is the one registered in CRM deployment manager. When you work with a CRM form or web resource, you don't want to use the base server URL directly, instead you need the local server URL that hosts the current form or web resource. For instance, if the user is using a URL which is different from what's in deployment manager, say IP address or a domain alias, the URL will cause cross-domain calls, which will fail.
For this reason, I have baked a solution today which might be able to address this issue universally for all scenarios (hopefully).
var getServerUrl = function () { var context, crmServerUrl; if (typeof GetGlobalContext != "undefined") { context = GetGlobalContext(); } else if (typeof Xrm != "undefined") { context = Xrm.Page.context; } else { throw new Error("CRM context is not available."); } if (context.isOutlookClient() && !context.isOutlookOnline()) { crmServerUrl = window.location.protocol + "//" + window.location.host; } else { crmServerUrl = context.getServerUrl(); crmServerUrl = crmServerUrl.replace(/^(http|https):\/\/([_a-zA-Z0-9\-\.]+)(:([0-9]{1,5}))?/, window.location.protocol + "//" + window.location.host); crmServerUrl = crmServerUrl.replace(/\/$/, ""); // remove trailing slash if any } return crmServerUrl; };In the code snippet, I assumed that a server host name can only be made of English, numeric characters, _ (underscore), . (dot), - (dash).
If you are using Silverlight web resource, you need to translate the code to C#, which shouldn't be something difficult. [Update - Please refer to my another blog post for C# code that works for Silverlight]
Although I am bluntly positive that this could solve the problem universally, but there might be exceptional scenarios that I am not currently aware. If that's the case, please let me know by leaving a comment below, I will try to come up with something better. ;-)
Thanks for reading, hope this helps.
Hello Daniel,
ReplyDeleteWhy not to use relative urls like
var url = Xrm.Page.prependOrgName("Your Url");?
Hi Andrii, if you construct url that way, you might have trouble with CRM offline client, although I haven't confirmed if that's the case. The goal of my post is to replace CRM getServerUrl function, since that's widely used in the CRM development practice, and it's causing a lot of trouble.
DeleteIt should work without issue. I've noticed that getServerUrl can create a lot of issues that's why I use relative urls in JavaScript that I develop.
DeleteSo you would do this way?
ReplyDeletevar odataEndpointUrl = Xrm.Page.prependOrgName("/XRMServices/2011/OrganizationData.svc");
Yes, I use it in my code. Should work without issues.
ReplyDeleteOfftopic - see you in 3 days ;)
Hey, Andrii. You are right, perpendOrgName works for offline client, hopefully it works for CRM online and IFD deployment (I don't have an environment to verify either of them).
DeleteJust one minor note, it's Xrm.Page.context.prependOrgName, I was trapped by Xrm.Page.prependOrgName. ;-)
During my testing, I realized, CRM returns http://localhost:2525 instead of the base server URL when getServerUrl() function is called for offline client. So I have updated my post to reflect this.
Thanks for your tips, see you at the summit.
prependOrgName will return empty string when using the context from ClientGlobalContext.js.aspx and not from CRM form.
ReplyDeleteI believe because the IS_PATHBASEDURLS variable is not defined in the ClientGlobalContext.js.aspx, and this is needed in prependOrgName function.
Hi Daniel,
ReplyDeleteIn my case it doesn't work but I think there is a problem with the configuration.
This is a CRM 2011 RU11 and I have configured to access by https.
I have 3 different ways to access:
1.-Within the LAN
If I type https://servername there is no problem, but if I type the IP adrress instead the name of the server, the access denied error appears.
2.-By internet
https://crm.domain-name.com I obtain the access denied error too. I have not configured the enviroment as an IFD.
In all the cases before entering to CRM system a certificate error appears.
I hope you can help me.
Regards
That's strange, can you check what you get after calling the method? Do you see a different server name?
DeleteI have a Dynamics instance with a custom host header, and my REST calls were failing, so I replaced getServerUrl(); with "/" + Xrm.Page.context.getOrgUniqueName(); and it works great.
ReplyDeleteThe URL is relative then, which seems to work fine as Adrii points out.
I do all my calls from the CRM page, not any custom pages that use the ClientGlobalContext.js.aspx which apparently doesn't work (see posting above..)
very helpful post for me
ReplyDeletemysql services