CSharp - Other

Difference between Parse / TryParse / ParseExact / TryParseExact

Parse

int.Parse("12.44");

Exception : Above code will generate the exception Input string was not in a correct format, just because you are trying to cast float / real value in Integer. Only it is parsing if your parameter value must match the desire type in which you are trying to parse.



TryParse

case #1
int.TryParse("14.55",out a);

case #2
int.TryParse("14", out a);

Output : Above code (case 1) will return false, just because parsing operation gets failed and value for variable 'a' would be 'zero'. Here consider 'a' is output type of parameter like we have in Oracle / SQL Server (not exactly same but behavior is same). If parsing get succeeded than it will return true and target variable (i.e. 'a') will have the parsed value, like in code (case 2), 'a' will return 14.


Difference between out and ref type

ref : parameter variable need to be assigned before passing to called function otherwise you will get the compile time error/there is no compulsion for called function to assign value in ref type parameter variable.

out : parameter variable need not to be assigned before passing in the called function but here we have compulsion for called method to assign a value in out type parameter variable before control leaves the current method as compile time error comes.



ParseExact

Case #1
string dateString = "Mon 16 Jun 8:30 AM 2008";
System.DateTime dt = DateTime.Parse(dateString).ToString("dd-MMM-yyyy")

MSDN : Because the Parse (String) method tries to parse the string representation of a date and time using the formatting rules of the current culture, trying to parse a particular string across different cultures can either fail or return different results If a specific date and time format will be parsed across different locales, use the DateTime.Parse(String, IFormatProvider) method or one of the overloads of the ParseExact method and provide a format specifier.


Exception : when you try to run this code it will give you an exception "String was not recognized as a valid DateTime".


Case #2
string dateString = "Mon 16 Jun 8:30 AM 2008"; 
string dateformat = "ddd dd MMM h:mm tt yyyy";

Response.Write(DateTime.ParseExact(dateString, format, CultureInfo.InvariantCulture).ToString("dd-MMM-yyyy"));

Output : The CultureInfo.InvariantCulture property is used if you are formatting or parsing a string that should be parse able by a piece of software independent of the user's local settings.



TryParseExact

Case #1
string dateString = "Mon 16 Jun 8:30 AM 2008";
string dateformat = "ddd dd MMM h:mm tt yyyy";

DateTime dt;

if (DateTime.TryParseExact(dateString, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out dt))
  Response.Write("After Parsed : " + dt.ToString("dd-MMM-yyyy"));
else
  Response.Write("Parsing Failed:" + dt.ToString("dd-MMM-yyyy"));

Output : Would be "After Parsed : " + , because your target date is exactly matched the format that you mentioned.


Case #2:
string dateString = "Mon 16 Jun 8:30 AM 2008";
string dateformat = "dd ddd MMM h:mm tt yyyy";

if (DateTime.TryParseExact(dateString, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out dt))
  Response.Write("After Parsed : " + dt.ToString("dd-MMM-yyyy"));
else
  Response.Write("Parsing Failed:" + dt.ToString("dd-MMM-yyyy"));

Output : Would be "Parsing Failed : 01-Jan-0001", because your target date is not exactly matched as the format that you mentioned.

Difference between String and string

String stands for System.String and it is a .NET Framework type. string is an alias in the C# language for System.String. Both of them are compiled to System.String in IL (Intermediate Language), so there is no difference. Choose what you like and use that. If you code in C#, I'd prefer string as it's a C# type alias and well-known by C# programmers.

Disabling Automatic Validation on Save Changes Method

using (var context = new DBContext())
{
    context.Configuration.ValidateOnSaveEnabled = false;
    context.SaveChanges();
}

Distinct in LINQ based on only one field

table.GroupBy(x => x.Column).Select(x => x.FirstOrDefault());

Do Proper Exception Handling

Do

catch(Exception ex) { 
  Logger.GetException(ex.Message); 
}

or

catch(Exception ex) { 
  throw; 
}


Don't

try { } 
catch(Eexception ex) { 
  throw ex; 
}

Dynamic Query for Filtering Data (LINQ-like Query)

Suppose you have a List<Person> and want to filter it dynamically by a property name.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

class Program
{
    static void Main()
    {
        var people = new List<Person>
        {
            new Person { Name = "Alice", Age = 25 },
            new Person { Name = "Bob", Age = 30 },
            new Person { Name = "Charlie", Age = 35 }
        };

        string propertyName = "Age";
        int value = 30;

        var parameter = Expression.Parameter(typeof(Person), "x");
        var property = Expression.Property(parameter, propertyName);
        var constant = Expression.Constant(value);
        var condition = Expression.GreaterThan(property, constant);

        var lambda = Expression.Lambda<Func<Person, bool>>(condition, parameter);

        var filteredList = people.AsQueryable().Where(lambda).ToList();

        foreach (var person in filteredList)
        {
            Console.WriteLine($"{person.Name}, {person.Age}");
        }
    }
}

Dynamic Query with Multiple Conditions

This example dynamically creates a query with AND or OR conditions based on user input.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

class Program
{
    static void Main()
    {
        var people = new List<Person>
        {
            new Person { Name = "Alice", Age = 25 },
            new Person { Name = "Bob", Age = 30 },
            new Person { Name = "Charlie", Age = 35 }
        };

        var parameter = Expression.Parameter(typeof(Person), "x");

        // Dynamic conditions
        var ageProperty = Expression.Property(parameter, "Age");
        var constant1 = Expression.Constant(30);
        var greaterThan = Expression.GreaterThan(ageProperty, constant1);

        var nameProperty = Expression.Property(parameter, "Name");
        var constant2 = Expression.Constant("Charlie");
        var equal = Expression.Equal(nameProperty, constant2);

        // Combine with OR: (x.Age > 30) || (x.Name == "Charlie")
        var orExpression = Expression.OrElse(greaterThan, equal);

        var lambda = Expression.Lambda<Func<Person, bool>>(orExpression, parameter);

        var result = people.AsQueryable().Where(lambda).ToList();

        foreach (var person in result)
        {
            Console.WriteLine($"{person.Name}, {person.Age}");
        }
    }
}

Dynamic Sorting (OrderBy)

Dynamically create an OrderBy clause for sorting by a property name.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

class Program
{
    static void Main()
    {
        var people = new List<Person>
        {
            new Person { Name = "Alice", Age = 25 },
            new Person { Name = "Bob", Age = 30 },
            new Person { Name = "Charlie", Age = 35 }
        };

        string sortBy = "Age";

        var parameter = Expression.Parameter(typeof(Person), "x");
        var property = Expression.Property(parameter, sortBy);

        var lambda = Expression.Lambda(property, parameter);

        var sortedList = people.AsQueryable()
                               .OrderBy((dynamic)lambda)
                               .ToList();

        foreach (var person in sortedList)
        {
            Console.WriteLine($"{person.Name}, {person.Age}");
        }
    }
}

EF Core: Easily detect slow running queries, and modify hard deletes

Implementing a Performance Interceptor

using Microsoft.EntityFrameworkCore.Diagnostics;
using System.Diagnostics;

public class PerformanceInterceptor : DbCommandInterceptor
{
    private const long QuerySlowThreshold = 100; // milliseconds

    public override InterceptionResult<DbDataReader> ReaderExecuting(
        DbCommand command, 
        CommandEventData eventData, 
        InterceptionResult<DbDataReader> result)
    {
        Stopwatch stopwatch = Stopwatch.StartNew();

        var originalResult = base.ReaderExecuting(command, eventData, result);

        stopwatch.Stop();
        if (stopwatch.ElapsedMilliseconds > QuerySlowThreshold)
        {
            Console.WriteLine($"Slow Query Detected: {command.CommandText}");
        }

        return originalResult;
    }
}


Implementing Soft Deletes

public class MyEntity
{
    public Guid Id { get; set; }
    public bool IsDeleted { get; set; }
    // Other properties...
}

public class SoftDeleteInterceptor : SaveChangesInterceptor
{
    public override InterceptionResult<int> SavingChanges(
        DbContextEventData eventData, 
        InterceptionResult<int> result)
    {
        foreach (var entry in eventData.Context.ChangeTracker.Entries())
        {
            if (entry.State == EntityState.Deleted && entry.Entity is MyEntity entity)
            {
                entity.IsDeleted = true;
                entry.State = EntityState.Modified;
            }
        }

        return base.SavingChanges(eventData, result);
    }
}


Register the interceptor with your DbContext.

using Microsoft.EntityFrameworkCore;

public class SampleDbContext : DbContext
{
    public DbSet<MyEntity> SampleEntities { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("Your_Connection_String");

        // Registering the PerformanceInterceptor
        optionsBuilder.AddInterceptors(new PerformanceInterceptor());

        // Registering the SoftDeleteInterceptor
        optionsBuilder.AddInterceptors(new SoftDeleteInterceptor());
    }   
}

Efficient Distinct Comparisons Using DistinctBy()

DistinctBy() efficiently removes duplicates from a collection based on a specific property without the overhead of GroupBy(). This improves performance and simplifies the code.


using System;
var titles = new List<string> { "Apple", "Banana", "Apple", "Orange", "Banana" };

// Remove duplicates based on value
var distinctTitles = titles.DistinctBy(title => title).ToList();

// Output distinct titles
distinctTitles.ForEach(Console.WriteLine);
//Apple, Banana, Orange

Email Notifications System

/// <summary>
/// Notifications system
/// </summary>
/// <returns>Result object</returns>
private Result NotificationsSystem()
{
    // Auxiliary variables
    DataTable _dtRecords;
    Result _Result = new Result();

    // Get results from database
    _dtRecords = GetResults();

    // Check success
    if (_dtRecords != null && _dtRecords.Rows.Count > 0)
    {
        // Load email template file path
        string _strEmailTemplate = LoadEmailTemplate();

        // Check email template path is not null
        if (string.IsNullOrEmpty(_strEmailTemplate))
        {
            // Add error message
            _Result.AddError("Undefined email template!");

            // Return
            return _Result;
        }

        // Check if template file exists
        if (!File.Exists(_strEmailTemplate))
        {
            // Add error message
            _Result.AddError("Email template doesn't exist!");

            // Return
            return _Result;
        }

        // Load excel directory path
        string _strExcelFilesPath = LoadExcelFilesPath();

        // Check if directory exists
        if (!Directory.Exists(Path.GetDirectoryName(_strExcelFilesPath)))
        {
            // Create directory
            Directory.CreateDirectory(Path.GetDirectoryName(_strExcelFilesPath));
        }

        // Load recipient emails list
        List<string> _lstRecipientEmails = LoadRecipientEmailsList();

        // Check if list are undefined
        if (_lstRecipientEmails == null || !_lstRecipientEmails.Any())
        {
            // Add error message
            _Result.AddError("Undefined recipient!");

            // Return
            return _Result;
        }

        // Generate excel file name
        string _strExcelFileName = Path.Combine(_strExcelFilesPath, string.Concat(Path.GetFileNameWithoutExtension(_strEmailTemplate), "_", Guid.NewGuid().ToString(), ".xlsx"));

        // Create excel file
        bool _blSuccess = ClExcel.CreateExcelFileFromDataTable(_dtRecords, _strExcelFileName);

        // Check success
        if (!_blSuccess)
        {
            // Add error message
            _Result.AddError("Error while creating the Excel file!");

            // Return
            return _Result;
        }

        // Send email
        SendEmail(_lstRecipientEmails, _strEmailTemplate, _strExcelFileName);
    }
    else
    {
        // Add info message
        _Result.AddInfo("No data is available!");

        // Return
        return _Result;
    }

    // Return
    return _Result;
}

/// <summary>
/// Send email
/// </summary>
/// <param name="_lstRecipientEmails">Recipient emails list</param>
/// <param name="_strEmailTemplate">Email template</param>
/// <param name="_strExcelFileName">Excel file name</param>
void SendEmail(List<string> _lstRecipientEmails, string _strEmailTemplate, string _strExcelFileName)
{
    // Email configurations
    string _strFrom = "FromEmail@gmail.com";
    string _strFromPassword = "FromPassword";

    // Create email message
    MailMessage _Message = new MailMessage();

    // Set from address
    _Message.From = new MailAddress(_strFrom);

    // Set subject
    _Message.Subject = "Subject Message!";

    // Set recipient list
    foreach (string item in _lstRecipientEmails)
        _Message.To.Add(new MailAddress(item));

    // Set body message (email template file
    _Message.Body = File.ReadAllText(_strEmailTemplate, Encoding.Default);
    _Message.IsBodyHtml = true;

    // Set attachment (Excel file)
    _Message.Attachments.Add(new Attachment(_strExcelFileName));

    // STMP configurations
    SmtpClient smtpClient = new SmtpClient("smtp.gmail.com")
    {
        Port = 587,
        Credentials = new System.Net.NetworkCredential(_strFrom, _strFromPassword),
        EnableSsl = true
    };

    // Send email
    smtpClient.Send(_Message);
}

/// <summary>
/// Get results from database
/// </summary>
/// <returns>Data table with the query results</returns>
DataTable GetResults()
{
    // Getting data from database should be implemented
}

/// <summary>
/// Load email template
/// </summary>
/// <returns>String with the email template path</returns>
string LoadEmailTemplate()
{
    // Getting the configuration of the email template must be implemented (.html file)
}

/// <summary>
/// Load Excel files path
/// </summary>
/// <returns>String with the Excel files directory</returns>
string LoadExcelFilesPath()
{
    // Getting the configuration of Excel files path must be implemented
}

/// <summary>
/// Load recipient emails list
/// </summary>
/// <returns>List of recipient emails list</returns>
List<string> LoadRecipientEmailsList()
{
    // Getting the recipient emails list must be implemented
}

Embed Power BI in your product for your customers (.NET Framework Embed Report)

Initialize

  1. Install nuget Microsoft.PowerBI.Api.
  2. Install nuget Microsoft.PowerBI.JavaScript.


Models

  • PBISetting.cs
public class PBISetting
{
  public string ApplicationId { get; set; }
  public List<Guid> WorkspaceId { get; set; }
  public List<List<Guid>> ReportId { get; set; }
  public string AuthenticationType { get; set; }
  public string Username { get; set; }
  public string Password { get; set; }
  public string ApplicationSecret { get; set; }
  public string Tenant { get; set; }
}
  • EmbedReport.cs
public class EmbedReport
{
  // Id of Power BI report to be embedded
  public Guid ReportId { get; set; }

  // Name of the report
  public string ReportName { get; set; }

  // Embed URL for the Power BI report
  public string EmbedUrl { get; set; }
}
  • ReportEmbedConfig.cs
public class ReportEmbedConfig
{
  // Report to be embedded
  public List<EmbedReport> EmbedReports { get; set; }

  // Embed Token for the Power BI report
  public EmbedToken EmbedToken { get; set; }
}
  • ErrorModel.cs
public class ErrorModel
{
  public string ErrorMessage { get; internal set; }
}


Services

  • AadService.cs
  public class AadService
  {
    private static readonly string m_authorityUrl = "https://login.microsoftonline.com/organizations";
    private static readonly string[] m_scope = "https://analysis.windows.net/powerbi/api/.default".Split(';');

    /// <summary>
    /// Get Access token
    /// </summary>
    /// <returns>Access token</returns>
    [Obsolete]
    public static async Task<string> GetAccessToken(PBISetting setting)
    {
      AuthenticationResult authenticationResult = null;
      if (setting.AuthenticationType.Equals("masteruser", StringComparison.InvariantCultureIgnoreCase))
      {
        IPublicClientApplication clientApp = PublicClientApplicationBuilder
                                  .Create(setting.ApplicationId)
                                  .WithAuthority(m_authorityUrl)
                                  .Build();
        var userAccounts = await clientApp.GetAccountsAsync();

        try
        {
          authenticationResult = await clientApp.AcquireTokenSilent(m_scope, userAccounts.FirstOrDefault()).ExecuteAsync();
        }
        catch (MsalUiRequiredException)
        {
          SecureString secureStringPassword = new SecureString();
          foreach (var key in setting.Password)
          {
            secureStringPassword.AppendChar(key);
          }
          authenticationResult = await clientApp.AcquireTokenByUsernamePassword(m_scope, setting.Username, secureStringPassword).ExecuteAsync();
        }
      }

      // Service Principal auth is recommended by Microsoft to achieve App Owns Data Power BI embedding
      else if (setting.AuthenticationType.Equals("serviceprincipal", StringComparison.InvariantCultureIgnoreCase))
      {
        // For app only authentication, we need the specific tenant id in the authority url
        var tenantSpecificURL = m_authorityUrl.Replace("organizations", setting.Tenant);

        IConfidentialClientApplication clientApp = ConfidentialClientApplicationBuilder
                                        .Create(setting.ApplicationId)
                                        .WithClientSecret(setting.ApplicationSecret)
                                        .WithAuthority(tenantSpecificURL)
                                        .Build();

        authenticationResult = await clientApp.AcquireTokenForClient(m_scope).ExecuteAsync();
      }

      return authenticationResult.AccessToken;
    }
  }
  • PBIService.cs
  public class PBIService
  {
    public static string CheckSettingError(PBISetting setting)
    {
      string message = null;
      Guid result;

      // Application Id must have a value.
      if (string.IsNullOrWhiteSpace(setting.ApplicationId))
      {
        message = "ApplicationId is empty. please register your application as Native app in https://dev.powerbi.com/apps and fill client Id in setting.";
      }
      // Application Id must be a Guid object.
      else if (!Guid.TryParse(setting.ApplicationId, out result))
      {
        message = "ApplicationId must be a Guid object. please register your application as Native app in https://dev.powerbi.com/apps and fill application Id in setting.";
      }
      // Workspace Id must have a value.
      else if (setting.WorkspaceId.Where(x => x == Guid.Empty).Count() > 0)
      {
        message = "WorkspaceId is empty or not a valid Guid. Please fill its Id correctly in setting";
      }
      // Report Id must have a value.
      else if (setting.ReportId.Where(x => x.Where(y => y == Guid.Empty).Count() > 0).Count() > 0)
      {
        message = "ReportId is empty or not a valid Guid. Please fill its Id correctly in setting";
      }
      else if (setting.AuthenticationType.Equals("masteruser", StringComparison.InvariantCultureIgnoreCase))
      {
        // Username must have a value.
        if (string.IsNullOrWhiteSpace(setting.Username))
        {
          message = "Username is empty. Please fill Power BI username in setting";
        }

        // Password must have a value.
        if (string.IsNullOrWhiteSpace(setting.Password))
        {
          message = "Password is empty. Please fill password of Power BI username in setting";
        }
      }
      else if (setting.AuthenticationType.Equals("serviceprincipal", StringComparison.InvariantCultureIgnoreCase))
      {
        if (string.IsNullOrWhiteSpace(setting.ApplicationSecret))
        {
          message = "ApplicationSecret is empty. please register your application as Web app and fill appSecret in setting.";
        }
        // Must fill tenant Id
        else if (string.IsNullOrWhiteSpace(setting.Tenant))
        {
          message = "Invalid Tenant. Please fill Tenant ID in Tenant under setting";
        }
      }
      else
      {
        message = "Invalid authentication type";
      }

      return message;
    }

    private static Guid GetParamGuid(string param)
    {
      Guid paramGuid = Guid.Empty;
      Guid.TryParse(param, out paramGuid);
      return paramGuid;
    }
  }
  • EmbedService.cs
  public static class EmbedService
  {
    private static readonly string urlPowerBiServiceApiRoot = "https://api.powerbi.com";

    public static async Task<PowerBIClient> GetPowerBiClient(PBISetting setting)
    {
      var tokenCredentials = new TokenCredentials(await AadService.GetAccessToken(setting), "Bearer");
      return new PowerBIClient(new Uri(urlPowerBiServiceApiRoot), tokenCredentials);
    }

    /// <summary>
    /// Get embed params for a report
    /// </summary>
    /// <returns>Wrapper object containing Embed token, Embed URL, Report Id, and Report name for single report</returns>
    public static async Task<ReportEmbedConfig> GetEmbedParams(PBISetting setting, Guid workspaceId, Guid reportId, [Optional] Guid additionalDatasetId)
    {
      using (var pbiClient = await GetPowerBiClient(setting))
      {
        // Get report info
        var pbiReport = pbiClient.Reports.GetReportInGroup(workspaceId, reportId);

        /*
        Check if dataset is present for the corresponding report
        If no dataset is present then it is a RDL report 
        */
        bool isRDLReport = String.IsNullOrEmpty(pbiReport.DatasetId);

        EmbedToken embedToken;

        if (isRDLReport)
        {
          // Get Embed token for RDL Report
          embedToken = await GetEmbedTokenForRDLReport(setting, workspaceId, reportId);
        }
        else
        {
          // Create list of dataset
          var datasetIds = new List<Guid>();

          // Add dataset associated to the report
          datasetIds.Add(Guid.Parse(pbiReport.DatasetId));

          // Append additional dataset to the list to achieve dynamic binding later
          if (additionalDatasetId != Guid.Empty)
          {
            datasetIds.Add(additionalDatasetId);
          }

          // Get Embed token multiple resources
          embedToken = await GetEmbedToken(setting, reportId, datasetIds, workspaceId);
        }

        // Add report data for embedding
        var embedReports = new List<EmbedReport>() {
          new EmbedReport
          {
            ReportId = pbiReport.Id, ReportName = pbiReport.Name, EmbedUrl = pbiReport.EmbedUrl
          }
        };

        // Capture embed params
        var embedParams = new ReportEmbedConfig
        {
          EmbedReports = embedReports,
          EmbedToken = embedToken
        };

        return embedParams;
      }
    }

    /// <summary>
    /// Get embed params for multiple reports for a single workspace
    /// </summary>
    /// <returns>Wrapper object containing Embed token, Embed URL, Report Id, and Report name for multiple reports</returns>
    /// <remarks>This function is not supported for RDL Report</remakrs>
    public static async Task<ReportEmbedConfig> GetEmbedParams(PBISetting setting, Guid workspaceId, IList<Guid> reportIds, [Optional] IList<Guid> additionalDatasetIds)
    {
      // Note: This method is an example and is not consumed in this sample app

      using (var pbiClient = await GetPowerBiClient(setting))
      {
        // Create mapping for reports and Embed URLs
        var embedReports = new List<EmbedReport>();

        // Create list of datasets
        var datasetIds = new List<Guid>();

        // Get datasets and Embed URLs for all the reports
        foreach (var reportId in reportIds)
        {
          // Get report info
          var pbiReport = pbiClient.Reports.GetReportInGroup(workspaceId, reportId);

          // Append to existing list of datasets to achieve dynamic binding later
          datasetIds.Add(Guid.Parse(pbiReport.DatasetId));

          // Add report data for embedding
          embedReports.Add(new EmbedReport { ReportId = pbiReport.Id, ReportName = pbiReport.Name, EmbedUrl = pbiReport.EmbedUrl });
        }

        // Append to existing list of datasets to achieve dynamic binding later
        if (additionalDatasetIds != null)
        {
          datasetIds.AddRange(additionalDatasetIds);
        }

        // Get Embed token multiple resources
        var embedToken = await GetEmbedToken(setting, reportIds, datasetIds, workspaceId);

        // Capture embed params
        var embedParams = new ReportEmbedConfig
        {
          EmbedReports = embedReports,
          EmbedToken = embedToken
        };

        return embedParams;
      }
    }

    /// <summary>
    /// Get Embed token for single report, multiple datasets, and an optional target workspace
    /// </summary>
    /// <returns>Embed token</returns>
    /// <remarks>This function is not supported for RDL Report</remakrs>
    public static async Task<EmbedToken> GetEmbedToken(PBISetting setting, Guid reportId, IList<Guid> datasetIds, [Optional] Guid targetWorkspaceId)
    {
      using (var pbiClient = await GetPowerBiClient(setting))
      {
        // Create a request for getting Embed token 
        // This method works only with new Power BI V2 workspace experience
        var tokenRequest = new GenerateTokenRequestV2(

        reports: new List<GenerateTokenRequestV2Report>() { new GenerateTokenRequestV2Report(reportId) },

        datasets: datasetIds.Select(datasetId => new GenerateTokenRequestV2Dataset(datasetId.ToString())).ToList(),

        targetWorkspaces: targetWorkspaceId != Guid.Empty ? new List<GenerateTokenRequestV2TargetWorkspace>() { new GenerateTokenRequestV2TargetWorkspace(targetWorkspaceId) } : null
        );

        // Generate Embed token
        var embedToken = pbiClient.EmbedToken.GenerateToken(tokenRequest);

        return embedToken;
      }
    }

    /// <summary>
    /// Get Embed token for multiple reports, datasets, and an optional target workspace
    /// </summary>
    /// <returns>Embed token</returns>
    /// <remarks>This function is not supported for RDL Report</remakrs>
    public static async Task<EmbedToken> GetEmbedToken(PBISetting setting, IList<Guid> reportIds, IList<Guid> datasetIds, [Optional] Guid targetWorkspaceId)
    {
      // Note: This method is an example and is not consumed in this sample app

      using (var pbiClient = await GetPowerBiClient(setting))
      {
        // Convert reports to required types
        var reports = reportIds.Select(reportId => new GenerateTokenRequestV2Report(reportId)).ToList();

        // Convert datasets to required types
        var datasets = datasetIds.Select(datasetId => new GenerateTokenRequestV2Dataset(datasetId.ToString())).ToList();

        // Create a request for getting Embed token 
        // This method works only with new Power BI V2 workspace experience
        var tokenRequest = new GenerateTokenRequestV2(

          datasets: datasets,

          reports: reports,

          targetWorkspaces: targetWorkspaceId != Guid.Empty ? new List<GenerateTokenRequestV2TargetWorkspace>() { new GenerateTokenRequestV2TargetWorkspace(targetWorkspaceId) } : null
        );

        // Generate Embed token
        var embedToken = pbiClient.EmbedToken.GenerateToken(tokenRequest);

        return embedToken;
      }
    }

    /// <summary>
    /// Get Embed token for multiple reports, datasets, and optional target workspaces
    /// </summary>
    /// <returns>Embed token</returns>
    /// <remarks>This function is not supported for RDL Report</remakrs>
    public static async Task<EmbedToken> GetEmbedToken(PBISetting setting, IList<Guid> reportIds, IList<Guid> datasetIds, [Optional] IList<Guid> targetWorkspaceIds)
    {
      // Note: This method is an example and is not consumed in this sample app

      using (var pbiClient = await GetPowerBiClient(setting))
      {
        // Convert report Ids to required types
        var reports = reportIds.Select(reportId => new GenerateTokenRequestV2Report(reportId)).ToList();

        // Convert dataset Ids to required types
        var datasets = datasetIds.Select(datasetId => new GenerateTokenRequestV2Dataset(datasetId.ToString())).ToList();

        // Convert target workspace Ids to required types
        IList<GenerateTokenRequestV2TargetWorkspace> targetWorkspaces = null;
        if (targetWorkspaceIds != null)
        {
          targetWorkspaces = targetWorkspaceIds.Select(targetWorkspaceId => new GenerateTokenRequestV2TargetWorkspace(targetWorkspaceId)).ToList();
        }

        // Create a request for getting Embed token 
        // This method works only with new Power BI V2 workspace experience
        var tokenRequest = new GenerateTokenRequestV2(

          datasets: datasets,

          reports: reports,

          targetWorkspaces: targetWorkspaceIds != null ? targetWorkspaces : null
        );

        // Generate Embed token
        var embedToken = pbiClient.EmbedToken.GenerateToken(tokenRequest);

        return embedToken;
      }
    }

    /// <summary>
    /// Get Embed token for RDL Report
    /// </summary>
    /// <returns>Embed token</returns>
    public static async Task<EmbedToken> GetEmbedTokenForRDLReport(PBISetting setting, Guid targetWorkspaceId, Guid reportId, string accessLevel = "view")
    {
      using (var pbiClient = await GetPowerBiClient(setting))
      {

        // Generate token request for RDL Report
        var generateTokenRequestParameters = new GenerateTokenRequest(
          accessLevel: accessLevel
        );

        // Generate Embed token
        var embedToken = pbiClient.Reports.GenerateTokenInGroup(targetWorkspaceId, reportId, generateTokenRequestParameters);

        return embedToken;
      }
    }
  }


Controllers

public class HomeController : Controller
{
  private string m_errorMessage;
  
  [Obsolete]
  public async Task<ActionResult> Index()
  {
    //Get User
    UserModel user = new UserModel();
    var users = crm.User.Where(x => x.IsActive == true).ToList();
    user = users.Where(x => x.ID.Equals(SessionHelper.UserID)).FirstOrDefault();
  
    if (user == null)
    {
      return RedirectToAction("Login", "Account");
    }
  
    //Get ClientProfile
    ClientProfileModel client = new ClientProfileModel();
    client = crm.ClientProfile.Where(x => x.ID.Equals(SessionHelper.ClientProfileID)).FirstOrDefault();
  
    if (client == null)
    {
      return RedirectToAction("Login", "Account");
    }
  
    //Get Workspaces
    List<PowerBIWorkspaceModel> workspace = new List<PowerBIWorkspaceModel>();
    var workspaces = crm.PowerBIWorkspace.Where(x => x.IsActive == true).ToList();
  
    if (user.PowerBIWorkspaceID != null)
    {
      workspace = workspaces.Where(x => user.PowerBIWorkspaceID.Split(',').ToList().Contains(x.ID.ToString())).ToList();
    }
  
    //Get Embeded
    List<PowerBIEmbedModel> embeds = new List<PowerBIEmbedModel>();
    List<List<Guid>> EmbedId = new List<List<Guid>>();
    List<List<string>> EmbedType = new List<List<string>>();
    List<List<string>> EmbedTitle = new List<List<string>>();
    embeds = crm.PowerBIEmbed.Where(x => x.IsActive == true).ToList();
    foreach (var w in workspace)
    {
      var e = embeds.Where(x => x.WorkspaceID.ToString() == w.ID.ToString());
      EmbedId.Add(e.Select(x => new Guid(x.EmbedID)).ToList());
    }
  
    string ApplicationId = client.PowerBIApplicationID;
    List<Guid> WorkspaceId = workspace.Select(x => new Guid(x.WorkspaceID)).ToList();
    string AuthenticationType = "masteruser";
    string ApplicationSecret = "";
    string Tenant = "";
    string Username = workspace.Select(x => x.PBIUsername).ToList().FirstOrDefault();
    string Password = workspace.Select(x => x.PBIPassword).ToList().FirstOrDefault();
  
    PBISetting setting = new PBISetting();
    setting.ApplicationId = ApplicationId;
    setting.WorkspaceId = WorkspaceId;
    setting.EmbedId = EmbedId;
    setting.EmbedType = EmbedType;
    setting.EmbedTitle = EmbedTitle;
    setting.AuthenticationType = AuthenticationType;
    setting.Username = Username;
    setting.Password = Password;
    setting.ApplicationSecret = ApplicationSecret;
    setting.Tenant = Tenant;
  
    m_errorMessage = PBIService.CheckSettingError(setting);
  
    if (!m_errorMessage.IsNullOrWhiteSpace())
    {
      return View("Error", BuildErrorModel(m_errorMessage));
    }
  
    try
    {
      EmbedConfig results = new EmbedConfig();
      List<ReportEmbedConfig> reportList = new List<ReportEmbedConfig>();
      List<DashboardEmbedConfig> dashboardList = new List<DashboardEmbedConfig>();
      List<TileEmbedConfig> tileList = new List<TileEmbedConfig>();
  
      for (int w = 0; w < setting.WorkspaceId.Count; w++)
      {
        var embedReport = await EmbedService.GetEmbedParams(setting, setting.WorkspaceId[w], setting.EmbedId[w]);
        reportList.Add(embedReport);
      }
  
      results.Reports = reportList;
      results.Dashboards = dashboardList;
      results.Tiles = tileList;
  
      return View(results);
    }
    catch (Exception ex)
    {
      //m_errorMessage = "Operation failed: system error. please contact your system administrator.";
      m_errorMessage = ex.Message;
      return View("Error", BuildErrorModel(m_errorMessage));
    }
  }
  
  private ErrorModel BuildErrorModel(string errorMessage)
  {
    return new ErrorModel
    {
      ErrorMessage = errorMessage
    };
  }
}


View

@if (Model.Count > 0)
{
    for (int i = 0; i < Model.Count; i++)
    {
        for (int j = 0; j < Model[i].EmbedReports.Count; j++)
        {
            string id = "embedContainer_" + i + "_" + j;


            <div id="@id" class="mb-3" style="height:@height"></div>
        }
    }
}

<script src="~/Scripts/powerbi-client/dist/powerbi.min.js"></script>
@if (Model.Count > 0)
{
    <script>
        // Get a reference to the embedded report HTML element
        const reportContainer = [];


        @for (int i = 0; i < Model.Count; i++)
        {
            for (int j = 0; j < Model[i].EmbedReports.Count; j++)
            {
                @:reportContainer.push($(`#embedContainer_@(i)_@(j)`)[0]);
            }
        }


        // Read embed application token from Model
        const accessToken = [];


        @for (int i = 0; i < Model.Count; i++)
        {
            for (int j = 0; j < Model[i].EmbedReports.Count; j++)
            {
                @:accessToken.push(`@(Model[i].EmbedToken.Token)`);
            }
        }


        // You can embed different reports as per your need by changing the index
        // Read embed URL from Model
        const embedUrl = [];


        @for (int i = 0; i < Model.Count; i++)
        {
            for (int j = 0; j < Model[i].EmbedReports.Count; j++)
            {
                @:embedUrl.push(`@(Model[i].EmbedReports[j].EmbedUrl)`);
            }
        }


        // Read report Id from Model
        const embedReportId = [];


        @for (int i = 0; i < Model.Count; i++)
        {
            for (int j = 0; j < Model[i].EmbedReports.Count; j++)
            {
                @:embedReportId.push(`@`(Model[i].EmbedReports[j].ReportId)`);
            }
        }


        // Use the token expiry to regenerate Embed token for seamless end user experience
        // Refer https://aka.ms/RefreshEmbedToken
        const tokenExpiry = [];


        @for (int i = 0; i < Model.Count; i++)
        {
            for (int j = 0; j < Model[i].EmbedReports.Count; j++)
            {
                @:embedReportId.push(`@(Html.Raw(Model[i].EmbedToken.Expiration))`);
            }
        }


        // Get models. models contains enums that can be used.
        const models = window['powerbi-client'].models;

        // Embed configuration used to describe the what and how to embed.
        // This object is used when calling powerbi.embed.
        // This also includes settings and options such as filters.
        // You can find more information at https://github.com/Microsoft/PowerBI-JavaScript/wiki/Embed-Configuration-Details.
        for (let i = 0; i < reportContainer.length; i++) {
            const config = {
                type: 'report',
                tokenType: models.TokenType.Embed,
                accessToken: accessToken[i],
                embedUrl: embedUrl[i],
                id: embedReportId[i],
                permissions: models.Permissions.All,
                settings: {
                    // Enable this setting to remove gray shoulders from embedded report
                    // background: models.BackgroundType.Transparent,
                    filterPaneEnabled: true,
                    navContentPaneEnabled: true
                }
            };


            // Embed the report and display it within the div container.
            const report = powerbi.embed(reportContainer[i], config);
        }
    </script>
}