{"id":35569,"date":"2019-03-07T06:00:53","date_gmt":"2019-03-07T13:00:53","guid":{"rendered":"http:\/\/devblogs.microsoft.com\/premier-developer\/?p=35569"},"modified":"2019-03-01T08:05:29","modified_gmt":"2019-03-01T15:05:29","slug":"exploring-blazor-with-visual-studio-2019","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/premier-developer\/exploring-blazor-with-visual-studio-2019\/","title":{"rendered":"Exploring Blazor with Visual Studio 2019"},"content":{"rendered":"<p>In this post, Senior App Dev Manager <a href=\"https:\/\/www.linkedin.com\/in\/keithbeller\">Keith Beller<\/a>\u00a0walks use through Blazor, a new experimental framework for WebAssembly.<\/p>\n<hr \/>\n<h2>What is Blazor?<\/h2>\n<p>After 22 years of dominance as \u201cthe\u201d native language for client-side browser interaction, JavaScript is facing new competition from other popular languages such as C\/C++, Go, PHP, C# and <a href=\"https:\/\/stackoverflow.com\/questions\/43540878\/what-languages-can-be-compiled-to-web-assembly-or-wasm\">others<\/a> thanks to the growing adoption of <a href=\"https:\/\/webassembly.org\/\">WebAssembly<\/a> or Wasm. All four major browser engines Firefox, Chrome, Safari and Edge now support WebAssembly. In fact, according to <a href=\"https:\/\/caniuse.com\/#search=webassembly\">caniuse.com<\/a> as of March 1<sup>st<\/sup> 2019 80.62% of users globally are using web browsers that support WebAssembly.<\/p>\n<p><a href=\"https:\/\/docs.microsoft.com\/en-us\/aspnet\/core\/client-side\/spa\/blazor\/?view=aspnetcore-3.0\">Blazor<\/a> is a new experimental web framework that allows you to write client-side web apps using C# all made possible by WebAssembly. That\u2019s right, C# running natively in the browser. Basically, WebAssembly apps are passed to the browser in an efficient binary instruction format that is able run natively and performantly at near-native speed and this has opened up new opportunities for languages like C# to run client-side in the browser.<\/p>\n<p>To demonstrate how easy it is to work with Blazor, we will walk you through a simple example app.<\/p>\n<h2>Getting started with Blazor<\/h2>\n<p>To get started with Blazor you\u2019ll need Visual Studio 2019, .Net Core SDK 3.0 Preview, the Blazor extensions form the Visual Studio Market Place and Blazor Templates. You\u2019ll find the installation guide (<a href=\"https:\/\/docs.microsoft.com\/en-us\/aspnet\/core\/client-side\/spa\/blazor\/get-started?view=aspnetcore-3.0&amp;tabs=visual-studio\">here<\/a>).<\/p>\n<h2>Create a new project<\/h2>\n<p>After you\u2019ve installed all the prerequisites, create your first project by selected ASP.NET Core Web Applications. Next, name your project and continue.<\/p>\n<p><img decoding=\"async\" width=\"1536\" height=\"1050\" class=\"wp-image-35570\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image.png\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image.png 1536w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-300x205.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-768x525.png 768w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-1024x700.png 1024w\" sizes=\"(max-width: 1536px) 100vw, 1536px\" \/><\/p>\n<p>If you\u2019ve installed everything correctly you should see .NET Core and ASP.NET Core 3.0 in the drop-down boxes with two Blazor templates. For this post we will work with the \u201cBlazor\u201d template.<\/p>\n<p><img decoding=\"async\" width=\"1536\" height=\"1050\" class=\"wp-image-35571\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-1.png\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-1.png 1536w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-1-300x205.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-1-768x525.png 768w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-1-1024x700.png 1024w\" sizes=\"(max-width: 1536px) 100vw, 1536px\" \/><\/p>\n<h2>Troubleshooting your first build<\/h2>\n<p>The main instructions don\u2019t call this out directly, but you\u2019ll need <a href=\"https:\/\/dotnet.microsoft.com\/download\/dotnet-core\/2.2\">.Net Core 2.2<\/a> installed to build and run your Blazor applications. If you don\u2019t have .NET Core 2.2, you will get an error when you build your app that reads, <em>\u201cPackage Microsoft.AspNetCore.Blazor.Cli 0.8.0-preview\u2026 is not compatible with netcoreapp2.2\u201d.<\/em><\/p>\n<p><img decoding=\"async\" width=\"2025\" height=\"1309\" class=\"wp-image-35572\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-2.png\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-2.png 2025w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-2-300x194.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-2-768x496.png 768w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-2-1024x662.png 1024w\" sizes=\"(max-width: 2025px) 100vw, 2025px\" \/><\/p>\n<p>You may think as I did that changing the &lt;TargetFramework&gt; to netcoreapp3.0 will fix the issue. It does not, instead changing the target framework will cause a linker error when you build in the Blazor.MonoRuntime.targets file on the line that executes the command \u201cdotnet &amp;quot;$(MonoLinkerPath)\u2026\u201d. If you tried deleting this line and didn\u2019t save a backup of the file, you\u2019ll need to delete the Blazor packages found in the C:\\Users\\&lt;USERNAME&gt;\\.nuget\\packages\\ directory and reinstall Blazor. So, to summarize, the fix here is leave the Target Framework alone and just the install .NET Core 2.2 SDK.<\/p>\n<p>You\u2019ll also want to enable previews of the .NET Core SDK which you can do by navigating to <strong>Tools &gt; Options <\/strong>and checking the box \u201cUse previews of the .NET Core SDK\u201d.<\/p>\n<p><img decoding=\"async\" width=\"2025\" height=\"1310\" class=\"wp-image-35573\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-3.png\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-3.png 2025w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-3-300x194.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-3-768x497.png 768w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-3-1024x662.png 1024w\" sizes=\"(max-width: 2025px) 100vw, 2025px\" \/><\/p>\n<p>Release notes for the latest release (0.8.0) as of this post can be found (<a href=\"https:\/\/devblogs.microsoft.com\/aspnet\/blazor-0-8-0-experimental-release-now-available\/\">here<\/a>). There is a troubleshooting section in the release notes should you get stuck.<\/p>\n<h2>Building a simple Mortgage Payment Calculator<\/h2>\n<p>Inspired by <a href=\"https:\/\/stackoverflow.com\/questions\/29567033\/simple-c-sharp-mortgage-formula-calculating-wrong\">this<\/a> Stack Overflow post, lets create a simple mortgage payment calculator to demonstrate the power of Blazor. If you\u2019re familiar with ASP.NET, you\u2019ll be very at home with the Blazor development experience. Blazor is essentially Razer views that run in the browser.<\/p>\n<p>To begin open <strong>Shared &gt; NavMenu.cshtml<\/strong> and add the snippet below to the @NavMenuCssClass div container and save the file.<\/p>\n<p>This will add a menu to the app side bar, so you are able to navigate to the calculator page we are going to build.<\/p>\n<p><img decoding=\"async\" width=\"381\" height=\"426\" class=\"wp-image-35574\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-4.png\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-4.png 381w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-4-268x300.png 268w\" sizes=\"(max-width: 381px) 100vw, 381px\" \/><\/p>\n<pre class=\"lang:default decode:true \">&lt;li class=\"nav-item px-3\"&gt;\r\n    &lt;NavLink class=\"nav-link\" href=\"calculator\"&gt;\r\n        &lt;span class=\"oi oi-list-rich\" aria-hidden=\"true\"&gt;&lt;\/span&gt; Calculator\r\n    &lt;\/NavLink&gt;\r\n&lt;\/li&gt;<\/pre>\n<p>Next, create a file in the Pages directory named Calculator.cshtml.<\/p>\n<p><img decoding=\"async\" width=\"388\" height=\"474\" class=\"wp-image-35575\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-5.png\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-5.png 388w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-5-246x300.png 246w\" sizes=\"(max-width: 388px) 100vw, 388px\" \/><\/p>\n<p>Paste this code snippet into the file and run the example.<\/p>\n<pre class=\"lang:default decode:true \">@page \"\/calculator\"\r\n\r\n&lt;div class=\"card\"&gt;\r\n    &lt;div class=\"card-header\"&gt;\r\n        &lt;h1&gt;Mortgage Payment Calculator&lt;\/h1&gt;\r\n    &lt;\/div&gt;\r\n    &lt;div class=\"card-body\"&gt;\r\n        &lt;div class=\"form-group\"&gt;\r\n            &lt;label for=\"enterPrinciple\"&gt;Principle Amount&lt;\/label&gt;\r\n            &lt;input id=\"enterPrinciple\" class=\"form-control\" aria-describedby=\"enterPrincipleHelp\" placeholder=\"Enter Principle\" bind=\"@p\" \/&gt;\r\n            &lt;small id=\"enterPrincipleHelp\" class=\"form-text text-muted\"&gt;Enter the princple amount. e.g. 100000&lt;\/small&gt;\r\n        &lt;\/div&gt;\r\n        &lt;div class=\"form-group\"&gt;\r\n            &lt;label for=\"enterInterest\"&gt;Interest Rate&lt;\/label&gt;\r\n            &lt;input id=\"enterInterest\" class=\"form-control\" aria-describedby=\"enterInterestHelp\" placeholder=\"Enter the interest rate\" bind=\"@r\" \/&gt;\r\n            &lt;small id=\"enterInterestHelp\" class=\"form-text text-muted\"&gt;Enter the interest rate. e.g.  3.75&lt;\/small&gt;\r\n        &lt;\/div&gt;\r\n        &lt;div class=\"form-group\"&gt;\r\n            &lt;label for=\"enterDuration\"&gt;Term (Years)&lt;\/label&gt;\r\n            &lt;select class=\"form-control\" aria-describedby=\"enterDurationHelp\" id=\"enterDuration\" bind=\"@y\"&gt;\r\n                @for (int i = 1; i &lt;= 30; i++)\r\n                {\r\n                    &lt;option&gt;@i&lt;\/option&gt;\r\n                }\r\n            &lt;\/select&gt;\r\n            &lt;small id=\"enterDurationHelp\" class=\"form-text text-muted\"&gt;Select the duration of the loan (in years).&lt;\/small&gt;\r\n        &lt;\/div&gt;\r\n        &lt;button class=\"btn btn-primary\" onclick=\"@Calculate\"&gt;Calculate&lt;\/button&gt;\r\n        &lt;br \/&gt;\r\n        &lt;br \/&gt;\r\n        &lt;div class=\"alert alert-secondary\" role=\"alert\"&gt;\r\n            Your monthly payment will be: &lt;strong&gt;$ @m.ToString(\"0.00\")&lt;\/strong&gt;\r\n        &lt;\/div&gt;\r\n    &lt;\/div&gt;\r\n&lt;\/div&gt;\r\n\r\n@functions {\r\n\r\n    double p = 100000; \/\/ principal\r\n    double r = 3.75; \/\/ interest rate\r\n    int y = 30; \/\/ number of payments\r\n    double m = 463.12; \/\/ monthly payment\r\n\r\n    void Calculate()\r\n    {\r\n        double rate = r \/ 100;\r\n        double monthlyRate = rate \/ 12;\r\n        double payments = 12 * y;\r\n\r\n        m = p * (monthlyRate * Math.Pow(1 + monthlyRate, payments)) \/ (Math.Pow(1 + monthlyRate, payments) - 1);\r\n    }\r\n}\r\n<\/pre>\n<p>If you\u2019ve done everything correctly you should see an interactive page that looks like this.<\/p>\n<p><img decoding=\"async\" width=\"1831\" height=\"1121\" class=\"wp-image-35576\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-6.png\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-6.png 1831w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-6-300x184.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-6-768x470.png 768w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-6-1024x627.png 1024w\" sizes=\"(max-width: 1831px) 100vw, 1831px\" \/><\/p>\n<p>Again, if you\u2019re familiar with ASP.NET this is a very low friction development experience. This page took just a few minutes to assemble. The binding experience Daniel and his team has put together looks very promising. Blazor also supports component libraries, dependency injection, debugging and much more. I encourage you to take a closer look at Blazor. For additional learning resources see Daniel Roth\u2019s video published on Channel 9 and also Robert Green\u2019s Visual Studio Toolbox episodes <a href=\"https:\/\/channel9.msdn.com\/Shows\/Visual-Studio-Toolbox\/Blazor-Part-1?term=Blazor&amp;lang-en=true\">Blazor Part 1<\/a> and <a href=\"https:\/\/channel9.msdn.com\/Shows\/Visual-Studio-Toolbox\/Blazor-Part-2?term=Blazor&amp;lang-en=true\">Blazor Part 2<\/a> with special guest Sam Basu and Ed Charbeneau. These videos provide an excellent introduction to the framework.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this post, Senior App Dev Manager Keith Beller\u00a0walks use through Blazor, a new experimental framework for WebAssembly. What is Blazor? After 22 years of dominance as \u201cthe\u201d native language for client-side browser interaction, JavaScript is facing new competition from other popular languages such as C\/C++, Go, PHP, C# and others thanks to the growing [&hellip;]<\/p>\n","protected":false},"author":582,"featured_media":35571,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[80,129,55],"tags":[61,3,386],"class_list":["post-35569","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net","category-premier","category-web","tag-asp-net-core","tag-team","tag-webassembly"],"acf":[],"blog_post_summary":"<p>In this post, Senior App Dev Manager Keith Beller\u00a0walks use through Blazor, a new experimental framework for WebAssembly. What is Blazor? After 22 years of dominance as \u201cthe\u201d native language for client-side browser interaction, JavaScript is facing new competition from other popular languages such as C\/C++, Go, PHP, C# and others thanks to the growing [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/posts\/35569","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/users\/582"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/comments?post=35569"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/posts\/35569\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/media\/35571"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/media?parent=35569"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/categories?post=35569"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/tags?post=35569"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}