Etapizarea soluției cu import și export în mod asincron

V-ați confruntat vreodată, în timpul importului sau exportului unei soluții mari, cu situația în care operațiunea se întrerupe? Dacă da, puteți fi un candidat pentru efectuarea importului/exportului soluției în mod asincron. Acest subiect descrie cum să inițiați importul sau exportul în mod asincron utilizând Dataverse SDK-ul pentru .NET și API-urile Web.

Etapizarea unei soluții

În comparație cu importul unei soluții în care soluția este importată și disponibilă imediat în mediu, etapizarea împarte procesul de import în faze mai controlabile. Procesul de etapizare importă soluția ca o soluție „holding” în care administratorul poate decide când să pună soluția etapizată la dispoziția utilizatorilor sau să efectueze o actualizare (în cazul unui upgrade al soluției) în mediul țintă. O parte a procesului de etapizare constă în validarea soluției etapizate. În acest fel, puteți etapiza soluția, puteți ști că soluția este validă și puteți planifica când să aplicați soluția respectivă sau să faceți upgrade la mediul țintă.

Operație API web Dataverse SDK pentru .NET
Etapizarea unei soluții StageSolution Cerere de soluție etapă

Rezultatul etapizării unei soluții va fi o colecție de rezultate de validare care indică succesul sau eșecul și (dacă are succes) un StageSolutionUploadId care va fi folosit în ImportSolutionAsync apel. Consultați eșantionul de cod API Web al soluției de import de mai sus pentru un exemplu în acest sens.

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);
}

Importul soluției

ImportSolution este acțiunea (sau mesajul) care efectuează operațiunea de import sincron. Pentru a executa operațiunea de import în mod asincron, utilizați ImportSolutionAsync.

Operație API web Dataverse SDK pentru .NET
Importul unei soluții ImportSolutionAsync ImportSolutionAsyncRequest

Acum să aruncăm o privire la un exemplu de cod care prezintă 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 partajează mulți parametri de intrare cu ImportSolution dar adaugă ComponentParameters şi SolutionParameters. ComponentParameters poate fi utilizat pentru a suprascrie datele componentelor din fișierul XML de personalizare al soluției. SolutionParameters poate fi folosit pentru a trece StageSolutionUploadId a unei soluții etapizate, așa cum s-a arătat în exemplul de cod Web API. Mai multe informații: Etapizarea unei soluții

Răspunsul returnat de la ImportSolutionAsync conține ImportJobKey și AsyncOperationId. Valoarea ImportJobKey poate fi utilizată pentru a obține rezultatul importului, iar valoarea AsyncOperationId poate fi utilizată pentru a urmări starea operațiunii de import.

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
    }
}

Exportul soluției

ExportSolution este acțiunea (sau mesajul) care efectuează operațiunea de export sincron. Pentru a executa operațiunea de export în mod asincron, utilizați ExportSolutionAsync.

Operație API web Dataverse SDK pentru .NET
Exportul unei soluţii ExportSoluțieAsincronă ExportSolutionAsyncRequest
Descărcați un fișier de soluție exportat DescărcareSoluțieExportareDate DescărcareSoluțieExportareDateCerere

Acum să aruncăm o privire la un exemplu de cod care prezintă 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);

În răspuns sunt valorile parametrilor AsyncOperationId și ExportJobId . Utilizați AsyncOperationId în răspuns pentru a verifica succesul (statecode == 3; statuscode == 30) operațiunii asincrone. Apoi, utilizați acțiunea DownloadSolutionExportData (sau mesajul) cu valoarea ExportJobId din răspunsul de export pentru a descărca fișierul de soluție exportat, care este returnat în parametrul 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);

Vedeți și

Exemplu: Stabilirea soluțiilor cu import asincron