簡體   English   中英

MS Dynamics 365 C# 審核歷史記錄 KeyNotFoundException

[英]MS Dynamics 365 C# audit history KeyNotFoundException

我正在嘗試提取特定帳戶的審計歷史記錄,如下面的示例所示:

在此處輸入圖像描述

我特別需要提取名為 Credit Limit 的 Changed Field 的所有結果。

為了做到這一點,我在 C# 中有以下代碼:

using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Tooling.Connector;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PowerApps.Samples
{
    public partial class SampleProgram
    {
        [STAThread] // Added to support UX
        static void Main(string[] args)
        {
            CrmServiceClient service = null;
            service = SampleHelpers.Connect("Connect");
            if (!service.IsReady)
                Console.WriteLine("No Connection was Made.");
            Console.WriteLine("Connected");

            //Create a new RetrieveAttributeChangeHistoryRequest

            RetrieveAttributeChangeHistoryRequest req = new RetrieveAttributeChangeHistoryRequest();

            //Set the target Entity

            req.Target = new EntityReference("new_case", new Guid("468f8db5-4f98-eb11-57ee-0006ffc2587a"));

            //Set the attribute you want to retrieve specifically

            req.AttributeLogicalName = "credit_limit";

            //Execute the request against the OrgService

            RetrieveAttributeChangeHistoryResponse resp = (RetrieveAttributeChangeHistoryResponse)service.Execute(req);

            AuditDetailCollection details = resp.AuditDetailCollection;

            Console.WriteLine("Before the loop");
            //Iterate through the AuditDetails

            foreach (var detail in details.AuditDetails)

            {
                Console.WriteLine("Inside the loop");
                //Important: the AuditDetailCollection.AuditDetails doesn’t always contain the type of AttributeAuditDetail, so make sure it is of correct type before casting

                if (detail.GetType() == typeof(AttributeAuditDetail))
                {
                    AttributeAuditDetail attributeDetail = (AttributeAuditDetail)detail;

                    String oldValue = "(no value)", newValue = "(no value)";

                    if (attributeDetail.OldValue.Contains("credit_limit"))
                        Console.WriteLine("old value: "+oldValue);

                    oldValue = attributeDetail.OldValue["credit_limit"].ToString();

                    if (attributeDetail.NewValue.Contains("credit_limit"))
                        Console.WriteLine("new value: "+newValue);

                    newValue = attributeDetail.NewValue["credit_limit"].ToString();

                    //TODO: Use the old value and new value in the Business Logic

                }
            }
            Console.WriteLine("After the loop");
            Console.ReadLine();
        }
    }
}

發生的事情是我在命令行中得到以下結果:

Connected
Before the loop
Inside the loop
old value: (no value)
new value: (no value)
Inside the loop

然后它在異常時中斷,在 Visual Studio 中告訴我

System.Collections.Generic.KeyNotFoundExemption: The given key was not present in the dictionary.

有人可以澄清我做錯了什么以及我能做些什么來解決它嗎?

問題是您正在檢查“新值”和“舊值”是否包含您的屬性,然后嘗試使用它,即使它是錯誤的。

我對您的代碼做了些許改動,它按預期工作。

//Create a new RetrieveAttributeChangeHistoryRequest

RetrieveAttributeChangeHistoryRequest req = new RetrieveAttributeChangeHistoryRequest();

//Set the target Entity

req.Target = new EntityReference("new_case", new Guid("468f8db5-4f98-eb11-57ee-0006ffc2587a"));

//Set the attribute you want to retrieve specifically

req.AttributeLogicalName = "credit_limit";

//Execute the request against the OrgService

RetrieveAttributeChangeHistoryResponse resp = (RetrieveAttributeChangeHistoryResponse)crmService.Execute(req);

AuditDetailCollection details = resp.AuditDetailCollection;

Console.WriteLine("Before the loop");
//Iterate through the AuditDetails

foreach (var detail in details.AuditDetails)

{
    Console.WriteLine("Inside the loop");
    //Important: the AuditDetailCollection.AuditDetails doesn’t always contain the type of AttributeAuditDetail, so make sure it is of correct type before casting

    if (detail.GetType() == typeof(AttributeAuditDetail))
    {
        AttributeAuditDetail attributeDetail = (AttributeAuditDetail)detail;

        String oldValue = "(no value)", newValue = "(no value)";

        if (attributeDetail.OldValue.Contains("credit_limit"))
            oldValue = attributeDetail.OldValue["credit_limit"].ToString();

        Console.WriteLine("old value: " + oldValue);

        if (attributeDetail.NewValue.Contains("credit_limit"))
            newValue = attributeDetail.NewValue["credit_limit"].ToString();

        Console.WriteLine("new value: " + newValue);
        
        //TODO: Use the old value and new value in the Business Logic

    }
}

Console.WriteLine("After the loop");
Console.ReadLine();

如果根據if條件執行多個語句,則必須將{}中的語句分組。

if (attributeDetail.OldValue.Contains("credit_limit"))
{
        oldValue = attributeDetail.OldValue["credit_limit"].ToString();
        Console.WriteLine("old value: " + oldValue);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM