locked
CRM Plugin Call a Custom Web Service RRS feed

  • Question

  • I am running into an issue that I suspect is a permissions issue.  I'm hoping someone can point out where my issue is.

    I have a web service that I created for CRM.  I've added a method to load a lead entity.  It works fine if I call it directly on the server though the .Net asmx page and provide the correct parameter values, such as enter a valid the lead guid.  But when I call them from a CRM plugin, I am getting errors that say SQL server is timing out. It also works fine on my local machine in debug mode.  It just doesn't work when the service is called from CRM plugin.  I suspect I need to setup the service in IIS differently or maybe add my app-pools user account to CRM.  But I don't really know and through trail-and-error I have not been able to resolve this.  All I can tell is that it cannot connect to SQL and CRM to load the lead.  If I remove the db code, all of this works fine... but when I try to hit the CRM database and retreive the lead entity, I get an error.

    Here's a sample of what I am doing.  I've removed most of the code to figure out my issue and I ended up with the following minimum to throw the error.

      public class CrmServices
        {

            readonly IOrganizationService _service;

            public CrmServices()
            {
                    //var con = new CrmConnection("CrmConnection");
                    var con = CrmConnection.Parse(@"... hardcoded my connection string here in case web.config was the issue...");

                    _service = new OrganizationService(con);
                }
                catch (Exception ex)
                {
                    throw new Exception(string.Format("CrmService Constructor error. {0}",ex.Message));
                }
               
            }

    public bool CreateContactFromExistingLead(Guid leadId) { // Load Lead Entity Entity lead = _service.Retrieve("lead", leadId, new ColumnSet(true)); // This throws an error.

    }

    The web service is called from a PpstLeadUpdate() plugin, as follows:

    protected void ExecutePostLeadUpdate(LocalPluginContext localContext)
            {
                if (localContext == null)
                {
                    throw new ArgumentNullException("localContext");
                }
    
                // Obtain the execution context from the service provider.
                //IOrganizationService orgService = localContext.OrganizationService;
                IPluginExecutionContext context = localContext.PluginExecutionContext;
                //_service = new CrmServices(orgService); // Initialize the service class.
    
                // The InputParameters collection contains all the data passed in the message request.
                if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
                {
                    // Obtain the target entity from the input parmameters.
                    Entity entity = (Entity)context.InputParameters["Target"];
    
                    if (entity.LogicalName.Equals("lead"))
                    {
                        Guid leadId = new Guid();
                        string statusCode = "";
    
                        foreach (var item in entity.Attributes)
                        {
                            if (item.Key == "leadid")
                                leadId = new Guid(item.Value.ToString());
    
                            if (item.Key == "statuscode")
                            {
                                OptionSetValue entityStatusCode = (OptionSetValue)entity.Attributes["statuscode"];
                                statusCode = entityStatusCode.Value.ToString();
                            }
                        }
    
                        try
                        {
                            if (statusCode == "3") // "QUALIFIED"
                            //_service.CreateContactFromExistingLead(leadId);
                            {
                                bool resp = _dhiCrmWebService.CreateContactFromExistingLead(leadId);
                            }
                        }
                        catch (FaultException ex)
                        {
                            throw new InvalidPluginExecutionException("An error occurred in the plug-in." + ex.Message, ex);
                        }
                    }
                }
            }

    If I move the web service code into the plugin, it works fine.  If I call the webservice directly and outside of CRM, the web service works fine and connects to CRM as expected. But if I call the web service from CRM, I get an error saying that it cannot connect to SQL server and it times out.

    I want to do this to allow for all of my plugin business rules to sit behind a .Net web service and have JavaScript and Plugins execute methods from the web service. It seems like an easier approach to have dozens of plugins with lots of duplicate code.  By putting the code in a service, I can reuse a lot of my code.  However, it may make more sense to just create a common class in the plugin for common methods used by all of the services.  If that is a better aprroch, I would like to know.  However, I still want to be able to fix the issue with this web service, as I would like to use web services for other things in CRM.

    Any idea why I cannot connect to CRM and retreive the lead entity?  Do I need to set some sort of permissions?  The web service is setup to run under a .Net 4.0 app pool.  I am using CRM 2011 On-Premise... an the older web service ("add a web reference") to allow a legacy application to call the service methods as well as CRM.

    Any ideas?


    Jon Gregory Rothlander



    Monday, March 10, 2014 8:49 PM