Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Register now to learn Fabric in free live sessions led by the best Microsoft experts. From Apr 16 to May 9, in English and Spanish.

Silent failures using REST API C# library

We have an automated service that sends data using the REST API C# client library that runs on a schedule. Over the weekend, one of the pushes failed with a Forbidden error, and after that, subsequent pushes via the client failed silently. Restarting the service fixed the issue, but right now we have no obvious way to prevent this issue from happening again other than to trigger a restart if the service gets a Forbidden error.

Status: Needs Info
Comments
v-jiascu-msft
Employee

Hi @cgh-greg,

 

How did you get the token? How often did the Service refresh the token? Maybe the token expired. Can you share the exact code of the error?

 

Best Regards,

Dale

Vicky_Song
Impactful Individual
Status changed to: Needs Info
 
cgh-greg
Regular Visitor

I create a new Power BI Client every time data is pushed. The code that pushes data to tables is mainly these two functions:

 

public async Task PostRowsToTable<T>(Table table, IList<T> rowData, bool replace)
{
    using (var pbiClient = await this.CreatePowerBIClient())
    {
        Console.WriteLine($"Authenticated. {(replace ? "Replacing rows in" : "Appending rows to")} {table.Name}...");

        var datasetKey = await this.GetDatasetKey(pbiClient);

        if (replace)
        {
            // TODO: Revisit to see if I can delete certain rows from a table. Right now, the API doesn't seem to allow it.
            if (string.IsNullOrEmpty(config.GroupId))
                pbiClient.Datasets.DeleteRows(datasetKey, table.Name);
            else
                pbiClient.Datasets.DeleteRowsInGroup(config.GroupId, datasetKey, table.Name);
        }

        if (rowData.Any())
        {
            var batchSize = this.config.RowUploadBatchSize;
            if (batchSize < 1)
            {
                throw new Exception("Configured upload batch size must be greater than 0.");
            }

            if (rowData.Count() > batchSize)
                Console.WriteLine($"{table.Name}: 0/{rowData.Count} uploaded...");

            for (int i = 0; i < rowData.Count(); i += batchSize)
            {
                var batch = rowData.Skip(i).Take(batchSize);

                if (string.IsNullOrEmpty(config.GroupId))
                    pbiClient.Datasets.PostRows(datasetKey, table.Name, batch);
                else
                    pbiClient.Datasets.PostRowsInGroup(config.GroupId, datasetKey, table.Name, batch);
                    
                if (rowData.Count() > batchSize)
                {
                    if (i + batchSize < rowData.Count())
                        Console.WriteLine($"{table.Name}: {i + batch.Count()}/{rowData.Count} uploaded...");
                    else
                        Console.WriteLine($"Upload to {table.Name} complete.");
                }
            }
        }
    }
}
private async Task<IPowerBIClient> CreatePowerBIClient()
{
    if (authContext == null)
        authContext = new AuthenticationContext(config.AuthorityUrl, new TokenCache());

    Task<AuthenticationResult> authTask;

    if (string.IsNullOrEmpty(config.Username) || string.IsNullOrEmpty(config.Password))
    {
        // Prompt user for credentials
        authTask = authContext.AcquireTokenAsync(config.ResourceUrl, config.ClientId, new Uri(config.RedirectUrl), new PlatformParameters(PromptBehavior.Auto));
    }
    else
    {
        // Authenticate using configured credentials
        var credential = new UserPasswordCredential(config.Username, config.Password);
        authTask = authContext.AcquireTokenAsync(config.ResourceUrl, config.ClientId, credential);
    }

    var accessToken = (await authTask).AccessToken;

    var tokenCredentials = new TokenCredentials(accessToken, "Bearer");

    // Create a Power BI Client object (it will be used to call Power BI APIs)
    return new PowerBIClient(new Uri(config.ApiUrl), tokenCredentials);
}

 

cgh-greg
Regular Visitor

Any advice? It happened again this morning.