Showing posts with label aspnet. Show all posts
Showing posts with label aspnet. Show all posts

Reading Notes #505

Me, thinking I could work with the dogs

Good Monday, Already time to share new reading notes. Here is a list of all the articles, blog posts, and podcast episodes that catch my interest during the week.

If you think you may have interesting content, share it!

Cloud

Programming

Miscellaneous

~frank


Reading Notes #486


It's Monday (the cyber one), time to share my reading notes. Those are a curated list of all the articles, blog posts, podcast episodes, and books that catch my interest during the week and that I found interesting. It's a mix of the actuality and what I consumed. 

You think you may have interesting content, share it!

 

Cloud

Programming

~Frank

Reading Notes #429

Suggestion of the week


Cloud


Programming

  • Remote Debugging .NET Containers (Karol Deland) - A nice tutorial that explains clearly first the difference between remote and local debugging and then explains how to do it.

Podcast


Miscellaneous

  • Screen Sharing with an Ultrawide Monitor (Kenny Lowe) - Really interesting post.As I think about getting a new screen and heard bad experiences sharing ultrawide screens this look like a nice solution.

Book


Vlog Like a Boss - How to Kill It Online with Video Blogging

Author: Amy Schmittauer Landino

An interesting book that shares the best practices about making videos today. How to plan, record, edit... What to do and not do. A quick, direct to the point and complete tutorial to get started. This book was done like today's videos.







~enjoy.

Reading Notes #335

IMG_20180622_184715Suggestion of the week


Cloud


Programming


Data


Miscellaneous



Reading Notes #321

ester-eggs-2345859_640

Suggestion of the week



Cloud



Programming



Databases



Miscellaneous


Books



When: The Scientific Secrets of Perfect Timing (Daniel H. Pink)

A really amazing book packed of very interesting advice. Things that you kind of already knew, or at least had a feeling you maybe knew are clearly explained to you.

After reading (or listening) this book, you will know why, and you can decide to fight it or change the when... improve your performance and use your time and energy on something else.

ISBN: 0525589333






Reading Notes #274

2017-04-03_5-57-51Suggestion of the week


Cloud


Programming



Secure a Asp.Net MVC multi-tenant Power Bi Embedded hosted in an Azure WebApp

Note: This post was originally published on Microsoft MVP Award blog, as part of the Technical Tuesday series.

Power Bi gives us the possibility to create amazing reports. Even if it's great to be able to share those reports from the very secure Power Bi portal sometimes we need to share them inside other applications or websites. Once again, Power BI doesn't disappoint us by providing Power BI Embedded. In this post, I will explain how to use Power Bi Embedded and make it secure so each tenant can only his data.

The Problem

Despite many online exist that explain how to use filters to change the witch is visible in our reports, filters can easily be changed by the user. Even if you hide the filter panel, those setting could easily be modified using JavaScript... Therefor, it's definitely not the best way to secure private information.

The Solution

In this post, I will be using roles to limit the access the data. The well knew the database Adventure Works will be used to demonstrate how to partition the data. In this case will be using the customer table.

In Azure

Open the Azure portal to create a Power BI Embedded component. Of course in a real project, it would be better to create it in an Azure Resource Management (ARM) template, but to keep this post simple we will create it with the portal. Click on the big green "+" at the top left corner. In the search box type powerbi, and hit Enter. Select Power BI Embedded in the list and click the Create button. Once it's created go to the Access Keys property of the brand-new Power BI Workspace Collection and take note of Key. We will need that key later to upload our Power BI report.

CreateWorkSpaceCollection

For this demo, the data source will be Adventure Works in an Azure Database. To do it simply click again the "+" button and select Database. Be sure to select Adventure Works as the source if to reproduce this demo.

createDB


In Power BI Desktop

Power BI Desktop is a free tool from Microsoft that will help us to create our report; it can be download here.
Before we get started, two options need to be modified. Go in the File menu and select Options and Settings, then Options. The first onr, is in the section (tab) Preview Features; check the option: Enable cross filtering in both direction for DirectQuery. The second is in the section DirectQuery, check the option Allow unrestricted measures in DirectQuery mode. It's a good idea to restart Power BI Desktop before continuing.

powerbioptions

To create our reports we first need to connect to our datasource, in this case our Azure Database. Click the Get Data button, then Azure and after that Microsoft Azure SQL Database. It's important to be attentive on the type of connection Import or Direct Query, because you won't be able to change it after. You will need to rebuild your report from scratch. For this case select DirectQuery.
This chart will be displaying information about invoice detail. Be sure to include the table that will be used for your role. In this case, I will be using Customer. Each customer must see only their invoices.

 tables

The report will contain two charts: the left one is a bar chart where you see the invoice historic, the right one is a pie chart that shows how products in the invoice(s) are distributed by category.
Note: in the sample database all customer have only one invoice and hey are all at the same date

chart_noRole

Now we need to create our dynamic Role. In the Modeling tab click on Manage Roles and create a CustomerRole mapping the CompanyName of the customer table to the variable USERNAME()

genericRole

Of course, to test if our charts are really dynamics, create other roles, and give them specific values ex: "Bike World" or "Action Bicycle Specialists". To visualize your report as those user, simply click on the View as Roles, in the Modeling tab, and select the role you want.

ViewAs

See how the charts look when see from "Action Bicycle Specialists".

chart_withRole

The report is now ready. Save it and we will need it soon.


Powerbi-cli

To upload our report in our Azure Workspace Collection, I like to use PowerBI-CLI because it runs everywhere, thanks to Node.js.
Open a command prompt or Terminal and execute the following command to install PowerBI-CLI:
npm install powerbi-cli -g
Now if you type 'powerbi' you should have the powerbi-cli help display.

powerbicli

It's time to use the access key we got previously, and use it in this command to create a workspace in our workspace collection.

//== Create Workspace ===========
powerbi create-workspace -c FrankWrkSpcCollection -k my_azure_workspace_collection_access_key

Now, let's upload our Power BI report into Azure. Retrieve the workspace ID returned by the previous command and pass it as the parameter -w (workspace).

//== Import ===========
powerbi import -c FrankWrkSpcCollection -w workspaceId -k my_azure_workspace_collection_access_key -f "C:\powerbidemo\CustomerInvoices.pbix" -n CustomerInvoices -o

Now we will need to update the connectionstring of our dataset. Get his ID with the following command:

//== Get-Datasets ===========
powerbi get-datasets -c FrankWrkSpcCollection -w workspaceId -k my_azure_workspace_collection_access_key 

Now update the connectionstring, passing the datasetId with the parameter -d:

//== update-connection ===========
powerbi update-connection -c FrankWrkSpcCollection -w workspaceId -k my_azure_workspace_collection_access_key -d 01fcabb6-1603-4653-a938-c83b7c45a59c -u usename@servername -p password


In Visual Studio

All the PowerBi Embeded part is now completed. Let's create the new Asp.Net MVC Web Application. A few Nuget packages are required, be sure to have those versions or newest:
  • Microsoft.PowerBI.AspNet.Mvc version="1.1.7"
  • Microsoft.PowerBI.Core version="1.1.6"
  • Microsoft.PowerBI.JavaScript version="2.2.6"
  • Newtonsoft.Json version="9.0.1"
By default Newtonsoft.Json is already there but needs an upgrade.
Update-Package Newtonsoft.Json
And for the Microsoft.PowerBI one, an install command should take care of all the other dependencies.

Install-Package Microsoft.PowerBI.AspNet.Mvc

We also need to add all the access information we previously used in our powerbi-Cli into our application. Let's add them in the web.config.

...
<appSettings>
    <add key="powerbi:AccessKey" value="my_azure_workspace_collection_access_key" />
    <add key="powerbi:ApiUrl" value="https://api.powerbi.com" />
    <add key="powerbi:WorkspaceCollection" value="FrankWrkSpcCollection" />
    <add key="powerbi:WorkspaceId" value="01fcabb6-1603-4653-a938-c83b7c45a59c" />
</appSettings>
...

Here the code of the InvoicesController:

using System;
using System.Configuration;
using System.Linq;
using System.Web.Mvc;
using demopowerbiembeded.Models;
using Microsoft.PowerBI.Api.V1;
using Microsoft.PowerBI.Security;
using Microsoft.Rest;
namespace demopowerbiembeded.Controllers
{
    public class InvoicesController : Controller
    {
        private readonly string workspaceCollection;
        private readonly string workspaceId;
        private readonly string accessKey;
        private readonly string apiUrl;
        public InvoicesController()
        {
            this.workspaceCollection = ConfigurationManager.AppSettings["powerbi:WorkspaceCollection"];
            this.workspaceId = ConfigurationManager.AppSettings["powerbi:WorkspaceId"];
            this.accessKey = ConfigurationManager.AppSettings["powerbi:AccessKey"];
            this.apiUrl = ConfigurationManager.AppSettings["powerbi:ApiUrl"];
        }
        private IPowerBIClient CreatePowerBIClient
        {
            get
            {
                var credentials = new TokenCredentials(accessKey, "AppKey");
                var client = new PowerBIClient(credentials)
                {
                    BaseUri = new Uri(apiUrl)
                };
                return client;
            }
        }
        public ReportViewModel GetFilteredRepot(string clientName)
        {
            using (var client = this.CreatePowerBIClient)
            {
                var reportsResponse = client.Reports.GetReportsAsync(this.workspaceCollection, this.workspaceId);
                var report = reportsResponse.Result.Value.FirstOrDefault(r => r.Name == "CustomerInvoices");
                var embedToken = PowerBIToken.CreateReportEmbedToken(this.workspaceCollection, this.workspaceId, report.Id, clientName, new string[] { "CustomerRole" });
                var model = new ReportViewModel
                {
                    Report = report,
                    AccessToken = embedToken.Generate(this.accessKey)
                };
                return model;
            }
        }
        public ActionResult Index()
        {
            var report = GetFilteredRepot("Action Bicycle Specialists");
            return View(report);
        }
    }
}

The interesting part of this controller is in the method GetFilteredRepot. First, it gets all the reports from our workspaces than look for the one named: "CustomerInvoices". The next step is where the loop gets closed; it creates the token. Of course, we pass the workspacecollection, workspace and report references, and that could be it. I mean passing only those references would result to our reports where all customers were displayed... But obviously that not what we want right now. The two last parameters are username and an Array of roles. When we created roles in Power BI Desktop, we created one call CustomerRole that was equal to the variable USERNAME(). So here we will pass the client name as username and specify that we want to use the role "CustomerRole".
Last piece to the puzzle is the View, so let add one.

@model demopowerbiembeded.Models.ReportViewModel
<style>iframe {border: 0;border-width: 0px;}</style>
<div id="test1" style="border-style: hidden;">
    @Html.PowerBIReportFor(m => m.Report, new { id = "pbi-report", style = "height:85vh", powerbi_access_token = Model.AccessToken })
</div>
@section scripts
{
    <script src="~/Scripts/powerbi.js"></script>
    <script>
        $(function () {
            var reportConfig = {
                settings: {
                    filterPaneEnabled: false,
                    navContentPaneEnabled: false
                }
            };
            var reportElement = document.getElementById('pbi-report');
            var report = powerbi.embed(reportElement, reportConfig);
        });
    </script>
}

One great advantage of using Asp.Net MVC is that we have an @Html.PowerBIReportFor at our disposal. Then we can instantiate the report with the call of powerbi.embed(reportElement, reportConfig);. Where I pass some configuration to remove the navigation, and the filter panes, but that optional.

Now if we run our project, you should have a result looking like that.

finalresult


Wrap it up

Viola! This of course was a demo and should be optimized. Please leave a comment if you have any questions, or don't hesitate to contact me. It's always great to chat with you.


References:



Reading Notes #258

AzureAdvisorSuggestion of the week

  • Announcing the public preview of Azure Advisor (Shankar Sivadasan) - This is definitely the most asked question from clients: how can I optimize my solutions. I was very positively surprised by the quality and precision of the suggestions of the advisor service. It's a must.

Cloud


Programming



Reading Notes #244

cakeWin10Cloud


Programming


Miscellaneous



Reading Notes #233

mprofileCloud


Programming


Miscellaneous



Reading Notes #217

yoman_asciiSuggestion of the week


Cloud


Programming


Miscellaneous



Reading Notes #207

msdnmagSuggestion of the week

  • A Beginner’s Mind - A very inspiring article, especially for the younger, but also for the more experienced, that want to keep their interior flame.

Cloud


Databases


Programming


Miscellaneous



Reading Notes #202

 

Azure automationSuggestion of the week


Cloud


Programming


Miscellaneous



Reading Notes #198

P1020009Cloud


Podcast

  • .NET Rocks! - Great episode very interesting discussion about the new Azure Service Fabric.

Programming


Databases



Get more from Azure application Insights

Application Insights is an incredible tool that will brings to you a gigantic quantity of information about your application. In a previous post: Tons statistics and metrics for Microsoft Azure websites (not only in Asp.Net), I was explaining how to get started with App Insights. In this post, I want to explain how you can create your own customs events or metrics.

The setup


I will use an Asp.Net MVC named SimpleWebApp that will consume an Azure Api App named FrankApiApp. For the demo purposes I will have both projects in the same solution, but let's pretend that the ApiApp is not us, and that we don't control what inside.

To create an Azure Api App you will need Visual Studio 2015 or Visual Studio 2013 with minimum Azure SDK 2.6 installed. When creating the app, select Asp.Net Web Application, then Azure Api App (Preview).

Azure_API_App

For this post, we simply need one function. Here the code of the Get method that will wait and return us a string:
    // GET api/values
    public IEnumerable<string> Get()
    {
        var rnd = new Random();
        var waitFor = rnd.Next(500, 3000);

        System.Threading.Thread.Sleep(waitFor);
        var msg = String.Format("You have wait {0}. Sorry about that.", waitFor);

        return new string[] { waitFor.ToString(), msg };
    }

The application where telemetries will be added is a simple Asp.Net Web Application with MVC, created with the default template in Visual Studio. To add App Insights, just right-click on the project and select Add Application Insights Telemetry.

Add_Azure_API_App_CLient

Now we need to add a reference of the Azure API App. That could be easily done. Right-click, once again, on the project and Select Add, then Azure API App Client. A new window will appear, and we only need to select our just deployed API App.

Select_API_App[3]

The Base


Of course, just by adding the code spinet to the head of _Layout.cshtml you will have a lot of information about your server, your application but also the client experience and browser. This is all very useful, and it worth the time to navigate/ dig in the Azure portal to understand how your application is going/ doing.


Custom Metric


An interesting information could be to measure the time for each call to FrankApiApp. Let's started by adding a custom metric. To do that we will add a function in the HomeController and a new tab in that menu of the _Layout.cshtml.
public class HomeController : Controller
{
    private TelemetryClient appInsights = new TelemetryClient();

    public ActionResult ApiCall()
    {
        var stopwatch = System.Diagnostics.Stopwatch.StartNew();
        var client = new FrankApiApp();
        var result = client.Values.Get();

        stopwatch.Stop();

        ViewBag.Message = result[1];

        appInsights.TrackMetric("TimeDoingNothing", stopwatch.Elapsed.TotalSeconds);

        return View("Contact");
    }
}   

First, we create an instance of TelemetryClient. Then before calling the FrankApiApp's Get method we start a stopwatch. And we just need to use the TrackMetric method to push the metric.

After deploying and navigating a little in the application, let see what's we have available for us. Open portal.azure.com, and navigate to your application Insights. Click on the Metrics Explorer, a new blade now open with three empty charts. Click on the timeline, then in the Metric texbox type "TimeDoingNothing" (new metric's name). Now, click on the grid (third chart), add the metric name and select Group By Continent. Interesting right?!

TimeDoingNothing


Even more


Application Insight gives the opportunity to track many things: PageViews, Events, Exception, Requests, Trace and of course Metrics. Here some alternative of our ApiCall function using the TrackEvent and TrackRequest.
// Using TrackEvent
public ActionResult ApiCall()
{
    var stopwatch = System.Diagnostics.Stopwatch.StartNew();

    var client = new FrankApiApp();
    var result = client.Values.Get();
    stopwatch.Stop();

    ViewBag.Message = result[1];

    var metrics = new Dictionary<string, double> {{"processingTime", stopwatch.Elapsed.TotalMilliseconds}};
    var properties = new Dictionary<string, string>  {{ "MessageSuggestedElapsed", result[0] } };

    // Send the event:
    appInsights.TrackEvent("APICallProcessed", properties, metrics);
    appInsights.TrackMetric("TimeDoingNothing", stopwatch.Elapsed.TotalSeconds);

    return View("Contact");
}



// Using TrackRequest
public ActionResult ApiCallWithTelemetry()
{
    appInsights.Context.Operation.Id = Guid.NewGuid().ToString();

    var stopwatch = System.Diagnostics.Stopwatch.StartNew();
    var client = new FrankApiApp();
    var result = client.Values.Get();

    stopwatch.Stop();

    ViewBag.Message = result[1];

    // Send the event:
    appInsights.TrackRequest("APICallRequest", DateTime.UtcNow, stopwatch.Elapsed, "200", true);
    appInsights.TrackMetric("TimeDoingNothing", stopwatch.Elapsed.TotalSeconds);

    return View("Contact");
}



Wrap it up


I couldn't show everything in one post, it's up to you to create new metrics, events and query them in Azure Application Insights. Share your discovery or questions in the comment section bellow.

References



Reading Notes #194

IMG_20150716_225401Suggestion of the week


Cloud

Customers can replicate on-premises workloads to Azure with Azure Site Recovery for 31 days at no charge

Programming


Documentation


Miscellaneous



~ Frank



Reading Notes #190

Father's daySuggestion of the week


Cloud


Programming


Miscellaneous


~Frank

Reading Notes #189

2015-06-15_0745Suggestion of the week


Cloud


Programming


~Frank


Reading Notes #186

published by Gartner
I finally watch most of the recorded sessions from Build, Ignite and MVPvConf, and I had more time to read.

Suggestion of the week

  • Learning to git bisect (Rural) - Very, very interesting walkthrough, I never knew Git got that kind of feature.

Cloud

Microsoft is currently the only vendor to be positioned as a Leader in Gartner’s Magic Quadrants for Cloud Infrastructure as a Service , Application Platform as a Service , Cloud Storage Services and Server Virtualization

Programming


Miscellaneous


~Frank

Note about the image of this week: This graphic was published by Gartner, Inc. as part of a larger research document and should be evaluated in the context of the entire document. The Gartner document is available upon request here.