Skip to content
Matthew Adams By Matthew Adams Co-Founder
How to use Power BI Embedded with AspNetCore

If you are looking to build an AspNetCore website, and take advantage of Power BI embedded, you've probably found that there isn't any SDK support for basic report rendering (yet).

While the underlying PowerBI.Core and PowerBI.Api assemblies work just fine, there is no equivalent to PowerBI.MVC, and PowerBI.Javascript fails to install correctly in the new project type.

The latter is easily fixed - just manually add the PowerBI.js file to your bundling in the usual way.

The former problem requires a snippet of code to give you the necessary IHtmHelper extensions. Here's that snippet:

namespace EndjinWeb.PowerBI
{
    using Microsoft.AspNetCore.Html;
    using Microsoft.AspNetCore.Mvc.ModelBinding;
    using Microsoft.AspNetCore.Mvc.Rendering;
    using Microsoft.AspNetCore.Mvc.ViewFeatures;
    using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
    using Microsoft.PowerBI.Api.V1.Models;
    using System;
    using System.Collections.Generic;
    using System.Linq.Expressions;

    public static class ReportExtensions
    {
        /// <summary>
        /// Renders a Power BI report based on the specified report
        /// </summary>
        /// <param name="htmlHelper">The HTML helper</param>
        /// <param name="name">The name to associate with this report</param>
        /// <param name="report">The Power BI report</param>
        /// <param name="htmlAttributes">Additional attributes used while rendering the report</param>
        /// <returns></returns>
        public static IHtmlContent PowerBIReport(this IHtmlHelper htmlHelper, string name, Report report, object htmlAttributes = null)
        {
            return ReportHelper(htmlHelper, null, report, name, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
        }

        /// <summary>
        /// Renders a Power BI report based on the specified embedUrl
        /// </summary>
        /// <param name="htmlHelper">The HTML helper</param>
        /// <param name="name">The name to associate with this report</param>
        /// <param name="embedUrl">The report embed url</param>
        /// <param name="htmlAttributes">Additional attributes used while rendering the report</param>
        /// <returns></returns>
        public static IHtmlContent PowerBIReport(this IHtmlHelper htmlHelper, string name, string embedUrl, object htmlAttributes = null)
        {
            var report = new Report { EmbedUrl = embedUrl };
            return ReportHelper(htmlHelper, null, report, name, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
        }

        /// <summary>
        /// Renders the Power BI report based on the specified report expression
        /// </summary>
        /// <typeparam name="TModel">The view mode.</typeparam>
        /// <typeparam name="TProperty">The property containing your report</typeparam>
        /// <param name="htmlHelper">The HTML helper</param>
        /// <param name="expression">The report expression</param>
        /// <param name="htmlAttributes">Additional attributes used while rendering the report</param>
        /// <returns></returns>
        public static IHtmlContent PowerBIReportFor<TModel, TProperty>(this IHtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null)
        {          
         
            var modelExplorer = ExpressionMetadataProvider.FromLambdaExpression(expression, htmlHelper.ViewData, htmlHelper.MetadataProvider);
            return ReportHelper(htmlHelper, modelExplorer.Metadata, modelExplorer.Model, ExpressionHelper.GetExpressionText(expression), HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
        }

        private static IHtmlContent ReportHelper(this IHtmlHelper htmlHelper, ModelMetadata metadata, object value, string expression, IDictionary<string, object> htmlAttributes)
        {
            var fullHtmlFieldName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(expression);

            var embedUrl = value as string;
            Report report = null;

            if (string.IsNullOrWhiteSpace(embedUrl))
            {
                report = value as Report;
                if (report != null)
                {
                    embedUrl = report.EmbedUrl;
                }
            }

            var tagBuilder = new TagBuilder("div") { TagRenderMode = TagRenderMode.Normal };
            tagBuilder.MergeAttributes(htmlAttributes, true);
            tagBuilder.MergeAttribute("powerbi-embed-url", embedUrl, true);
            tagBuilder.MergeAttribute("powerbi-type", "report", true);
            tagBuilder.GenerateId(fullHtmlFieldName,"?");

            return tagBuilder;
        }
    }
}

Matthew Adams

Co-Founder

Matthew Adams

Matthew was CTO of a venture-backed technology start-up in the UK & US for 10 years, and is now the co-founder of endjin, which provides technology strategy, experience and development services to its customers who are seeking to take advantage of Microsoft Azure and the Cloud.