0

我是 CRM 新手,我创建了一个新的自动编号插件(实际上修改了现有插件)。

我在让这个插件在 CRM 端工作时遇到问题。

我已经创建了插件,并且创建了一个 CREATE 步骤。我对 IMAGE 的创建以及我需要如何去做这件事感到困惑。

另外,我正在使用 localContext.Trace,但不确定在哪里查看此信息。

任何人都可以帮助我了解实现此插件所需遵循的确切步骤。我将在此处包含我的代码,以防我做错了什么。同样,这是一个有效的插件,我只是修改了它。我试图遵循以前开发人员使用的模式。

仅供参考——我已经购买了 CRM 解决方案管理器实用程序来帮助部署过程,但仍然没有任何运气。

在此先感谢您的时间。

这是代码..

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IccPlugin.ProxyClasses;
using IccPlugin.ProxyClasses.ProxyClasses;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;

namespace IccPlugin {
    public class ProgramReportAutoNumber : PluginBase {
        private readonly string imageAlias = "ProgramReport";
        private new_programreport preImage { get; set; }
        private new_programreport postImage { get; set; }
        private new_programreport targetEntity { get; set; }

        private readonly string imageAlias_program = "Program";
        private new_program preImage_program { get; set; }
        private new_program postImage_program { get; set; }
        private new_program targetEntity_program { get; set; }

        public ProgramReportAutoNumber(string unsecure, string secure)
            : base(typeof(ProgramReportAutoNumber), unsecure, secure) {
            base.RegisteredEvents.Add(new Tuple<int, string, string, Action<LocalPluginContext>>((int)CrmPluginStepStage.PreOperation, "Create", "new_programreport", new Action<LocalPluginContext>(Execute)));
            //base.RegisteredEvents.Add(new Tuple<int, string, string, Action<LocalPluginContext>>((int)CrmPluginStepStage.PostOperation, "Update", "new_programreport", new Action<LocalPluginContext>(Execute)));
            //base.RegisteredEvents.Add(new Tuple<int, string, string, Action<LocalPluginContext>>((int)CrmPluginStepStage.PostOperation, "Delete", "new_programreport", new Action<LocalPluginContext>(Execute)));
        }

        protected void Execute(LocalPluginContext localContext) {
            if (localContext == null) {
                throw new ArgumentNullException("localContext");
            }

            IPluginExecutionContext context = localContext.PluginExecutionContext;

            if (context.PreEntityImages.Contains(imageAlias) && (context.PreEntityImages[imageAlias] is Entity)) {
                preImage = new new_programreport((Entity)context.PreEntityImages[imageAlias]);
            }

            if (context.PostEntityImages.Contains(imageAlias) && (context.PostEntityImages[imageAlias] is Entity)) {
                postImage = new new_programreport((Entity)context.PostEntityImages[imageAlias]);
            }

            if (context.PreEntityImages.Contains(imageAlias_program) && (context.PreEntityImages[imageAlias_program] is Entity)) {
                preImage_program = new new_program((Entity)context.PreEntityImages[imageAlias_program]);
            }

            if (context.PostEntityImages.Contains(imageAlias_program) && (context.PostEntityImages[imageAlias_program] is Entity)) {
                postImage_program = new new_program((Entity)context.PostEntityImages[imageAlias_program]);
            }

            if (context.InputParameters.Contains("Target") && (context.InputParameters["Target"] is Entity)) {
                targetEntity = new new_programreport((Entity)context.InputParameters["Target"]);
            }

            switch (context.MessageName) {
                case "Create":
                    HandleCreate(localContext);
                    break;
                case "Update":
                    HandleUpdate(localContext);
                    break;
                case "Delete":
                    HandleDelete(localContext);
                    break;
                default:
                    throw new ArgumentException("Invalid Message Name: " + context.MessageName);
            }
        }

        private void HandleDelete(LocalPluginContext localContext) {

            localContext.Trace("START - IccPlugin.ProgramReport.AutoNumber.HandleDelete");

            try {
                if (preImage == null) {
                    throw new Exception("IccPlugin.ProgramReport.AutoNumber.HandleDelete: preImage is null, unable to process the delete message.");
                }

                // TODO: Add code here to implement delete message. 
            } catch (Exception ex) {
                localContext.Trace(String.Format("IccPlugin.ProgramReport.AutoNumber.HandleDelete: Exception while processing the delete message, Error Message: {0}", ex.Message), ex);
                throw ex;
            } finally {
                localContext.Trace("END - IccPlugin.ProgramReport.AutoNumber.HandleDelete");
            }
            return;
        }

        private void HandleUpdate(LocalPluginContext localContext) {

            localContext.Trace("START - IccPlugin.ProgramReport.AutoNumber.HandleUpdate");

            if (preImage == null) {
                string msg = "IccPlugin.ProgramReport.AutoNumber.HandleUpdate : The Update step is not registered correctly.  Unable to retrieve the pre-operation image using alias" + imageAlias;
                localContext.Trace(msg);
                throw new Exception(msg);
            }

            if (postImage == null) {
                string msg = "IccPlugin.ProgramReport.AutoNumber.HandleUpdate : The Update step is not registered correctly.  Unable to retrieve the post-operation image using alias" + imageAlias;
                localContext.Trace(msg);
                throw new Exception(msg);
            }

            if (preImage_program == null) {
                string msg = "IccPlugin.Program.AutoNumber.HandleUpdate : The Update step is not registered correctly.  Unable to retrieve the pre-operation image using alias" + imageAlias_program;
                localContext.Trace(msg);
                throw new Exception(msg);
            }

            if (postImage_program == null) {
                string msg = "IccPlugin.Program.AutoNumber.HandleUpdate : The Update step is not registered correctly.  Unable to retrieve the post-operation image using alias" + imageAlias_program;
                localContext.Trace(msg);
                throw new Exception(msg);
            }

            try {
                // TODO: Add code here to implement update message.
            } catch (Exception ex) {
                localContext.Trace(String.Format("IccPlugin.ProgramReport.AutoNumber.HandleUpdate: Exception while processing the update message, Error Message: {0}", ex.Message), ex);
                throw ex;
            } finally {
                localContext.Trace("END - IccPlugin.ProgramReport.AutoNumber.HandleUpdate");
            }
            return;
        }

        private void HandleCreate(LocalPluginContext localContext) {
            localContext.Trace("START - IccPlugin.ProgramReport.AutoNumber.HandleCreate");

            if (targetEntity == null) {
                string msg = "IccPlugin.ProgramReport.AutoNumber.HandleCreate : The Create step is not registered correctly.  Unable to retrieve the target entity using alias Target.";
                localContext.Trace(msg);
                throw new Exception(msg);
            }

            try {
                // if the target entity does not have the new_filenumber attribute set we will set it now.
                if (targetEntity.new_filenumber != null && targetEntity.new_filenumber != "") {
                    // log a warning message and do not change this value.
                    localContext.Trace("The Program Report being created already has a value for File Number, skipping the auto number assignment for this field.");
                } else {
                    SetFileNumber(localContext);
                }

                if (targetEntity.new_name != null && targetEntity.new_name != "") {
                    localContext.Trace("The Program Report being created already has a value for Report Number, skipping the auto number assignment for this field.");
                } else {
                    SetReportNumber(localContext);
                }
            } catch (Exception ex) {
                localContext.Trace(String.Format("IccPlugin.ProgramReport.AutoNumber.HandleCreate: Exception while processing the create message, Error Message: {0}", ex.Message), ex);
                throw ex;
            } finally {
                localContext.Trace("END - IccPlugin.ProgramReport.AutoNumber.HandleCreate");
            }
            return;
        }

        private void SetFileNumber(LocalPluginContext localContext) {
            localContext.Trace("START - IccPlugin.ProgramReport.AutoNumber.SetFileNumber");
            string s_new_filenumberformat = string.Empty;
            string s_new_reportnumberprefix = string.Empty;
            string s_new_filenumbercode = string.Empty;

            try {
                IOrganizationService service = localContext.OrganizationService;
                string fileNumberValue = "";
                emds_autonumbersequence fileNumberSequence = null;

                //  ##################################################################################################
                //  05/02/2013  --  BEP -- Code added for the following change to the auto-number for file numbering
                //  ##################################################################################################
                //      1 - Year/Month/Sequence
                //              [Year]-[Month]-[Sequence] = [Year] is the current year / [Month] is the current month / [Sequence] is a number series for each Year & Month and resets to 1 when the Month changes
                //      2 - Year/PMG/Sequence - PMG 
                //              [Year]-[PMGProductType][Sequence] = [Year] is the current year / [PMGProductType] is 1st letter from the PMG Product Type on the Program Report / [Sequence] is a single number series for this Format
                //      3 - Year/Letter/Sequence - ESL,VAR
                //              [Year]-[FileCode][Sequence] = [Year] is the current year / [FileCode] is from a new field on the Program entity / [Sequence] is a number series for each Format & File Code
                //  ##################################################################################################

                localContext.Trace("Look at the File Number Format to determine which format to use for the Auto-Number, will default to 1 if not set");

                if (targetEntity_program.new_filenumberformat.ToString() != "") {
                    localContext.Trace("A value was set for the new_filenumberformat field, so we will be using this value.");
                    s_new_filenumberformat = targetEntity_program.new_filenumberformat.ToString();
                } else {
                    localContext.Trace("A value was NOT set for the new_filenumberformat field, so we will be using 1 as the default.");
                    s_new_filenumberformat = "1";
                }

                localContext.Trace("File Number Format Being Used = " + s_new_filenumberformat);

                switch (s_new_filenumberformat) {
                    case "1":
                        #region File Format #1
                        fileNumberValue = String.Format("{0}-{1}", DateTime.Now.ToString("yy"), DateTime.Now.ToString("MM"));

                        localContext.Trace("Building QueryExpression to retrieve FileNumber Sequence record.");

                        QueryExpression qeFileNumberSequence_1 = new QueryExpression(BaseProxyClass.GetLogicalName<emds_autonumbersequence>());
                        qeFileNumberSequence_1.ColumnSet = new ColumnSet(true);
                        qeFileNumberSequence_1.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_entitylogicalname, ConditionOperator.Equal, BaseProxyClass.GetLogicalName<new_programreport>());
                        qeFileNumberSequence_1.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_attributelogicalname, ConditionOperator.Equal, new_programreport.Properties.new_filenumber);
                        qeFileNumberSequence_1.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_prefix, ConditionOperator.Equal, fileNumberValue);

                        localContext.Trace("Getting FileNumber sequence record.");

                        List<emds_autonumbersequence> lFileNumberSequences_1 = service.RetrieveProxies<emds_autonumbersequence>(qeFileNumberSequence_1);
                        if (lFileNumberSequences_1 == null || lFileNumberSequences_1.Count == 0) {
                            localContext.Trace("No FileNumber sequence record was returned, creatign a new one.");

                            // no matching sequence records.  Lets start a new sequence index record for this month and year.
                            fileNumberSequence = new emds_autonumbersequence();
                            fileNumberSequence.emds_attributelogicalname = new_programreport.Properties.new_filenumber;
                            fileNumberSequence.emds_entitylogicalname = BaseProxyClass.GetLogicalName<new_programreport>();
                            fileNumberSequence.emds_index = 1;
                            fileNumberSequence.emds_prefix = fileNumberValue;
                            fileNumberSequence.emds_name = String.Format("File Number Sequence For: {0}", fileNumberValue);
                            fileNumberSequence.Create(service);
                        } else {
                            localContext.Trace("A FileNumber sequence record was found, using it.");
                            // a file number sequence record was returned.  Even if there happen to be multiple we are going to just use the first one returned.
                            fileNumberSequence = lFileNumberSequences_1[0];
                        }
                        //  ###############################################################################
                        //  05/02/2013  --  BEP --  Changed the format from "###" to be "##" for seq number
                        //  ###############################################################################
                        fileNumberValue = String.Format("{0}-{1:00}", fileNumberValue, fileNumberSequence.emds_index);
                        fileNumberSequence.emds_index++;
                        fileNumberSequence.Update(service);
                        #endregion
                        break;
                    case "2":
                        #region File Format #2

                        if (targetEntity_program.new_reportnumberprefix != null && targetEntity_program.new_reportnumberprefix != "") {
                            localContext.Trace("A value was set for the new_reportnumberprefix field, so we will be using this value.");
                            s_new_reportnumberprefix = targetEntity_program.new_reportnumberprefix;
                        } else {
                            localContext.Trace("A value was NOT set for the new_reportnumberprefix field, so we will be using P as the default.");
                            s_new_reportnumberprefix = "P";
                        }

                        fileNumberValue = String.Format("{0}-{1}", DateTime.Now.ToString("yy"), s_new_reportnumberprefix);

                        localContext.Trace("Building QueryExpression to retrieve FileNumber Sequence record.");

                        QueryExpression qeFileNumberSequence_2 = new QueryExpression(BaseProxyClass.GetLogicalName<emds_autonumbersequence>());
                        qeFileNumberSequence_2.ColumnSet = new ColumnSet(true);
                        qeFileNumberSequence_2.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_entitylogicalname, ConditionOperator.Equal, BaseProxyClass.GetLogicalName<new_programreport>());
                        qeFileNumberSequence_2.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_attributelogicalname, ConditionOperator.Equal, new_programreport.Properties.new_filenumber);
                        qeFileNumberSequence_2.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_prefix, ConditionOperator.Equal, "PMG");

                        localContext.Trace("Getting FileNumber sequence record.");

                        List<emds_autonumbersequence> lFileNumberSequences_2 = service.RetrieveProxies<emds_autonumbersequence>(qeFileNumberSequence_2);
                        if (lFileNumberSequences_2 == null || lFileNumberSequences_2.Count == 0) {
                            localContext.Trace("No FileNumber sequence record was returned, creatign a new one.");

                            // no matching sequence records.  Lets start a new sequence index record for this month and year.
                            fileNumberSequence = new emds_autonumbersequence();
                            fileNumberSequence.emds_attributelogicalname = new_programreport.Properties.new_filenumber;
                            fileNumberSequence.emds_entitylogicalname = BaseProxyClass.GetLogicalName<new_programreport>();
                            fileNumberSequence.emds_index = 1;
                            fileNumberSequence.emds_prefix = "PMG";
                            fileNumberSequence.emds_name = String.Format("File Number Sequence For: {0}", fileNumberValue);
                            fileNumberSequence.Create(service);
                        } else {
                            localContext.Trace("A FileNumber sequence record was found, using it.");
                            // a file number sequence record was returned.  Even if there happen to be multiple we are going to just use the first one returned.
                            fileNumberSequence = lFileNumberSequences_2[0];
                        }
                        fileNumberValue = String.Format("{0}-{1:0000}", fileNumberValue, fileNumberValue + fileNumberSequence.emds_index.ToString());
                        fileNumberSequence.emds_index++;
                        fileNumberSequence.Update(service);
                        #endregion
                        break;
                    case "3":
                        #region File Format #3

                        if (targetEntity_program.new_filenumbercode != null && targetEntity_program.new_filenumbercode != "") {
                            localContext.Trace("A value was set for the new_filenumbercode field, so we will be using this value.");
                            s_new_filenumbercode = targetEntity_program.new_filenumbercode;
                        } else {
                            localContext.Trace("A value was NOT set for the new_filenumbercode field, so we will be using L as the default.");
                            s_new_filenumbercode = "l";
                        }

                        fileNumberValue = String.Format("{0}-{1}", DateTime.Now.ToString("yy"), s_new_filenumbercode);

                        localContext.Trace("Building QueryExpression to retrieve FileNumber Sequence record.");

                        QueryExpression qeFileNumberSequence_3 = new QueryExpression(BaseProxyClass.GetLogicalName<emds_autonumbersequence>());
                        qeFileNumberSequence_3.ColumnSet = new ColumnSet(true);
                        qeFileNumberSequence_3.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_entitylogicalname, ConditionOperator.Equal, BaseProxyClass.GetLogicalName<new_programreport>());
                        qeFileNumberSequence_3.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_attributelogicalname, ConditionOperator.Equal, new_programreport.Properties.new_filenumber);
                        qeFileNumberSequence_3.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_prefix, ConditionOperator.Equal, fileNumberValue);

                        localContext.Trace("Getting FileNumber sequence record.");

                        List<emds_autonumbersequence> lFileNumberSequences_3 = service.RetrieveProxies<emds_autonumbersequence>(qeFileNumberSequence_3);
                        if (lFileNumberSequences_3 == null || lFileNumberSequences_3.Count == 0) {
                            localContext.Trace("No FileNumber sequence record was returned, creatign a new one.");

                            // no matching sequence records.  Lets start a new sequence index record for this month and year.
                            fileNumberSequence = new emds_autonumbersequence();
                            fileNumberSequence.emds_attributelogicalname = new_programreport.Properties.new_filenumber;
                            fileNumberSequence.emds_entitylogicalname = BaseProxyClass.GetLogicalName<new_programreport>();
                            fileNumberSequence.emds_index = 1;
                            fileNumberSequence.emds_prefix = fileNumberValue;
                            fileNumberSequence.emds_name = String.Format("File Number Sequence For: {0}", fileNumberValue);
                            fileNumberSequence.Create(service);
                        } else {
                            localContext.Trace("A FileNumber sequence record was found, using it.");
                            // a file number sequence record was returned.  Even if there happen to be multiple we are going to just use the first one returned.
                            fileNumberSequence = lFileNumberSequences_3[0];
                        }
                        fileNumberValue = String.Format("{0}-{1:0000}", fileNumberValue, fileNumberValue + fileNumberSequence.emds_index.ToString());
                        fileNumberSequence.emds_index++;
                        fileNumberSequence.Update(service);
                        #endregion
                        break;
                    default:
                        break;
                }

                targetEntity.new_filenumber = fileNumberValue;
            } catch (Exception ex) {
                localContext.Trace(String.Format("IccPlugin.ProgramReport.AutoNumber.SetFileNumber: Exception while setting the File Number value, Error Message: {0}", ex.Message), ex);
                throw ex;
            } finally {
                localContext.Trace("END - IccPlugin.ProgramReport.AutoNumber.SetFileNumber");
            }
        }

        private void SetReportNumber(LocalPluginContext localContext) {
            localContext.Trace("START - IccPlugin.ProgramReport.AutoNumber.SetReportNumber");
            string s_new_reportnumberprefix = string.Empty;

            try {
                IOrganizationService service = localContext.OrganizationService;
                string reportNumberValue = "";
                emds_autonumbersequence reportNumberSequence = null;

                //  ##################################################################################################
                //  05/02/2013  --  BEP -- Code added for the following change to the auto-number for file numbering
                //  ##################################################################################################
                //  Currently the plugin uses the GP Class Id as the prefix for the Report Number.  
                //  It now needs to use the Report Number Prefix field. 
                //  ##################################################################################################

                if (targetEntity_program.new_reportnumberprefix != null && targetEntity_program.new_reportnumberprefix != "") {
                    localContext.Trace("A value was set for the new_reportnumberprefix field, so we will be using this value.");
                    s_new_reportnumberprefix = targetEntity_program.new_reportnumberprefix;
                } else {
                    localContext.Trace("A value was NOT set for the new_reportnumberprefix field, so we will be using P as the default.");
                    s_new_reportnumberprefix = "P";
                }

                localContext.Trace("Building QueryExpression to retrieve parent new_program record.");

                //  #################################################################################
                //  05/02/2013  --  BEP --  The above code replaces the need to pull the GP Class ID
                //  #################################################################################
                //new_program program = targetEntity.new_programid.RetrieveProxy<new_program>(service, new ColumnSet(true));
                // going to assume that we were able to get the parent program record.  If not an exception will be thrown.
                // could add a check here and throw our own detailed exception if needed.

                reportNumberValue = String.Format("{0}", s_new_reportnumberprefix);  // using Trim just to be safe.

                // now lets get the sequence record for this Report Number Prefix
                QueryExpression qeReportNumberSequence = new QueryExpression(BaseProxyClass.GetLogicalName<emds_autonumbersequence>());
                qeReportNumberSequence.ColumnSet = new ColumnSet(true);
                qeReportNumberSequence.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_entitylogicalname, ConditionOperator.Equal, BaseProxyClass.GetLogicalName<new_programreport>());
                qeReportNumberSequence.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_attributelogicalname, ConditionOperator.Equal, new_programreport.Properties.new_name);
                qeReportNumberSequence.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_prefix, ConditionOperator.Equal, reportNumberValue);

                localContext.Trace("Getting Report Number sequence record.");

                List<emds_autonumbersequence> lReportNumberSequences = service.RetrieveProxies<emds_autonumbersequence>(qeReportNumberSequence);
                if (lReportNumberSequences == null || lReportNumberSequences.Count == 0) {
                    localContext.Trace("No Report Number sequence record was returned, creatign a new one.");

                    // no matching sequence records.  Lets start a new sequence index record for this month and year.
                    reportNumberSequence = new emds_autonumbersequence();
                    reportNumberSequence.emds_attributelogicalname = new_programreport.Properties.new_name;
                    reportNumberSequence.emds_entitylogicalname = BaseProxyClass.GetLogicalName<new_programreport>();
                    reportNumberSequence.emds_index = 1;
                    reportNumberSequence.emds_prefix = reportNumberValue;
                    reportNumberSequence.emds_name = String.Format("Report Number Sequence For Report Number Prefix: {0}", reportNumberValue);
                    reportNumberSequence.Create(service);
                } else {
                    localContext.Trace("A Report Number sequence record was found, using it.");
                    // a file number sequence record was returned.  Even if there happen to be multiple we are going to just use the first one returned.
                    reportNumberSequence = lReportNumberSequences[0];
                }

                reportNumberValue = String.Format("{0}-{1}", reportNumberValue, reportNumberSequence.emds_index);
                reportNumberSequence.emds_index++;
                reportNumberSequence.Update(service);

                targetEntity.new_name = reportNumberValue;
            } catch (Exception ex) {
                localContext.Trace(String.Format("IccPlugin.ProgramReport.AutoNumber.SetReportNumber: Exception while setting the File Number value, Error Message: {0}", ex.Message), ex);
                throw ex;
            } finally {
                localContext.Trace("END - IccPlugin.ProgramReport.AutoNumber.SetReportNumber");
            }
        }
    }
}
4

1 回答 1

0

这是专门针对:

我正在使用 localContext.Trace,但不确定在哪里查看此信息

来自 MSDN;调试插件 - 记录和跟踪

在执行期间并且仅当该插件在运行时将异常传递回平台时,才会向用户显示跟踪信息。对于同步注册插件,跟踪信息显示在 Microsoft Dynamics CRM Web 应用程序的对话框中。对于异步注册插件,跟踪信息显示在 Web 应用程序中系统作业表单的详细信息区域中。

于 2013-05-06T15:52:26.737 回答