Calling Custom Web Services Through MSCRM 3.0 Form – A way to Duplicate Detection
Here is a sample code for calling custom web services through MSCRM 3.0 Form. This sample code checks duplicate accounts during account creation or updating.
Put this java script code at OnSave event for Account Form. This code calls our duplicate detection web service at CRM server machine:
var url = “/DuplicateDetection/DuplicateDetection.asmx/CheckDuplicateAccount”;
var msg = “”;
try
{
// Use xmlhttp connection to web server
var oXmlHTTP = new ActiveXObject(“Msxml2.XMLHTTP”); // Open connection to web service
oXmlHTTP.Open(“POST”, url, false); // We set a header to tell the browser we are sending posted data
oXmlHTTP.setRequestHeader(“Content-Type”, “application/x-www-form-urlencoded”) // Build query string based on entered values
var qs = “name=” + document.all.name.value;
qs += “&objectguid=” + crmForm.ObjectId; // Send request, passing in the request string
oXmlHTTP.Send(qs); var result = “”;
// Check to see if we have a valide response
if ((oXmlHTTP.responseXML.xml) != null && (oXmlHTTP.responseXML.xml.toString().length > 0))
{
// The service will return the result in a string node.
result = oXmlHTTP.responseXML.selectSingleNode(“string”).text;
}
msg = result;
}
catch(e)
{
msg = “There was an error with your submission. Please try again. Error:” + e.message;
} // Display our results back to the user.
if(msg.length > 0)
{
alert(msg);
}
Here is code for the web method for our duplicate detection webservice:
[WebMethod]
public string CheckDuplicateAccount(string objectguid, string name)
{
CrmService service = new CrmService();
service.Credentials = System.Net.CredentialCache.DefaultCredentials;
if(objectguid == null || objectguid == string.Empty )
{
//Code for checking account records at creation time
try
{
QueryExpression query = new QueryExpression();
query.EntityName = EntityName.account.ToString();// Create a set of columns to return.
ColumnSet cols = new ColumnSet();
cols.Attributes = new string [] {“name”};// Create the ConditionExpression.
ConditionExpression condition = new ConditionExpression();
condition.AttributeName = “name”;
condition.Values = new string[] {name};// Builds the filter based on the condition
FilterExpression filter = new FilterExpression();
filter.FilterOperator = LogicalOperator.And;
filter.Conditions = new ConditionExpression[] {condition};
query.ColumnSet = cols;
query.Criteria = filter;// Retrieve the values from Microsoft CRM.
BusinessEntityCollection retrieved = service.RetrieveMultiple(query);
if(retrieved.BusinessEntities.Length > 0 )
{
return “Duplicate record exists for : ” + name;
}else
{
return “”;
}
}
catch(System.Web.Services.Protocols.SoapException se)
{
return “ERROR: ” + se.Detail.InnerText;
}
}
else {//Code for checking account records at updation time
try{
QueryExpression query = new QueryExpression();
query.EntityName = EntityName.account.ToString();// Create a set of columns to return.
ColumnSet cols = new ColumnSet();
cols.Attributes = new string [] {“name”};// Create the ConditionExpression.
ConditionExpression condition1 = new ConditionExpression();
condition1.AttributeName = “name”;
condition1.Values = new string[] {name};
condition1.Operator = ConditionOperator.Equal;
ConditionExpression condition2 = new ConditionExpression();
condition2.AttributeName = “accountid”;
condition2.Values = new string[] {objectguid};
condition2.Operator = ConditionOperator.NotEqual;// Builds the filter based on the condition
FilterExpression filter = new FilterExpression();
filter.FilterOperator = LogicalOperator.And;
filter.Conditions = new ConditionExpression[] {condition1, ondition2};
query.ColumnSet = cols;
query.Criteria = filter;// Retrieve the values from Microsoft CRM.
BusinessEntityCollection retrieved = service.RetrieveMultiple(query);
if(retrieved.BusinessEntities.Length > 0 )
{
return “Duplicate record exists for : ” + name;
}
else
{
return “”;
}
}catch(System.Web.Services.Protocols.SoapException se)
{
return “ERROR: ” + se.Detail.InnerText;
}
}

Hello!
Is this a real working code for CRM 3.0 Duplicate Detection?
Can you send us the code for Contacts and Accounts detection?
Thanks
Serge
well Serge,
Yes, this is a real working code but only for duplicate account detection by name. Not throughly tested yet. This code only gived you an idea of how to call webservices which in turn check for duplicate records. In this, web service you can introduce you own methods for checking duplicate contacts.
Regards,
Ayaz
Ayaz,
Thanks for reply.
Do we have to do anything special with your web service? (Publish? Where? How?)
Somehow JavaScript getting nothing from this web service?
Thanks!
Serge
Hi Serge,
Its just a sample application build in hurry although it works. My web service return empty string in case account does not exist in MSCRM. It return Error message in case Account exist in MSCRM. You can program your webservice as per your requirements.
Regards,
Ayaz
Hi Ayaz
Thanks for the solution.
I was searching for a simple solution to learn MSCRM Services.
This one really helped.
Keep posting such solutions.
Thanks Manish
After using this technique with some minor modifications Ive found that I can only get this service to work while accessing it from the crm server. If I try it from an external client (intranet) the service appears to return nothing. Im new to web services and CRM in general and while researching these topics Ive seen mention of proxy services. Now these seem to be client side implementations necissary to utilized web services. I see nothing in the CRM documentation that discusses how to set them up. Is there something I need to do to get this code working out side of the server? Maybe security settings? Or is there a way to implement a proxy into the crm client?
Thanks for any help you can give.
Hi Jon,
Are you using proper impersonation in your code? Is your calling user is a
member of PrivUserGroup .
Impersonation is used to execute business logic (code) on behalf of a
Microsoft CRM user in order to provide a desired feature or service.
Try to imtroduce impersonation in your web.config file by adding following
tag:
>identity impersonate=”true” username=”myUserName”
password=”myPassword”>
this username should be a member of PrivUserGroup.
You can even introduct impersonation in your code as follows:
CrmService myService = new CrmService();
myService.Url = “http://localhost/mscrmservices/2006/crmservice.asmx”;
myService.Credentials = new
NetworkCredential(“PrivUserName”,”PrivUserPassword”,”PrivUserDomain”)
For in detail description of security groups (PrivUserGroup) please check
this post:
http://ayazahmad.wordpress.com/2007/01/26/active-directory-security-groups-for-mscrm/
Hope this helps.
Regards,
Ayaz
Thanks for the help. Unfortunately Ive already added impersonation to the code in the manner you have suggested. Any other suggestions for allowing access to the customizations from client machines?
You also may want to try this on a machine other than the server, and
alter your ActiveX settings on the browser to accommodate these
controls. (Tools->Security, select the area which the webservice falls
into and click custom level. There is a whole section of ActiveX
security settings that can prevent the web services from executing
properly.)
Ive already tried this as well. Do you think there could be a problem with Strong Naming? Ive seen it mentioned but dont know too much about it. Ive had to set it up once (sn.key etc) for a different .net application but Im not sure its necissary here. Do I need to add an SN key to the assembly when compiling this and then the mykey.snk file to the GAC?
Thanks again for all your help and patience w/ me.
well jon,
If possible then post your code here. both web service and the web service calling code. i will try my level best to figure out things where no working.
Im terribly sorry I should have done that in the first place. Let me lay out how I have things set up here. Currently we have one development server which has only development environments and an IIS set up. We use this for immediate debugging and quick testing. When it looks like it works I copy the files from this server over to the CRM server in the directory specified by CRM-IIS. If I run the client from on the CRM server it works perfectly as expected. As soon as I get off the server and try to access it from any number of other computers it fails (in the case of the current code I get a msg box w/ “0 a” as the message). As you can see I have added ‘debugging code’ to every code path so I could see what was happening and when.
Thank you so much for all of your help this has been haunting me for nearly two weeks now and I am at my wits end.
Server names and the security impersonation have been renamed for web posting.
—Start JS
var url = “\DupService\DuplicateDetect.asmx/CheckDuplicateAccount”;
var msg = “2″;
try
{
// Use xmlhttp connection to web server
var oXmlHTTP = new ActiveXObject(“Msxml2.XMLHTTP”);
// Open connection to web service
oXmlHTTP.Open(“POST”, url, false);
// We set a header to tell the browser we are sending posted data
oXmlHTTP.setRequestHeader(“Content-Type”, “application/x-www-form-urlencoded”)
// Build query string based on entered values
var qs = “name=” + document.all.name.value;
// Send request, passing in the request string
oXmlHTTP.Send(qs);
var result = “3″;
// Check to see if we have a valid response
if ((oXmlHTTP.responseXML.xml) != null && (oXmlHTTP.responseXML.xml.toString().length > 0))
{
// The service will return the result in a string node.
result = oXmlHTTP.responseXML.selectSingleNode(“string”).text;
}
else
{
result = oXmlHTTP.responseXML.xml.toString().length + ” a”;
}
msg = result;
}
catch(e)
{
msg = “There was an error with your submission. Please try again. Error:” + e.message;
}
// Display our results back to the user.
if(msg.length > 0)
{
alert(msg);
event.returnValue = false;
return false;
}
—End JS
—Start Web service Code
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Web;
using System.Web.Services;
using DupService.crmSDK;
namespace DupService
{
///
/// Duplicate Detection web service for CRM
///
public class DuplicateDetect : System.Web.Services.WebService
{
#region Account Duplication Check
[WebMethod(CacheDuration = 30, Description = "Detects Duplicate Accounts.")]
public string CheckDuplicateAccount(string name)
{
CrmService service = new crmSDK.CrmService();
service.Url = “http://my-crmServer/mscrmservices/2006/crmservice.asmx”;
service.Credentials = new System.Net.NetworkCredential(“myAdminAccount”, “adminpassword”, “mydomain.com”);
//service.Credentials = System.Net.CredentialCache.DefaultCredentials;
try
{
ColumnSet cols = new ColumnSet();
cols.Attributes = new string [] {“name”};
ConditionExpression condition = new ConditionExpression();
condition.AttributeName = “name”;
condition.Operator = ConditionOperator.Equal;
condition.Values = new string [] {name};
FilterExpression filter = new FilterExpression();
filter.Conditions = new ConditionExpression[] {condition};
QueryExpression query1 = new QueryExpression();
query1.EntityName = EntityName.account.ToString();
query1.ColumnSet = cols;
query1.Criteria = filter;
RetrieveMultipleRequest retrieve1 = new RetrieveMultipleRequest();
retrieve1.Query = query1;
BusinessEntityCollection retrieved = service.RetrieveMultiple(query1);
if(retrieved.BusinessEntities.Length > 0 )
{
return “Duplicate record exists for : ” + name;
}
else
{
return “1″;
}
}
catch(System.Web.Services.Protocols.SoapException se)
{
return “ERROR: ” + se.Detail.InnerText;
}
}
#endregion
#region Contact Duplication Check
[WebMethod(CacheDuration = 30, Description = "Detects Duplicate Contacts.")]
public string CheckDuplicateContact(string fname, string lname)
{
CrmService service = new CrmService();
service.Credentials = System.Net.CredentialCache.DefaultCredentials;
service.Credentials = new System.Net.NetworkCredential(“myAdminAccount”, “adminpassword”, “mydomain.com”);
try
{
ColumnSet cols = new ColumnSet();
cols.Attributes = new string[] {“firstname”, “lastname”};
ConditionExpression condition = new ConditionExpression();
condition.AttributeName = “lastname”;
condition.Operator = ConditionOperator.Equal;
condition.Values = new string[] {lname};
ConditionExpression condition2 = new ConditionExpression();
condition2.AttributeName = “firstname”;
condition2.Operator = ConditionOperator.Equal;
condition2.Values = new string[] {fname};
FilterExpression filter = new FilterExpression();
filter.FilterOperator = LogicalOperator.And;
filter.Conditions = new ConditionExpression[] {condition, condition2};
QueryExpression query1 = new QueryExpression();
query1.EntityName = EntityName.contact.ToString();
query1.ColumnSet = cols;
query1.Criteria = filter;
RetrieveMultipleRequest retrieve1 = new RetrieveMultipleRequest();
retrieve1.Query = query1;
BusinessEntityCollection retrieved = service.RetrieveMultiple(query1);
if (retrieved.BusinessEntities.Length > 0)
{
return “A Duplicate record exsists for contact: ” + fname + ” ” + lname;
}
else
{
return “”;
}
}
catch(System.Web.Services.Protocols.SoapException se)
{
return “ERROR: ” + se.Detail.InnerText;
}
}
#endregion
}
}
I need help. I am tring to publish this project and it fails. can any one help me here.
I can not build it nor can I put it in the CRM server.
Can some one provide instructions on how to get this built?
thank you
godmcse
My appology to Jon Beschen as i have not yet tested his code due to work load these days.
Godmcse:
Well Godmcse, if you are trying the orginal code in the post then let me tell you that this is not a single project. It contains a web service for Duplicate Detection mechanism and java script code to be called from CRMForm.
So please create a web service project and paste that web service code there. Then try to build that project and publish. its written in VS2003.
Secondly, paste the javascipt code to your CRMForm events or control events to validate record.
Hope this helps,
Regards,
Ayaz
Can u replay me wht is purpose of passing accountid
Well Prabhu, as i have already mentioned in my post that its a working sample not a well polished code. So, the purpose of passing account id is simply checking that weather account is being checked at create time or update time. In case of account creation i simply send null and in case of updation i am sending account guid. You can even send flags like create or update to identity that account is being checked at creation time of updation time.
Hope this helps.
Ayaz
Thanks for your replay ayaz,I have created a web service in my machine and ur coding is working well.so i deploy this project in the crm server.when i check for the duplicate accounts i am getting the following error
“Their was an error with your submission,Plz try again:error “unknown name” “.My problem is similar to “Jon Beschen ”
PLz give me solutionnnnnnn
Hello Ayaz,
I have indeed tried out all the ways.
But I am not able to get the correct result even though I do not get any error.
What I mean to say is that a duplicate account is created even after I add this javascript to my CRM Onsave event.
The Web Service runs perfectly fine when I run it from Visual Studio environment by passing parameters.
I donno what the error is in the javascript code.
Please help me out.
Hi Susan,
Well things are working fine at my end. If you are still facing problems then please add me (ayaz.ahmad@hotmail.com) in your messager list and i will try my level best to help you out.
Ayaz
Hello ayaz,
I really cant figure out where I am making amistake.
I am not able to pass parameters through the web service call.
Help me out .
Regards,
Swati
Hello,
I have same problem as Prabhu. Please help.
Prabhu Says:
May 22nd, 2007 at 6:13 am
Thanks for your replay ayaz,I have created a web service in my machine and ur coding is working well.so i deploy this project in the crm server.when i check for the duplicate accounts i am getting the following error
“Their was an error with your submission,Plz try again:error “unknown name” “.My problem is similar to “Jon Beschen ”
PLz give me solutionnnnnnn
Hi Ayaz,
I’ve created a WebService Project, put the java script code at OnSave event for Account Form.
Where do i need to put the WebService Code, as i never create any webservice for MS CRM?
Could you pls let me know the step by step procedure, if psbl.
Thanks,
Raj
Imad/Prabhu,
While moving your web service solutions, have you ppl updated your web services references? Are you sure your wev services is accessible by simply calling through browser. Please confirm?
Raj:
1) You need to develop a web services soltion at your CRM server.
2) then this java script code is used to call that web service at your CRM server.
Hope this all helps,
Ayaz
This code may fail if the following line which use name attribute for duplicate check contains & symbol. One should check and see if the name field contains & symbole then replace with & to get this working.
var qs = “name=” + document.all.name.value;
Otherwise interesting concept if you quick feedback through jscript instead of using precallout event model.
Regards,
Sanjay
Hello,
I have same problem as “Jon Beschen” with other custom web service.
1. on CRM server work all OK
2. on Client PC I get blank xml.
3. on Client PC I see the WebService in IE.
4. when i add a breakpoint in to WebService method in VS2005 (on CRM SERVER), and call it from Client PC, don’t break.
pls. help
Svafko.
Hi, I found reason why it is not work from client, I forgot:
“This technique provides an excellent mechanism for allowing your client scripts to communicate with outside services and systems. To allow these commands, we need to allow the virtual Web to accept the Get and Post protocols for a Web service. This can be done by updating the Web.config file’s node located in your workingwithcrm virtual Web with the following:
” – Microsoft.Press.Working.with.Microsoft.Dynamics.CRM.3.0
Bye
Hi, I found reason why it is not work from client, I forgot:
“This technique provides an excellent mechanism for allowing your client scripts to communicate with outside services and systems. To allow these commands, we need to allow the virtual Web to accept the Get and Post protocols for a Web service. This can be done by updating the Web.config file’s node located in your workingwithcrm virtual Web with the following:
” – Microsoft.Press.Working.with.Microsoft.Dynamics.CRM.3.0
Bye
Hi, I found reason why it is not work from client, I forgot:
“This technique provides an excellent mechanism for allowing your client scripts to communicate with outside services and systems. To allow these commands, we need to allow the virtual Web to accept the Get and Post protocols for a Web service. This can be done by updating the Web.config file’s node located in your workingwithcrm virtual Web with the following:
<webServices>
<protocols>
<add name=”HttpGet”/>
<add name=”HttpPost”/>
</protocols>
</webServices>
============
< is
============
” – Microsoft.Press.Working.with.Microsoft.Dynamics.CRM.3.0
Bye
Hi Ayaz,
Of course the Webservice reference is updated.
I think it is a kind of security reason, although it is on the same domain.
Regards
well if domain is same then try to introduce impersonation into application. otherwise there is a common problem of doule hop problem. try to explore it, may solve ur problem.
Hi Ayaz,
Tried compiling the codes. The web service works well in my Visual Studio. It detects the duplication of accounts and the output is generated via IE. Can’t seem to get in work via the onSave functionality on the Account form.
Hope someone can help me out on this….
Thanking all in advance.
revathi
Rechecck your java script code. its case senstive so be carefull in this regard.
Regards,
Ayaz
Hello Ayaz
You done great job. But you miss out something. See the line below it is from your great work but I think you by mistake call Condition2 to ondition2. Can you able to rectify it so that everyone got the right code.
But Ayaz it is just excellent work.
Regards
Jaber
filter.Conditions = new ConditionExpression[] {condition1, ondition2};
Thanks for correcting me jaber.
Hi Ayaz,
I have rechecked the java codes but its still not working. I tried the codes submitted by Jon and I have the same error as him “0 a” message.
I m kinda of new with CRM Customization, hope u can help me to get it working.
Thanks,
Revathi
Thanks Ayaz about this example, it’s very useful to me.
I do have a question though,
how do I modify the example so it can query custom entities that are created at runtime ??
I might run into situations, where the web service was created before the custom entities did.
Would make ReturnDynamicEntities to “true” work ??
Thanks,
John
Hi Ayaz,
I have tried your coding and I received the same error as Revathi.
Any other solution for this?
Thanks.
Oh btw, its both running on 2 diff machine.
Could this be a problem?
Hi,
For the original posting, in the calling JS you pass through “qs” (Ex qs = “name=entity&objectguid=123456789″). But in the web method, the arguments are CheckDuplicateAccount(string objectguid, string name). They are backwards – the way you pass them in and the way you receive them. Am I missing something or should they align?
Thanks,
Matt
Well, the whole sample work fine at my side. Both parameter will be treated as strings.
Regards,
Ayaz
can you give me the code for finding both contact and account exists or not, iam new to crm do this favour for me
Hi,
I have used your javascript code and run perfectly on local computer… but gave me an access denied error if i run from client on the same domain..
Could you Help Me
THANKS
Hi Ayaz
i am calling my web service from an html page which loads on button click but when i call the service it ask for user name password how we can stop that.
thanks
nav
Hi Ayaz,
I am using the same code in MSCRM 4.0 but it is throwing an error saying “Unknown name”.
Will this code work with MSCRM 4.0 also?? if yes, how??
home made sex movies free You read this and think …. A salary of between 5% per day Thank you very much! I took a too-handy. and how difficult it is to your own blog? moskvasoset i ne ebet! agree with the author super original fabulous idea … we would learn … great. fantastic! …
It’s an remarkable post in favor of all the web viewers; they will take benefit from it I am sure.