locked
CRM 4.0 Plugin Deployment Failing RRS feed

  • Question

  • So here's my scenario and I've easily killed two days on this.  I have a plugin I built for CRM 4.0 that is to run prestage the create event for the account.  This plugin write a new guid overtop of the old for the account, prior to it being saved and then puts that guid + url of the account edit page into a field.

    The idea is a deep link is then stored in a field I can access in the workflows. 

    I built it in a VPC, and it works great there, I used the CRM Plugin registration tool to register the assembly and the step.  It constructs the full url, so that's fine.

    My problem is this, when I go to deploy it to our production CRM 4.0 server, it fails.  I repeated the steps exactly as on the VPC, and when I hit "New" under accounts, and enter teh required information it seems to save but at some point I get a "Microsoft CRM has experienced an error..."  It goes on to say contact the administrator, or check the forums. 

    I've tried stopping and starting IIS and the CRM Workflow Service, I've tried different permissions levels, everything and I don't know why its failing.  Here is my code for the plugin, it is a modified version of Jeremy Mitchell's embedded link.

    Thanks
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    using Microsoft.Crm.Sdk;
    using Microsoft.Crm.SdkTypeProxy;
    
    namespace CRMCaptureUtil
    {
    	public class Plugin:IPlugin
    	{
    		private string crmSite = "<CRMSiteDomainName>" + "/sfa/accts/edit.aspx?id=";
    		private string GUIDfield = "accountid";
    		private string OutputField = "new_urllink";
    				
    		public void Execute(IPluginExecutionContext context)
    		{
    			if ((context.InputParameters.Properties.Contains(ParameterName.Target) && (context.InputParameters.Properties[ParameterName.Target] is DynamicEntity )))
    			{
    				DynamicEntity _dentity = (DynamicEntity)context.InputParameters[ParameterName.Target];
    				switch(context.MessageName)
    				{
    					case MessageName.Create:
    					GenerateGuid(ref _dentity);
    					BuildUrl(ref _dentity);
    					context.InputParameters[ParameterName.Target] = _dentity;
    					break;
    					case MessageName.Update:
    					break;
    
    					case MessageName.Delete:
    					break;
    				}
    
    			}
    
    		}
    
    		public void BuildUrl(ref DynamicEntity _dentity)
    		{
    			Key _keyproperty = (Key)_dentity[GUIDfield];
    			string url = crmSite  + _keyproperty.Value.ToString();
    			StringProperty _url = new StringProperty(OutputField, url);
    			_dentity .Properties .Add(_url);
    		}
    
    		public void GenerateGuid(ref DynamicEntity _dentity)
    		{
    			//Generates a GUID to assign to the entity
    			Guid _accountguid = Guid.NewGuid();
    			Key _accountkey = new Key(_accountguid);
    			KeyProperty _keyprop = new KeyProperty(GUIDfield, _accountkey);
    			_dentity.Properties.Add(_keyprop);
    		}
    	}
    }
    Wednesday, April 22, 2009 8:23 PM

Answers

  • Here is a Step-By-Step description coming from SDK:
    http://msdn.microsoft.com/en-us/library/cc151088.aspx

    I hope you do not use Visual C# 2008 Express because it is not possible to debug external processes with the Express edition.


    Jürgen Beck

    Dipl. Kfm./Wirtschaftsinformatik
    MVP, MCSD.NET, MCITP DBA, MCDBA, MCSE
    Microsoft Certified Business Management Solutions Professional
    Microsoft Certified CRM Developer
    Microsoft Certified Trainer

    ComBeck IT Services & Business Solutions
    Microsoft Gold Certified Partner
    Microsoft Small Business Specialist

    Developing & Supporting Business Applications from small business to big enterprises covering scores of sectors

    http://www.combeck.de
    Wednesday, April 22, 2009 9:14 PM
    Moderator
  • Thanks for the tip on debugging.  Unfortuantely I am not the CRM admin and am only a developer.  I don't have rights to the server, so debugging it on production is not an issue.  There was one thing I was just thinking of. 

    This probably sounds like a stupid question but do I need to worry about the "microsoft.crm.sdk.dll" and "microsoft.crm.sdktypeproxy.dll", are those automatically put in with CRM, or do they require the SDK also be installed on the server?

    I debugged my code on the VPC, where its working and saw nothing that could cause an issue. 

    Another possible problem I thought of, and you can tell me if this is even an issue.  Could it have to do with the framework.  This was developed in Visual Studio 2005, but the VPC has both framework 2.0 and 3.0 installed.  Is it possible that the CRM 4.0 server on production could be configured with only 2.0 and causing it to fail, or is that not possible.

    I am trying having it through more descriptive errors now, and having separate builds which will (when registered 1 at a time) tell me how far it is making it through the code.  Any other ideas would be great, thanks.
    • Marked as answer by Jim Glass Jr Friday, April 24, 2009 4:13 PM
    Thursday, April 23, 2009 5:50 PM
  • RavenKDM,

    I typically get that kind of error if I have registered my plugin against the wrong Image type.  For a PreCreate you want only the PostImage, and yes, you definitely need your image registered for the plugin.  On a PreCreate there is no PreImage, only a PostImage.

    Check that out and see if that doesn't get you going in the right direction.

    Fronk
    http://dmcrm.blogspot.com
    • Marked as answer by Jim Glass Jr Friday, April 24, 2009 4:13 PM
    Friday, April 24, 2009 12:44 PM

All replies

  • Hi RavenKDM,

    have you tried to debug your Plug-In?

    Best regards,
    Jürgen
    Jürgen Beck

    Dipl. Kfm./Wirtschaftsinformatik
    MVP, MCSD.NET, MCITP DBA, MCDBA, MCSE
    Microsoft Certified Business Management Solutions Professional
    Microsoft Certified CRM Developer
    Microsoft Certified Trainer

    ComBeck IT Services & Business Solutions
    Microsoft Gold Certified Partner
    Microsoft Small Business Specialist

    Developing & Supporting Business Applications from small business to big enterprises covering scores of sectors

    http://www.combeck.de
    Wednesday, April 22, 2009 8:58 PM
    Moderator
  • How would I go about debugging it.  I'm relatively new to this whole process.  I know it has something to do with .pdb files.  How exactly does this work? 
    Wednesday, April 22, 2009 9:10 PM
  • Here is a Step-By-Step description coming from SDK:
    http://msdn.microsoft.com/en-us/library/cc151088.aspx

    I hope you do not use Visual C# 2008 Express because it is not possible to debug external processes with the Express edition.


    Jürgen Beck

    Dipl. Kfm./Wirtschaftsinformatik
    MVP, MCSD.NET, MCITP DBA, MCDBA, MCSE
    Microsoft Certified Business Management Solutions Professional
    Microsoft Certified CRM Developer
    Microsoft Certified Trainer

    ComBeck IT Services & Business Solutions
    Microsoft Gold Certified Partner
    Microsoft Small Business Specialist

    Developing & Supporting Business Applications from small business to big enterprises covering scores of sectors

    http://www.combeck.de
    Wednesday, April 22, 2009 9:14 PM
    Moderator
  • Thanks for the tip on debugging.  Unfortuantely I am not the CRM admin and am only a developer.  I don't have rights to the server, so debugging it on production is not an issue.  There was one thing I was just thinking of. 

    This probably sounds like a stupid question but do I need to worry about the "microsoft.crm.sdk.dll" and "microsoft.crm.sdktypeproxy.dll", are those automatically put in with CRM, or do they require the SDK also be installed on the server?

    I debugged my code on the VPC, where its working and saw nothing that could cause an issue. 

    Another possible problem I thought of, and you can tell me if this is even an issue.  Could it have to do with the framework.  This was developed in Visual Studio 2005, but the VPC has both framework 2.0 and 3.0 installed.  Is it possible that the CRM 4.0 server on production could be configured with only 2.0 and causing it to fail, or is that not possible.

    I am trying having it through more descriptive errors now, and having separate builds which will (when registered 1 at a time) tell me how far it is making it through the code.  Any other ideas would be great, thanks.
    • Marked as answer by Jim Glass Jr Friday, April 24, 2009 4:13 PM
    Thursday, April 23, 2009 5:50 PM
  • Ok, another question, mainly as I'm not really very experienced at plugin development.  Would I need to set up a preCreate image for the plugin to have access to.  And then it would update the image to have the new guid and urllink fields?

    Any help would be great?
    Thursday, April 23, 2009 6:51 PM
  • RavenKDM,

    I typically get that kind of error if I have registered my plugin against the wrong Image type.  For a PreCreate you want only the PostImage, and yes, you definitely need your image registered for the plugin.  On a PreCreate there is no PreImage, only a PostImage.

    Check that out and see if that doesn't get you going in the right direction.

    Fronk
    http://dmcrm.blogspot.com
    • Marked as answer by Jim Glass Jr Friday, April 24, 2009 4:13 PM
    Friday, April 24, 2009 12:44 PM
  • RavenKDM,

    To answer a couple of your questions:
    1) The two sdk-DLL files should be installed on the CRM-server, as far as I know.
    2) CRM 4 always comes with Framework 3.0, if you want to use Linq someone needs to install Framework 3.5 on the CRM-server

    But I do have a few comments on you plugin:
    1. First of all I don't like it when you generate id's of records, how can you be sure this id hasn't been used before? No leave this task to the CRM system.
    2. And when you extract a DynamicEntity the way you do you don't need to assign it back to the InputParameters, as any changes to the extracted entity will by reflected by the InputParameters object.
    An easier way of setting properties on DynamicEntity objects is done like this (with reference to your code):
    _dentity["booleanPropertyName"] = new CrmBoolean(true);
    _dentity["numberPropertyName"] = new CrmNumber(123);
    _dentity["datetimePropertyName"] = new CrmDateTime("1985-06-05T17:00:00");
    _dentity["stringPropertyName"] = "this is just a string";
    ...etc

    and clearing values from an attribute/property can be done like this:
    _dentity["booleanPropertyName"] = CrmBoolean.Null;
    _dentity["numberPropertyName"] = CrmNumber.Null;
    _dentity["datetimePropertyName"] = CrmDateTime.Null;
    _dentity["stringPropertyName"] = null;



    Now should I write the plugin you have sketched, I would something like this:
    namespace CRMCaptureUtil
    {
        using Microsoft.Crm.Sdk;
        using Microsoft.Crm.SdkTypeProxy;

        public class GenerateUrlLinkPlugin : IPlugin
        {
            public void Execute(IPluginExecutionContext context)
            {
                // Ensure this is a post-create event
                if(context.MessageName == MessageName.Create && context.Stage == MessageProcessingStage.AfterMainOperationOutsideTransaction) {

                    // post-create only contains id (Guid) of the created record
                    //
                    // extract the id generated by CRM for the current record
                    //
                    Guid recordId = this.OutputParameters.Contains(ParameterName.Id)? (Guid)this.OutputParameters[ParameterName.Id] :
                        (Guid)this.OutputParameters[ParameterName.EmailId];

                    // Create a new entity for updating the record which has just been created with an url to the record
                    DynamicEntity _dentity = new DynamicEntity(context.PrimaryEntityName);

                    // Set id of record which should be updated
                    // this is of course set to recordId extracted above
                    // REMARK: this way of addressing the id-attribute (property) isn't bullet proof
                    // but "entityname" + "id" covers 99% percent of the cases
                    // to be sure one should do a query against the metadata to get the correct name
                    //
                    _dentity[context.PrimaryEntityName + "id"] = new Key(accountId);

                    // Set new_urllink property
                    // You'll notice that we have used the format used by customentities, luckly CRM allow us to
                    // access system entities through the same url.
                    //
                    // also notice that the normal "etc" holding a reference to the ObjectTypeCode of the entity
                    // has been replaced by "etn" which takes the name of an entity
                    //
                    _dentity["new_urllink"] = String.Format("/userdefined/edit.aspx?id={0}&etn={1}", accountId, context.PrimaryEntityName);
               
                    // finally create an ICrmService object with admin privileges
                    // and in the same step pass the create _dentity object to the Update method
                    // of the create entity
                    context.CreateCrmService(false).Update(_dentity);   
                }
            }
        }
    }
    Thursday, May 7, 2009 11:31 PM