Припрема решења, са асинхроним увозом и извозом

Да ли сте икада наишли на ситуацију током увоза или извоза великог решења где је време операције истекло? Ако је тако, можда ћете бити кандидат за асинхроно извршавање увоза/извоза решења. Овај тема описује како се покреће асинхрони увоз или извоз када користите Dataverse SDK за .NET и Web API-је.

Припрема решења

У поређењу са увозом решења у које се решење одмах увози и одмах је доступно у окружењу, припрема дели процес увоза на више фазе које могу да се контролишу. Процес припреме увози решење као решење „са задршком“, где администратор може да одлучи када ће припремљено решење учинити доступним корисницима или извршити надоградњу (у случају надоградње решења) у циљном окружењу. Део процеса припреме је валидација припремљеног решења. На тај начин можете да припремите решење, знајући да је решење важеће, и да закажете када да примените или надоградите то решење на циљно окружење.

Операција Веб АПИ Dataverse SDK за .NET
Припрема решења СтагеСолутион СтагеСолутионРеqуест

Резултат припреме решења биће колекција резултата провере ваљаности који указују на успех или неуспех и (ако је успешно) који StageSolutionUploadId ће се користити у позиву ImportSolutionAsync. Погледајте Web API узорак кода решења за увоз да бисте видели како се то ради.

public static StageSolutionResults StageSolution(
    IOrganizationService service,
    string solutionFilePath)
{
  // Stage the solution
  var req = new StageSolutionRequest();

  byte[] fileBytes = File.ReadAllBytes(solutionFilePath);
  req["CustomizationFile"] = fileBytes;
  var res = service.Execute(req);

  return (res["StageSolutionResults"] as StageSolutionResults);
}

Увоз решења

ImportSolution је акција (или порука) која обавља синхрону операцију увоза. Да бисте извршили операцију увоза асинхроно, користите ImportSolutionAsync.

Операција Веб АПИ Dataverse SDK за .NET
Увоз решења ИмпортСолутионАсyнц ИмпортСолутионАсyнцРеqуест

Погледајмо сада неке примере кода који демонстрирају ImportSolutionAsync.

public static ImportSolutionAsyncResponse ImportSolution(
    IOrganizationService service,
    StageSolutionResults stagingResults,
    Dictionary<string,Guid> connectionIds,
    Dictionary<string,string> envarValues )
{
    // Import the staged solution
    var componentDetails = stagingResults.SolutionComponentsDetails;

    // TODO These are not referenced in the code but are useful to explore
    var missingDependencies = stagingResults.MissingDependencies;   // Contains missing dependencies
    var solutionDetails = stagingResults.SolutionDetails;           // Contains solution details

    var connectionReferences = componentDetails.Where(x => string.Equals(x.ComponentTypeName, "connectionreference"));
    var envVarDef = componentDetails.Where(x => string.Equals(x.ComponentTypeName, "environmentvariabledefinition"));
    var envVarValue = componentDetails.Where(x => string.Equals(x.ComponentTypeName, "environmentvariablevalue"));

    var componentParams = new EntityCollection();

    // Add each connection reference to the component parmameters entity collection.
    foreach (var conn in connectionReferences)
    {
        var e = new Entity("connectionreference")
        {
            ["connectionreferencelogicalname"] = conn.Attributes["connectionreferencelogicalname"].ToString(),
            ["connectionreferencedisplayname"] = conn.Attributes["connectionreferencedisplayname"].ToString(),
            ["connectorid"] = conn.Attributes["connectorid"].ToString(),
            ["connectionid"] = connectionIds[conn.ComponentName]
        };
        componentParams.Entities.Add(e);
    }
            
    // Add each environment variable to the component parmameters entity collection.
    foreach (var value in envVarValue)
    {
        var e = new Entity("environmentvariablevalue")
        {
            ["schemaname"] = value.Attributes["schemaname"].ToString(),
            ["value"] = envarValues[value.ComponentName]
        };

        if (value.Attributes.ContainsKey("environmentvariablevalueid"))
        {
            e["environmentvariablevalueid"] = value.Attributes["environmentvariablevalueid"].ToString();
        }
        componentParams.Entities.Add(e);
    }

    // Import the solution
    var importSolutionReq = new ImportSolutionAsyncRequest();
    importSolutionReq.ComponentParameters = componentParams;
    importSolutionReq.SolutionParameters = new SolutionParameters { StageSolutionUploadId = stagingResults.StageSolutionUploadId };
    var response = service.Execute(importSolutionReq) as ImportSolutionAsyncResponse;

    return (response);
}

ImportSolutionAsync дели многе улазне параметре са, ImportSolution али додаје ComponentParameters и SolutionParameters. ComponentParameters може се користити за преписивање података о компонентама у XМЛ датотеци прилагођавања решења. SolutionParameters може се користити за пролазак StageSolutionUploadId фазног решења као што је приказано у примеру Веб АПИ кода. Још информација: Припрема решења

Одговор враћен из ImportSolutionAsync садржи ImportJobKey и AsyncOperationId. Вредност ImportJobKey се може користити за добијање резултата увоза, а вредност AsyncOperationId се може користити за праћење статуса посла увоза.

public static void CheckImportStatus(
    IOrganizationService service,
    Guid asyncOperationId,
    Guid importJobKey)
{
    // Get solution import status
    var finished = false;
    Entity asyncOperation = null;
    // Wait until the async job is finished
    while (!finished)
    {
        asyncOperation = service.Retrieve("asyncoperation", asyncOperationId, new ColumnSet("statecode", "statuscode"));
        OptionSetValue statecode = (OptionSetValue)asyncOperation["statecode"];
        if (statecode.Value == 3)
        {
            finished = true;
        }
        else
        {
            Thread.Sleep(10000);
        }
    }
    // Solution import completed successfully
    OptionSetValue statuscode = (OptionSetValue)asyncOperation["statuscode"];
    if (statuscode.Value == 30)
    {
        Console.WriteLine("The solution import completed successfully.");
    }
    else if (asyncOperation["statuscode"].ToString() == "31")  // Solution import failed
    {
        Console.WriteLine("The solution import failed.");
        var getLogReq = new RetrieveFormattedImportJobResultsRequest { ImportJobId = importJobKey };
        var importJob = service.Execute(getLogReq) as RetrieveFormattedImportJobResultsResponse;
        // TODO Do something with the import job results
    }
}

Извоз решење

ExportSolution је акција (или порука) која обавља синхрону операцију извоза. Да бисте извршили операцију извоза асинхроно, користите ExportSolutionAsync.

Операција Веб АПИ Dataverse SDK за .NET
Извоз решења ЕxпортСолутионАсинц ЕкпортСолутионАсyнцРеqуест
Преузимање датотеке извезеног решења ДовнлоадСолутионЕxпортДата ДовнлоадСолутионЕxпортДатаРеqуест

Погледајмо сада неке примере кода који демонстрирају ExportSolutionAsync.

// Where 'service' is a pre-configured IOrganizationService instance.
var service = (OrganizationServiceProxy)xsc.CreateOrganizationService();

var req = new OrganizationRequest("ExportSolutionAsync");
req.Parameters.Add("SolutionName", "ExportSolutionAsyncTest");
req.Parameters.Add("Managed", false);
var response = service.Execute(req);

У одговору су вредности параметара AsyncOperationId и ExportJobId. Користите AsyncOperationId као одговор да бисте потврдили успех (statecode == 3; statuscode == 30) асинхроног посла. Затим користите радњу (или поруку) DownloadSolutionExportData са вредношћу ExportJobId из одговора о извозу да бисте преузели извезену датотеку решења која се враћа у параметру ExportSolutionFile.

// Where 'service' is a pre-configured IOrganizationService instance.
var service = (OrganizationServiceProxy)xsc.CreateOrganizationService();

var req = new OrganizationRequest("DownloadSolutionExportData");
req.Parameters.Add("ExportJobId", Guid.Parse("a9089b53-a1c7-ea11-a813-000d3a14420d");
var response = service.Execute(req);

Такође погледајте

Узорак : Постављање решења са асинхроним увозом