6

見積もり商品のプラグインを登録しました。プラグインは、テスト環境でうまく機能しました。私はそれを何度もテストしました。次に、プラグインをメインサーバーに登録しました。ただし、次のシナリオが発生します。最初に見積もり商品を作成または更新すると、見積もり商品フォームがグレー表示されます。

ここに画像の説明を入力してください

見積もりフォームをクリックすると、エラーが表示されます。利用可能なログファイルはありません(ご覧のとおり)。プラグインをデバッグしましたが、エラーもありません。[OK]をクリックすると、エラーが消え、必要なビジネスが見積もり商品(税フィールド用)で実行されます。プラグインのコードにエラーがなく、その仕事がうまくいくことを意味します。コードは次のとおりです。

using System;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel;
using Microsoft.Xrm.Sdk;
using Xrm;
using System.Collections.Generic;
using Microsoft.Xrm.Sdk.Deployment;

public class Plugin : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        IPluginExecutionContext context = (IPluginExecutionContext)
        serviceProvider.GetService(typeof(IPluginExecutionContext));
        Entity entity;
        if (context.InputParameters.Contains("Target") &&
        context.InputParameters["Target"] is Entity)
        {
            entity = (Entity)context.InputParameters["Target"];
            if (entity.LogicalName != "quotedetail") { return; }
        }
        else
        {
            return;
        }
        try
        {
            IOrganizationServiceFactory serviceFactory =
                (IOrganizationServiceFactory)serviceProvider.GetService(
            typeof(IOrganizationServiceFactory));
            IOrganizationService service =
            serviceFactory.CreateOrganizationService(context.UserId);
            if (context.MessageName == "Create")
            {
                Entity QuoteProduct = (Entity)context.InputParameters["Target"];
                Guid QPID = QuoteProduct.Id;
                TaxCreator(service, QPID);
            }
            if (context.MessageName == "Update" && context.Depth < 3)
            {
                Entity QuoteProduct = (Entity)context.PostEntityImages["Target"];
                Guid QPID = QuoteProduct.Id;
                TaxUpdater(service, QPID);
            }
        }
        catch (FaultException<OrganizationServiceFault> ex)
        {
            throw new InvalidPluginExecutionException(
            "An error occurred in the plug-in.", ex);
        }
    }
    private static void TaxCreator(IOrganizationService service, Guid QPID)
    {
        using (var crm = new XrmServiceContext(service))
        {
            var QuoteProduct = crm.QuoteDetailSet.Where(c => c.QuoteDetailId == QPID).First();
            var SaleSetting = crm.new_salessettingSet.Where(c => c.statecode == 0).First();
            double TaxPercent = (Convert.ToDouble(SaleSetting.new_TaxPercent) / 100);
            if (QuoteProduct.IsPriceOverridden == false)
            {
                decimal Tax = (decimal)Convert.ToDecimal(Convert.ToDouble(QuoteProduct.BaseAmount - QuoteProduct.ManualDiscountAmount.GetValueOrDefault()) * TaxPercent);
                decimal PricePerUnit = (decimal)(QuoteProduct.PricePerUnit.GetValueOrDefault() - QuoteProduct.VolumeDiscountAmount.GetValueOrDefault());
                crm.UpdateObject(QuoteProduct);
                crm.SaveChanges();
                QuoteProduct.Attributes["tax"] = new Money(Tax);
                QuoteProduct.Attributes["new_result"] = new Money(PricePerUnit);
                crm.UpdateObject(QuoteProduct);
                crm.SaveChanges();
            }
        }
    }
    private static void TaxUpdater(IOrganizationService service, Guid QPID)
    {
        using (var crm = new XrmServiceContext(service))
        {
            var QuoteProduct = crm.QuoteDetailSet.Where(c => c.QuoteDetailId == QPID).First();
            var SaleSetting = crm.new_salessettingSet.Where(c => c.statecode == 0).First();
            double TaxPercent = (Convert.ToDouble(SaleSetting.new_TaxPercent) / 100);
            if (QuoteProduct.IsPriceOverridden == false)
            {
                decimal Tax = (decimal)Convert.ToDecimal(Convert.ToDouble(QuoteProduct.BaseAmount - QuoteProduct.ManualDiscountAmount.GetValueOrDefault()) * TaxPercent);
                decimal PricePerUnit = (decimal)(QuoteProduct.PricePerUnit.GetValueOrDefault() - QuoteProduct.VolumeDiscountAmount.GetValueOrDefault());
                crm.UpdateObject(QuoteProduct);
                crm.SaveChanges();
                QuoteProduct.Attributes["tax"] = new Money(Tax);
                QuoteProduct.Attributes["new_result"] = new Money(PricePerUnit);
                crm.UpdateObject(QuoteProduct);
                crm.SaveChanges();
            }
        }
    }
}

また、サーバーのイベントビューアでエラーを確認しましたが、結果はありませんでした。見積もり製品の作成と更新時にプラグインを登録しました。どんな助けでも大歓迎です。

4

2 に答える 2

2
    public void Execute(IServiceProvider serviceProvider)
    {
        IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
        Entity entity;
        if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
        {
            entity = (Entity)context.InputParameters["Target"];
            if (entity.LogicalName != "quotedetail") { return; }
        }
        else
        {
            return;
        }

        try
        {
            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
            QuoteDetail QuoteProduct = ((Entity)context.InputParameters["Target"]).ToEntity<QuoteDetail>();
            if (context.MessageName == "Create" || context.MessageName == "Update")
                // && context.Depth < 3) //try to avoid depth unless you have to have it
            {
                TaxSetter(service, QuoteProduct);
            }
        }
        catch (FaultException<OrganizationServiceFault> ex)
        {
            throw new InvalidPluginExecutionException( "An error occurred in the plug-in.", ex);
        }
    }

    private static void TaxSetter(IOrganizationService service, QuoteDetail product)
    {
        using (var crm = new TrainingContext(service))
        {
            var QuoteProduct = product.ToEntity<QuoteDetail>();
            if (QuoteProduct.IsPriceOverridden == false)
            {
                double TaxPercent = Convert.ToDouble(50 / 100);
                decimal Tax = (decimal)Convert.ToDecimal(Convert.ToDouble(QuoteProduct.BaseAmount - QuoteProduct.ManualDiscountAmount.GetValueOrDefault()) * TaxPercent);
                decimal PricePerUnit = (decimal)(QuoteProduct.PricePerUnit.GetValueOrDefault() - QuoteProduct.VolumeDiscountAmount.GetValueOrDefault());

                QuoteProduct.Tax = Tax; //depending on how you the parameters passed into CrmSvcUtil
                QuoteProduct.Attributes["new_result"] = new Money(PricePerUnit); //same deal here

                //crm.UpdateObject(QuoteProduct);
                //crm.SaveChanges();
                //code not needed, the Plugin context will take care of this for you
            }
        }
    }

アイデアは、プラグイン コンテキストが機能するようにすることです。そして、あなたはあからさまにできる限り少なくしたいと思っています。あなたの属性がないため、税金の計算を変更しました。それらを元に戻したいと思うでしょう。それでも問題を読み違えている場合は、喜んで投稿を削除します (または削除してみます)。

于 2013-03-12T18:19:55.133 に答える
2

私はそれでショットガンデバッグに行きます。次のトレースを実装します。通常、トレーサーの宣言をクラス メンバーとして配置し (そのため、クラス内のすべてのヘルプ メソッドから参照できるようになります)、すべての操作 (多かれ少なかれ) の後に (絶望的でイライラしたときに) 書き込みます。その後、プログラムが単独でクラッシュした場合 (または、トレース ログを確認するために意図的にクラッシュした場合)、通常は問題の領域を特定できます。

public class MyPlugin _ IPlugin
{
  private ITracingService _trace;

  public void Execute(IServiceProvider service)
  {
    _trace = (ITracingService)service.GetService(typeof(ITracingService));
    _trace.Trace("Commencing.");
    ...
    _trace.Trace("Right before an operation. " + someValue);
    PerformAnOperation();
    _trace.Trace("Right before an other operation. " + someOtherValue);
    PerformAnOtherOperation();
    ...
    throw new Exception("Intentional!");
  }
}

問題が発生した場所を正確に確認することができます。私の経験では、どこが痛いのかがわかれば、問題を解決する方法を簡単に提案できます.

編集:

OPが詳細を要求したので、私は彼のコードを取り、彼のためにトレースアルゴリズムを入れています. 少し冗長ですが、明らかに、CRM は非常に混乱する可能性があります。私自身そこにいました。

public class Plugin : IPlugin
{
  // Here we declare our tracer.
  private ITracingService _trace;

  public void Execute(IServiceProvider serviceProvider)
  {
    // Here we create it.
    _trace = (ITracingService)serviceProvider
      .GetService(typeof(ITracingService));
    _trace.Trace("Commencing.");

    // Here we crash our plugin just to make sure that we can see the logs 
    // with trace information. This statement should be gradually moved down
    // the code to discover where exactly the plugin brakes.
    throw new Exception("Intentional!");

    IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider
      .GetService(typeof(IPluginExecutionContext));
    Entity entity;
    ...

    try { ... }
    catch (FaultException<OrganizationServiceFault> ex)
    {
      throw new InvalidPluginExecutionException(
        "An error occurred in the plug-in.", ex);
    }

    // Here we catch all other kinds of bad things that can happen.
    catch(Exception exception) { throw exception; }
  }

  private static void TaxCreator(IOrganizationService service, Guid QPID)
  {
    // Here we add a line to the trace hoping that the execution gets here.
    _trace.Trace("Entered TaxCreator.");

    using (var crm = new XrmServiceContext(service))
    {
      var QuoteProduct = crm.QuoteDetailSet.Where(...).First();
      var SaleSetting = crm.new_salessettingSet.Where(...).First();
      double TaxPercent = (Convert.ToDouble(...) / 100);

      // Here we add a line to the trace to see if we get past this point.
      _trace.Trace("Approaching if statement.");

      if (QuoteProduct.IsPriceOverridden == false) { ... }
    }
  }

  private static void TaxUpdater(IOrganizationService service, Guid QPID)
  {
    // Here we add a line to the trace hoping that the execution gets here.
    _trace.Trace("Entered TaxUpdater.");

    ...
  }
}
于 2013-03-12T19:18:14.890 に答える