{"id":12735,"date":"2018-03-22T10:00:26","date_gmt":"2018-03-22T17:00:26","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/webdev\/?p=12735"},"modified":"2018-03-22T10:00:26","modified_gmt":"2018-03-22T17:00:26","slug":"get-started-building-net-web-apps-in-the-browser-with-blazor","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/get-started-building-net-web-apps-in-the-browser-with-blazor\/","title":{"rendered":"Get started building .NET web apps that run in the browser with Blazor"},"content":{"rendered":"<p><strong><em>For up to date instructions on how to get started with Blazor, please go to <a href=\"http:\/\/blazor.net\">https:\/\/blazor.net<\/a>.<\/em><\/strong><\/p>\n<p>Today we released our first public preview of <a href=\"https:\/\/github.com\/aspnet\/blazor\">Blazor<\/a>, a new experimental .NET web framework using C#\/Razor and HTML that runs in the browser with <a href=\"http:\/\/webassembly.org\">WebAssembly<\/a>. Blazor enables full stack web development with the stability, consistency, and productivity of .NET. While this release is alpha quality and should not be used in production, the code for this release was written from the ground up with an eye towards building a production quality web UI framework.<\/p>\n<p>In this release we&#8217;ve laid the ground work for the Blazor component model and added other foundational features, like routing, dependency injection, and JavaScript interop. We&#8217;ve also been working on the tooling experience so that you get great IntelliSense and completions in the Razor editor. Other features that have been demonstrated previously in prototype form, like live reload, debugging, and prerendering, have not been implemented yet, but are planned for future preview updates. Even so, there is plenty in this release for folks to start kicking the tires and giving feedback on the current direction. For additional details on what&#8217;s included in this release and known issue please see the <a href=\"https:\/\/go.microsoft.com\/fwlink\/?linkid=870448\">release notes<\/a>.<\/p>\n<p>Let&#8217;s get started!<\/p>\n<h3 id=\"help-feedback\">Help &amp; feedback<\/h3>\n<p>Your feedback is especially important to us during this experimental phase for Blazor. If you run into issues or have questions while trying out Blazor please let us know!<\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/aspnet\/blazor\/issues\">File issues on GitHub<\/a> for any problems you run into or to make suggestions for improvements.<\/li>\n<li>Chat with us and the Blazor community on <a href=\"https:\/\/gitter.im\/aspnet\/blazor\">Gitter<\/a> if you get stuck or to share how blazor is working for you.<\/li>\n<\/ul>\n<p>Also, after you&#8217;ve tried out Blazor for a while please let us know what you think by taking our in-product survey. Just click the survey link shown on the app home page when running one of the Blazor project templates:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/aspnet\/wp-content\/uploads\/sites\/16\/2018\/03\/blazor-survey-2.png\" alt=\"Blazor survey\" \/><\/p>\n<h3 id=\"get-started\">Get started<\/h3>\n<p>To get setup with Blazor:<\/p>\n<ol>\n<li>Install the <a href=\"https:\/\/www.microsoft.com\/net\/download\/dotnet-core\/sdk-2.1.300-preview1\">.NET Core 2.1 Preview 1 SDK<\/a>.<\/li>\n<li>Install the latest <em>preview<\/em> of <a href=\"https:\/\/www.visualstudio.com\/vs\/preview\">Visual Studio 2017 (15.7)<\/a> with the <em>ASP.NET and web development<\/em> workload.\n<ul>\n<li><em>Note:<\/em> You can install Visual Studio previews side-by-side with an existing Visual Studio installation without impacting your existing development environment.<\/li>\n<\/ul>\n<\/li>\n<li>Install the <a href=\"https:\/\/go.microsoft.com\/fwlink\/?linkid=870389\">ASP.NET Core Blazor Language Services extension<\/a> from the Visual Studio Marketplace.<\/li>\n<\/ol>\n<p>To create your first project from Visual Studio:<\/p>\n<ol>\n<li>Select <strong>File -&gt; New Project -&gt; Web -&gt; ASP.NET Core Web Application<\/strong><\/li>\n<li>Make sure .NET Core and ASP.NET Core 2.0 are selected at the top.<\/li>\n<li>\n<p>Pick the Blazor template<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/aspnet\/wp-content\/uploads\/sites\/16\/2018\/03\/new-blazor-app-dialog-2.png\" alt=\"New Blazor app dialog\" \/><\/p>\n<\/li>\n<li>\n<p>Press <strong>Ctrl-F5<\/strong> to run the app <em>without the debugger<\/em>. Running with the debugger (F5) is not supported at this time.<\/p>\n<\/li>\n<\/ol>\n<p>If you&#8217;re not using Visual Studio you can install the Blazor templates from the command-line:<\/p>\n<pre><code>dotnet new -&lt;span class=\"hljs-selector-tag\"&gt;i&lt;\/span&gt; Microsoft&lt;span class=\"hljs-selector-class\"&gt;.AspNetCore&lt;\/span&gt;&lt;span class=\"hljs-selector-class\"&gt;.Blazor&lt;\/span&gt;&lt;span class=\"hljs-selector-class\"&gt;.Templates&lt;\/span&gt;\ndotnet new blazor -o BlazorApp1\ncd BlazorApp1\ndotnet run\n<\/code><\/pre>\n<p>Congrats! You just ran your first Blazor app!<\/p>\n<h3 id=\"building-components\">Building components<\/h3>\n<p>When you browse to the app, you&#8217;ll see that it has three prebuilt pages: a home page, a counter page, and a fetch data page:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/aspnet\/wp-content\/uploads\/sites\/16\/2018\/03\/blazor-home-2.png\" alt=\"Blazor app home page\" \/><\/p>\n<p>These three pages are implemented by the three Razor files in the <code>Pages<\/code> folder: <code>Index.cshtml<\/code>, <code>Counter.cshtml<\/code>, <code>FetchData.cshtml<\/code>. Each of these files implements a Blazor component. The home page only contains static markup, but the counter and fetch data pages contain C# logic that will get compiled and executed client-side in the browser.<\/p>\n<p>The counter page has a button that increments a count each time you press it without a page refresh.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/aspnet\/wp-content\/uploads\/sites\/16\/2018\/03\/blazor-counter-2.png\" alt=\"Blazor app home page\" \/><\/p>\n<p>Normally this kind of client-side behavior would be handled in JavaScript, but here it&#8217;s implemented in C# and .NET by the <code>Counter<\/code> component. Take a look at the implementation of the <code>Counter<\/code> component in the <code>Counter.cshtml<\/code> file:<\/p>\n<pre><code class=\"lang-html\">&lt;span class=\"hljs-meta\"&gt;@page&lt;\/span&gt; &lt;span class=\"hljs-string\"&gt;\"\/counter\"&lt;\/span&gt;\n&lt;span class=\"hljs-variable\"&gt;&lt;h1&gt;&lt;\/span&gt;Counter&lt;span class=\"hljs-variable\"&gt;&lt;\/h1&gt;&lt;\/span&gt;\n\n&lt;span class=\"hljs-variable\"&gt;&lt;p&gt;&lt;\/span&gt;Current count: &lt;span class=\"hljs-meta\"&gt;@currentCount&lt;\/p&gt;&lt;\/span&gt;\n\n&lt;span class=\"hljs-variable\"&gt;&lt;button @onclick(IncrementCount)&gt;&lt;\/span&gt;Click me&lt;span class=\"hljs-variable\"&gt;&lt;\/button&gt;&lt;\/span&gt;\n\n&lt;span class=\"hljs-meta\"&gt;@functions&lt;\/span&gt; {\n    int currentCount = 0;\n\n    void IncrementCount()\n    {\n        currentCount++;\n    }\n}\n<\/code><\/pre>\n<p>Each Razor (.cshtml) file defines a Blazor component. A Blazor component is a .NET class that defines a reusable piece of web UI. The UI for the <code>Counter<\/code> component is defined using normal HTML. Dynamic rendering logic (loops, conditionals, expressions, etc.) can be added using <a href=\"https:\/\/docs.microsoft.com\/aspnet\/core\/mvc\/views\/razor\">Razor syntax<\/a>. The HTML markup and rendering logic are converted into a component class at build time. The name of the generated .NET class matches the name of the file.<\/p>\n<p>Members of the component class are defined in a <code>@functions<\/code> block. In the <code>@functions<\/code> block you can specify component state (properties, fields) as well as methods for event handling or for defining other component logic. These members can then be used as part of the component&#8217;s rendering logic and for handling events.<\/p>\n<p><em>Note:<\/em> Defining components in a single Razor file is typical, but in a future update you will also be able to define component logic in a code behind file.<\/p>\n<p>Each time an event occurs on a component (like the <code>onclick<\/code> event in the <code>Counter<\/code> component), that component regenerates its render tree. Blazor will then compare the new render tree against the previous one and apply any modifications to the browser DOM.<\/p>\n<h3 id=\"routing-to-components\">Routing to components<\/h3>\n<p>The <code>@page<\/code> directive at the top of the <code>Counter.cshtml<\/code> file specifies that this component is a page to which requests can be routed. Specifically, the <code>Counter<\/code> component will handle requests sent to <code>\/counter<\/code>. Without the <code>@page<\/code> directive the component would not handle any routed request, but it could still be used by other components.<\/p>\n<p>Routing requests to specific components is handled by the Router component, which is used by the root <code>App<\/code> component in <code>App.cshtml<\/code>:<\/p>\n<pre><code class=\"lang-html\">&lt;span class=\"hljs-comment\"&gt;&lt;!--\n    Configuring this here is temporary. Later we'll move the app config\n    into Program.cs, and it won't be necessary to specify AppAssembly.\n--&gt;&lt;\/span&gt;\n&lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;Router&lt;\/span&gt; &lt;span class=\"hljs-attr\"&gt;AppAssembly&lt;\/span&gt;=&lt;span class=\"hljs-string\"&gt;typeof(Program).Assembly&lt;\/span&gt; \/&gt;&lt;\/span&gt;\n<\/code><\/pre>\n<h3 id=\"using-components\">Using components<\/h3>\n<p>Once you define a component it can be used to implement other components. For example, we can add a <code>Counter<\/code> component to the home page of the app, like this:<\/p>\n<pre><code class=\"lang-html\">&lt;span class=\"hljs-meta\"&gt;@page&lt;\/span&gt; &lt;span class=\"hljs-string\"&gt;\"\/\"&lt;\/span&gt;\n\n&lt;span class=\"hljs-variable\"&gt;&lt;h1&gt;&lt;\/span&gt;Hello, world!&lt;span class=\"hljs-variable\"&gt;&lt;\/h1&gt;&lt;\/span&gt;\n\nWelcome to your new app.\n\n&lt;span class=\"hljs-variable\"&gt;&lt;SurveyPrompt Title=\"How is Blazor working for you?\" \/&gt;&lt;\/span&gt;\n\n&lt;span class=\"hljs-variable\"&gt;&lt;Counter \/&gt;&lt;\/span&gt;\n<\/code><\/pre>\n<p>If you build and run the app again (live reload <a href=\"https:\/\/github.com\/aspnet\/Blazor\/issues\/5\">coming soon<\/a>!) you should now see a separate instance of the <code>Counter<\/code> component on the home page.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/aspnet\/wp-content\/uploads\/sites\/16\/2018\/03\/blazor-home-with-counter-2.png\" alt=\"Blazor home page with counter\" \/><\/p>\n<h3 id=\"component-parameters\">Component parameters<\/h3>\n<p>Components can also have parameters, which you define using public properties on the component class. Let&#8217;s update the <code>Counter<\/code> component to have an <code>IncrementAmount<\/code> property that defaults to 1, but that we can change to something different.<\/p>\n<pre><code class=\"lang-html\">&lt;span class=\"hljs-meta\"&gt;@page&lt;\/span&gt; &lt;span class=\"hljs-string\"&gt;\"\/counter\"&lt;\/span&gt;\n&lt;h1&gt;Counter&lt;\/h1&gt;\n\n&lt;p&gt;Current count: &lt;span class=\"hljs-meta\"&gt;@currentCount&lt;\/span&gt;&lt;\/p&gt;\n\n&lt;button &lt;span class=\"hljs-meta\"&gt;@onclick&lt;\/span&gt;(IncrementCount)&gt;Click me&lt;\/button&gt;\n\n&lt;span class=\"hljs-meta\"&gt;@functions&lt;\/span&gt; {\n    &lt;span class=\"hljs-built_in\"&gt;int&lt;\/span&gt; currentCount = &lt;span class=\"hljs-number\"&gt;0&lt;\/span&gt;;\n\n    public &lt;span class=\"hljs-built_in\"&gt;int&lt;\/span&gt; IncrementAmount { &lt;span class=\"hljs-keyword\"&gt;get&lt;\/span&gt;; &lt;span class=\"hljs-keyword\"&gt;set&lt;\/span&gt;; } = &lt;span class=\"hljs-number\"&gt;1&lt;\/span&gt;;\n\n    &lt;span class=\"hljs-keyword\"&gt;void&lt;\/span&gt; IncrementCount()\n    {\n        currentCount += IncrementAmount;\n    }\n}\n<\/code><\/pre>\n<p>The component parameters can be set as attributes on the component tag. In the home page change the increment amount for the counter to 10.<\/p>\n<pre><code class=\"lang-html\">&lt;span class=\"hljs-meta\"&gt;@page&lt;\/span&gt; &lt;span class=\"hljs-string\"&gt;\"\/\"&lt;\/span&gt;\n\n&lt;span class=\"hljs-variable\"&gt;&lt;h1&gt;&lt;\/span&gt;Hello, world!&lt;span class=\"hljs-variable\"&gt;&lt;\/h1&gt;&lt;\/span&gt;\n\nWelcome to your new app.\n\n&lt;span class=\"hljs-variable\"&gt;&lt;Counter IncrementAmount=\"10\" \/&gt;&lt;\/span&gt;\n<\/code><\/pre>\n<p>When you build and run the app the counter on the home page now increments by 10, while the counter page still increments by 1.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/aspnet\/wp-content\/uploads\/sites\/16\/2018\/03\/blazor-home-count-by-ten-2.png\" alt=\"Blazor count by ten\" \/><\/p>\n<h3 id=\"layouts\">Layouts<\/h3>\n<p>The layout for the app is specified using the <code>@layout<\/code> directive in <code>_ViewImports.cshtml<\/code> in the <code>Pages<\/code> folder.<\/p>\n<pre><code class=\"lang-html\">&lt;span class=\"hljs-meta\"&gt;@layout&lt;\/span&gt; MainLayout\n<\/code><\/pre>\n<p>Layouts in Blazor are also also built as components. In our app the <code>MainLayout<\/code> component in <code>Shared\/MainLayout.cshtml<\/code> defines the app layout.<\/p>\n<pre><code class=\"lang-html\">&lt;span class=\"hljs-variable\"&gt;@implements&lt;\/span&gt; ILayoutComponent\n\n&lt;div class=&lt;span class=\"hljs-string\"&gt;'container-fluid'&lt;\/span&gt;&gt;\n    &lt;div class=&lt;span class=\"hljs-string\"&gt;'row'&lt;\/span&gt;&gt;\n        &lt;div class=&lt;span class=\"hljs-string\"&gt;'col-sm-3'&lt;\/span&gt;&gt;\n            &lt;NavMenu \/&gt;\n        &lt;\/div&gt;\n        &lt;div class=&lt;span class=\"hljs-string\"&gt;'col-sm-9'&lt;\/span&gt;&gt;\n            &lt;span class=\"hljs-variable\"&gt;@Body&lt;\/span&gt;\n        &lt;\/div&gt;\n    &lt;\/div&gt;\n&lt;\/div&gt;\n\n&lt;span class=\"hljs-variable\"&gt;@functions&lt;\/span&gt; {\n    &lt;span class=\"hljs-selector-tag\"&gt;public&lt;\/span&gt; &lt;span class=\"hljs-selector-tag\"&gt;RenderFragment&lt;\/span&gt; &lt;span class=\"hljs-selector-tag\"&gt;Body&lt;\/span&gt; { &lt;span class=\"hljs-selector-tag\"&gt;get&lt;\/span&gt;; &lt;span class=\"hljs-selector-tag\"&gt;set&lt;\/span&gt;; }\n}\n<\/code><\/pre>\n<p>Layout components implement <code>ILayoutComponent<\/code>. In Razor syntax interfaces can be implemented using the <code>@implements<\/code> directive. The <code>Body<\/code> property on the <code>ILayoutComponent<\/code> interface is used by the layout component to specify where the body content should be rendered. In our app the <code>MainLayout<\/code> component adds a <code>NavMenu<\/code> component and then renders the body in the main section of the page.<\/p>\n<p>The <code>NavMenu<\/code> component is implemented in <code>Shared\/NavMenu.cshtml<\/code> and creates a <a href=\"https:\/\/getbootstrap.com\/docs\/3.3\/\">Bootstrap<\/a> nav bar. The nav links are generated using the built-in <code>NavLink<\/code> component, which generates an anchor tag with an <code>active<\/code> CSS class if the current page matches the specified <code>href<\/code>.<\/p>\n<h3 id=\"the-root-component\">The root component<\/h3>\n<p>The root component for the app is specified in the app&#8217;s <code>Program.Main<\/code> entry point defined in <code>Program.cs<\/code>. This is also where you configure services with the service provider for the app.<\/p>\n<pre><code class=\"lang-csharp\">&lt;span class=\"hljs-keyword\"&gt;class&lt;\/span&gt; &lt;span class=\"hljs-title\"&gt;Program&lt;\/span&gt;\n{\n    &lt;span class=\"hljs-function\"&gt;&lt;span class=\"hljs-keyword\"&gt;static&lt;\/span&gt; &lt;span class=\"hljs-keyword\"&gt;void&lt;\/span&gt; &lt;span class=\"hljs-title\"&gt;Main&lt;\/span&gt;(&lt;span class=\"hljs-params\"&gt;&lt;span class=\"hljs-keyword\"&gt;string&lt;\/span&gt;[] args&lt;\/span&gt;)\n    &lt;\/span&gt;{\n        &lt;span class=\"hljs-keyword\"&gt;var&lt;\/span&gt; serviceProvider = &lt;span class=\"hljs-keyword\"&gt;new&lt;\/span&gt; BrowserServiceProvider(configure =&gt;\n        {\n            &lt;span class=\"hljs-comment\"&gt;\/\/ Add any custom services here&lt;\/span&gt;\n        });\n\n        &lt;span class=\"hljs-keyword\"&gt;new&lt;\/span&gt; BrowserRenderer(serviceProvider).AddComponent&lt;App&gt;(&lt;span class=\"hljs-string\"&gt;\"app\"&lt;\/span&gt;);\n    }\n}\n<\/code><\/pre>\n<p>The DOM element selector argument determines where the root component will get rendered. In our case, the <code>app<\/code> element in <code>index.html<\/code> is used.<\/p>\n<pre><code class=\"lang-html\">&lt;span class=\"hljs-meta\"&gt;&lt;!DOCTYPE html&gt;&lt;\/span&gt;\n&lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;html&lt;\/span&gt;&gt;&lt;\/span&gt;\n&lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;head&lt;\/span&gt;&gt;&lt;\/span&gt;\n    &lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;meta&lt;\/span&gt; &lt;span class=\"hljs-attr\"&gt;charset&lt;\/span&gt;=&lt;span class=\"hljs-string\"&gt;\"utf-8\"&lt;\/span&gt; \/&gt;&lt;\/span&gt;\n    &lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;title&lt;\/span&gt;&gt;&lt;\/span&gt;BlazorApp1&lt;span class=\"hljs-tag\"&gt;&lt;\/&lt;span class=\"hljs-name\"&gt;title&lt;\/span&gt;&gt;&lt;\/span&gt;\n    &lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;base&lt;\/span&gt; &lt;span class=\"hljs-attr\"&gt;href&lt;\/span&gt;=&lt;span class=\"hljs-string\"&gt;\"\/\"&lt;\/span&gt; \/&gt;&lt;\/span&gt;\n    &lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;link&lt;\/span&gt; &lt;span class=\"hljs-attr\"&gt;href&lt;\/span&gt;=&lt;span class=\"hljs-string\"&gt;\"css\/bootstrap\/bootstrap.min.css\"&lt;\/span&gt; &lt;span class=\"hljs-attr\"&gt;rel&lt;\/span&gt;=&lt;span class=\"hljs-string\"&gt;\"stylesheet\"&lt;\/span&gt; \/&gt;&lt;\/span&gt;\n    &lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;link&lt;\/span&gt; &lt;span class=\"hljs-attr\"&gt;href&lt;\/span&gt;=&lt;span class=\"hljs-string\"&gt;\"css\/site.css\"&lt;\/span&gt; &lt;span class=\"hljs-attr\"&gt;rel&lt;\/span&gt;=&lt;span class=\"hljs-string\"&gt;\"stylesheet\"&lt;\/span&gt; \/&gt;&lt;\/span&gt;\n&lt;span class=\"hljs-tag\"&gt;&lt;\/&lt;span class=\"hljs-name\"&gt;head&lt;\/span&gt;&gt;&lt;\/span&gt;\n&lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;body&lt;\/span&gt;&gt;&lt;\/span&gt;\n    &lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;app&lt;\/span&gt;&gt;&lt;\/span&gt;Loading...&lt;span class=\"hljs-tag\"&gt;&lt;\/&lt;span class=\"hljs-name\"&gt;app&lt;\/span&gt;&gt;&lt;\/span&gt; &lt;span class=\"hljs-comment\"&gt;&lt;!--Root component goes here--&gt;&lt;\/span&gt;\n\n    &lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;script&lt;\/span&gt; &lt;span class=\"hljs-attr\"&gt;src&lt;\/span&gt;=&lt;span class=\"hljs-string\"&gt;\"css\/bootstrap\/bootstrap-native.min.js\"&lt;\/span&gt;&gt;&lt;\/span&gt;&lt;span class=\"undefined\"&gt;&lt;\/span&gt;&lt;span class=\"hljs-tag\"&gt;&lt;\/&lt;span class=\"hljs-name\"&gt;script&lt;\/span&gt;&gt;&lt;\/span&gt;\n    &lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;script&lt;\/span&gt; &lt;span class=\"hljs-attr\"&gt;type&lt;\/span&gt;=&lt;span class=\"hljs-string\"&gt;\"blazor-boot\"&lt;\/span&gt;&gt;&lt;\/span&gt;&lt;span class=\"undefined\"&gt;&lt;\/span&gt;&lt;span class=\"hljs-tag\"&gt;&lt;\/&lt;span class=\"hljs-name\"&gt;script&lt;\/span&gt;&gt;&lt;\/span&gt;\n&lt;span class=\"hljs-tag\"&gt;&lt;\/&lt;span class=\"hljs-name\"&gt;body&lt;\/span&gt;&gt;&lt;\/span&gt;\n&lt;span class=\"hljs-tag\"&gt;&lt;\/&lt;span class=\"hljs-name\"&gt;html&lt;\/span&gt;&gt;&lt;\/span&gt;\n<\/code><\/pre>\n<h3 id=\"bootstrapping-the-runtime\">Bootstrapping the runtime<\/h3>\n<p>At build-time the <code>blazor-boot<\/code> script tag is replaced with a bootstrapping script that handles starting the .NET runtime and executing the app&#8217;s entry point. You can see the updated script tag using the browser developer tools.<\/p>\n<pre><code class=\"lang-html\">&lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;script&lt;\/span&gt; &lt;span class=\"hljs-attr\"&gt;src&lt;\/span&gt;=&lt;span class=\"hljs-string\"&gt;\"_framework\/blazor.js\"&lt;\/span&gt; &lt;span class=\"hljs-attr\"&gt;main&lt;\/span&gt;=&lt;span class=\"hljs-string\"&gt;\"BlazorApp1.dll\"&lt;\/span&gt; &lt;span class=\"hljs-attr\"&gt;entrypoint&lt;\/span&gt;=&lt;span class=\"hljs-string\"&gt;\"BlazorApp1.Program::Main\"&lt;\/span&gt; &lt;span class=\"hljs-attr\"&gt;references&lt;\/span&gt;=&lt;span class=\"hljs-string\"&gt;\"Microsoft.AspNetCore.Blazor.dll,netstandard.dll,...\"&lt;\/span&gt;&gt;&lt;\/span&gt;&lt;span class=\"undefined\"&gt;&lt;\/span&gt;&lt;span class=\"hljs-tag\"&gt;&lt;\/&lt;span class=\"hljs-name\"&gt;script&lt;\/span&gt;&gt;&lt;\/span&gt;\n<\/code><\/pre>\n<p>As part of the build Blazor will analyze which code paths are being used from the referenced assemblies and then remove unused assemblies and code.<\/p>\n<h3 id=\"dependency-injection\">Dependency injection<\/h3>\n<p>Services registered with the app&#8217;s service provider are available to components via dependency injection. You can inject services into a component using constructor injection or using the <code>@inject<\/code> directive. The latter is how an <code>HttpClient<\/code> is injected into the <code>FetchData<\/code> component.<\/p>\n<pre><code class=\"lang-html\">&lt;span class=\"hljs-keyword\"&gt;@page&lt;\/span&gt; &lt;span class=\"hljs-string\"&gt;\"\/fetchdata\"&lt;\/span&gt;\n&lt;span class=\"hljs-variable\"&gt;@inject&lt;\/span&gt; HttpClient Http\n<\/code><\/pre>\n<p>The <code>FetchData<\/code> component uses the injected <code>HttpClient<\/code> to retrieve some JSON from the server when the component is initialized.<\/p>\n<pre><code class=\"lang-csharp\">@functions {\n    WeatherForecast[] forecasts;\n\n    &lt;span class=\"hljs-function\"&gt;&lt;span class=\"hljs-keyword\"&gt;protected&lt;\/span&gt; &lt;span class=\"hljs-keyword\"&gt;override&lt;\/span&gt; &lt;span class=\"hljs-keyword\"&gt;async&lt;\/span&gt; Task &lt;span class=\"hljs-title\"&gt;OnInitAsync&lt;\/span&gt;(&lt;span class=\"hljs-params\"&gt;&lt;\/span&gt;)\n    &lt;\/span&gt;{\n        forecasts = &lt;span class=\"hljs-keyword\"&gt;await&lt;\/span&gt; Http.GetJsonAsync&lt;WeatherForecast[]&gt;(&lt;span class=\"hljs-string\"&gt;\"\/sample-data\/weather.json\"&lt;\/span&gt;);\n    }\n\n    &lt;span class=\"hljs-keyword\"&gt;class&lt;\/span&gt; &lt;span class=\"hljs-title\"&gt;WeatherForecast&lt;\/span&gt;\n    {\n        &lt;span class=\"hljs-keyword\"&gt;public&lt;\/span&gt; DateTime Date { &lt;span class=\"hljs-keyword\"&gt;get&lt;\/span&gt;; &lt;span class=\"hljs-keyword\"&gt;set&lt;\/span&gt;; }\n        &lt;span class=\"hljs-keyword\"&gt;public&lt;\/span&gt; &lt;span class=\"hljs-keyword\"&gt;int&lt;\/span&gt; TemperatureC { &lt;span class=\"hljs-keyword\"&gt;get&lt;\/span&gt;; &lt;span class=\"hljs-keyword\"&gt;set&lt;\/span&gt;; }\n        &lt;span class=\"hljs-keyword\"&gt;public&lt;\/span&gt; &lt;span class=\"hljs-keyword\"&gt;int&lt;\/span&gt; TemperatureF { &lt;span class=\"hljs-keyword\"&gt;get&lt;\/span&gt;; &lt;span class=\"hljs-keyword\"&gt;set&lt;\/span&gt;; }\n        &lt;span class=\"hljs-keyword\"&gt;public&lt;\/span&gt; &lt;span class=\"hljs-keyword\"&gt;string&lt;\/span&gt; Summary { &lt;span class=\"hljs-keyword\"&gt;get&lt;\/span&gt;; &lt;span class=\"hljs-keyword\"&gt;set&lt;\/span&gt;; }\n    }\n}\n<\/code><\/pre>\n<p>The data is deserialized into the <code>forecasts<\/code> C# variable as an array of <code>WeatherForecast<\/code> objects and then used to render the weather table.<\/p>\n<pre><code class=\"lang-html\">&lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;table&lt;\/span&gt; &lt;span class=\"hljs-attr\"&gt;class&lt;\/span&gt;=&lt;span class=\"hljs-string\"&gt;'table'&lt;\/span&gt;&gt;&lt;\/span&gt;\n    &lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;thead&lt;\/span&gt;&gt;&lt;\/span&gt;\n        &lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;tr&lt;\/span&gt;&gt;&lt;\/span&gt;\n            &lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;th&lt;\/span&gt;&gt;&lt;\/span&gt;Date&lt;span class=\"hljs-tag\"&gt;&lt;\/&lt;span class=\"hljs-name\"&gt;th&lt;\/span&gt;&gt;&lt;\/span&gt;\n            &lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;th&lt;\/span&gt;&gt;&lt;\/span&gt;Temp. (C)&lt;span class=\"hljs-tag\"&gt;&lt;\/&lt;span class=\"hljs-name\"&gt;th&lt;\/span&gt;&gt;&lt;\/span&gt;\n            &lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;th&lt;\/span&gt;&gt;&lt;\/span&gt;Temp. (F)&lt;span class=\"hljs-tag\"&gt;&lt;\/&lt;span class=\"hljs-name\"&gt;th&lt;\/span&gt;&gt;&lt;\/span&gt;\n            &lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;th&lt;\/span&gt;&gt;&lt;\/span&gt;Summary&lt;span class=\"hljs-tag\"&gt;&lt;\/&lt;span class=\"hljs-name\"&gt;th&lt;\/span&gt;&gt;&lt;\/span&gt;\n        &lt;span class=\"hljs-tag\"&gt;&lt;\/&lt;span class=\"hljs-name\"&gt;tr&lt;\/span&gt;&gt;&lt;\/span&gt;\n    &lt;span class=\"hljs-tag\"&gt;&lt;\/&lt;span class=\"hljs-name\"&gt;thead&lt;\/span&gt;&gt;&lt;\/span&gt;\n    &lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;tbody&lt;\/span&gt;&gt;&lt;\/span&gt;\n        @foreach (var forecast in forecasts)\n        {\n            &lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;tr&lt;\/span&gt;&gt;&lt;\/span&gt;\n                &lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;td&lt;\/span&gt;&gt;&lt;\/span&gt;@forecast.Date.ToShortDateString()&lt;span class=\"hljs-tag\"&gt;&lt;\/&lt;span class=\"hljs-name\"&gt;td&lt;\/span&gt;&gt;&lt;\/span&gt;\n                &lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;td&lt;\/span&gt;&gt;&lt;\/span&gt;@forecast.TemperatureC&lt;span class=\"hljs-tag\"&gt;&lt;\/&lt;span class=\"hljs-name\"&gt;td&lt;\/span&gt;&gt;&lt;\/span&gt;\n                &lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;td&lt;\/span&gt;&gt;&lt;\/span&gt;@forecast.TemperatureF&lt;span class=\"hljs-tag\"&gt;&lt;\/&lt;span class=\"hljs-name\"&gt;td&lt;\/span&gt;&gt;&lt;\/span&gt;\n                &lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;td&lt;\/span&gt;&gt;&lt;\/span&gt;@forecast.Summary&lt;span class=\"hljs-tag\"&gt;&lt;\/&lt;span class=\"hljs-name\"&gt;td&lt;\/span&gt;&gt;&lt;\/span&gt;\n            &lt;span class=\"hljs-tag\"&gt;&lt;\/&lt;span class=\"hljs-name\"&gt;tr&lt;\/span&gt;&gt;&lt;\/span&gt;\n        }\n    &lt;span class=\"hljs-tag\"&gt;&lt;\/&lt;span class=\"hljs-name\"&gt;tbody&lt;\/span&gt;&gt;&lt;\/span&gt;\n&lt;span class=\"hljs-tag\"&gt;&lt;\/&lt;span class=\"hljs-name\"&gt;table&lt;\/span&gt;&gt;&lt;\/span&gt;\n<\/code><\/pre>\n<h3 id=\"hosting-with-asp-net-core\">Hosting with ASP.NET Core<\/h3>\n<p>The Blazor template creates a client-side web application that can be used with any back end, but by hosting your Blazor application with ASP.NET Core you can do full stack web development with .NET.<\/p>\n<p>The &#8220;Blazor (ASP.NET Core Hosted)&#8221; project template creates a solution with three projects for you: 1. a Blazor client project, 2. an ASP.NET Core server project, and 3. a shared .NET Standard class library project.<\/p>\n<p>To host the Blazor app in ASP.NET Core the server project has a reference to the client project. Blazor-specific middleware makes the Blazor client app available to browsers.<\/p>\n<pre><code class=\"lang-csharp\">public void Configure(IApplicationBuilder &lt;span class=\"hljs-keyword\"&gt;app&lt;\/span&gt;, IHostingEnvironment env)\n{\n    &lt;span class=\"hljs-keyword\"&gt;app&lt;\/span&gt;.UseResponseCompression();\n\n    &lt;span class=\"hljs-keyword\"&gt;if&lt;\/span&gt; (env.IsDevelopment())\n    {\n        &lt;span class=\"hljs-keyword\"&gt;app&lt;\/span&gt;.UseDeveloperExceptionPage();\n    }\n\n    &lt;span class=\"hljs-keyword\"&gt;app&lt;\/span&gt;.UseMvc(routes =&gt;\n    {\n        routes.MapRoute(name: &lt;span class=\"hljs-string\"&gt;\"default\"&lt;\/span&gt;, template: &lt;span class=\"hljs-string\"&gt;\"{controller}\/{action}\/{id?}\"&lt;\/span&gt;);\n    });\n\n    &lt;span class=\"hljs-keyword\"&gt;app&lt;\/span&gt;.UseBlazor&lt;Client.&lt;span class=\"hljs-keyword\"&gt;Program&lt;\/span&gt;&gt;();\n}\n<\/code><\/pre>\n<p>In the standalone Blazor app the weather forecast data was a static JSON file, but in the hosted project the <code>SampleDataController<\/code> provides the weather data Using ASP.NET Core.<\/p>\n<p>The shared class library project is referenced by both the Blazor client project and the ASP.NET Core server project, so that code can be shared between the two projects. This is a great place to put your domain types. For example, the <code>WeatherForecast<\/code> class is used by the Web API in the ASP.NET Core project for serialization and in the Blazor project for deserialization.<\/p>\n<h3 id=\"build-a-todo-list\">Build a todo list<\/h3>\n<p>Let&#8217;s add a new page to our app that implements a simple todo list. Add a <code>Pages\/Todo.cshtml<\/code> file to the project. We don&#8217;t have a Blazor component item template in Visual Studio quite yet, but you can use the Razor View item template as a substitute. Replace the content of the file with some initial markup:<\/p>\n<pre><code class=\"lang-html\">&lt;span class=\"hljs-meta\"&gt;@page&lt;\/span&gt; &lt;span class=\"hljs-string\"&gt;\"\/todo\"&lt;\/span&gt;\n\n&lt;span class=\"hljs-variable\"&gt;&lt;h1&gt;&lt;\/span&gt;Todo&lt;span class=\"hljs-variable\"&gt;&lt;\/h1&gt;&lt;\/span&gt;\n<\/code><\/pre>\n<p>Now add the todo list page to the nav bar. Update <code>Shared\/Navbar.cshtml<\/code> to add a nav link for the todo list.<\/p>\n<pre><code class=\"lang-html\">&lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;li&lt;\/span&gt;&gt;&lt;\/span&gt;\n    &lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;NavLink&lt;\/span&gt; &lt;span class=\"hljs-attr\"&gt;href&lt;\/span&gt;=&lt;span class=\"hljs-string\"&gt;\"\/todo\"&lt;\/span&gt;&gt;&lt;\/span&gt;\n        &lt;span class=\"hljs-tag\"&gt;&lt;&lt;span class=\"hljs-name\"&gt;span&lt;\/span&gt; &lt;span class=\"hljs-attr\"&gt;class&lt;\/span&gt;=&lt;span class=\"hljs-string\"&gt;'glyphicon glyphicon-th-list'&lt;\/span&gt;&gt;&lt;\/span&gt;&lt;span class=\"hljs-tag\"&gt;&lt;\/&lt;span class=\"hljs-name\"&gt;span&lt;\/span&gt;&gt;&lt;\/span&gt; Todo\n    &lt;span class=\"hljs-tag\"&gt;&lt;\/&lt;span class=\"hljs-name\"&gt;NavLink&lt;\/span&gt;&gt;&lt;\/span&gt;\n&lt;span class=\"hljs-tag\"&gt;&lt;\/&lt;span class=\"hljs-name\"&gt;li&lt;\/span&gt;&gt;&lt;\/span&gt;\n<\/code><\/pre>\n<p>Build and run the app. You should now see the new todo page.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/aspnet\/wp-content\/uploads\/sites\/16\/2018\/03\/blazor-todo-start-1.png\" alt=\"Blazor todo start\" \/><\/p>\n<p>Add a class to represent your todo items.<\/p>\n<pre><code class=\"lang-csharp\">&lt;span class=\"hljs-keyword\"&gt;public&lt;\/span&gt; &lt;span class=\"hljs-keyword\"&gt;class&lt;\/span&gt; &lt;span class=\"hljs-title\"&gt;TodoItem&lt;\/span&gt;\n{\n    &lt;span class=\"hljs-keyword\"&gt;public&lt;\/span&gt; &lt;span class=\"hljs-keyword\"&gt;string&lt;\/span&gt; Title { &lt;span class=\"hljs-keyword\"&gt;get&lt;\/span&gt;; &lt;span class=\"hljs-keyword\"&gt;set&lt;\/span&gt;; }\n    &lt;span class=\"hljs-keyword\"&gt;public&lt;\/span&gt; &lt;span class=\"hljs-keyword\"&gt;bool&lt;\/span&gt; IsDone { &lt;span class=\"hljs-keyword\"&gt;get&lt;\/span&gt;; &lt;span class=\"hljs-keyword\"&gt;set&lt;\/span&gt;; }\n}\n<\/code><\/pre>\n<p>The <code>Todo<\/code> component will maintain the state of the todo list. In the <code>Todo<\/code> component add a field for the todos in a <code>@functions<\/code> block and a <code>foreach<\/code> loop to render them.<\/p>\n<pre><code class=\"lang-html\">&lt;span class=\"hljs-meta\"&gt;@page&lt;\/span&gt; &lt;span class=\"hljs-string\"&gt;\"\/todo\"&lt;\/span&gt;\n\n&lt;span class=\"hljs-variable\"&gt;&lt;h1&gt;&lt;\/span&gt;Todo&lt;span class=\"hljs-variable\"&gt;&lt;\/h1&gt;&lt;\/span&gt;\n\n&lt;span class=\"hljs-variable\"&gt;&lt;ul&gt;&lt;\/span&gt;\n    &lt;span class=\"hljs-meta\"&gt;@foreach&lt;\/span&gt; (var todo in todos)\n    {\n        &lt;span class=\"hljs-variable\"&gt;&lt;li&gt;&lt;\/span&gt;&lt;span class=\"hljs-meta\"&gt;@todo.Title&lt;\/li&gt;&lt;\/span&gt;\n    }\n&lt;span class=\"hljs-variable\"&gt;&lt;\/ul&gt;&lt;\/span&gt;\n\n&lt;span class=\"hljs-meta\"&gt;@functions&lt;\/span&gt; {\n    IList&lt;span class=\"hljs-variable\"&gt;&lt;TodoItem&gt;&lt;\/span&gt; todos = new List&lt;span class=\"hljs-variable\"&gt;&lt;TodoItem&gt;&lt;\/span&gt;();\n}\n<\/code><\/pre>\n<p>Now we need some UI for adding todos to the list. Add a text input and a button at the bottom of the list.<\/p>\n<pre><code class=\"lang-html\">&lt;span class=\"hljs-meta\"&gt;@page&lt;\/span&gt; &lt;span class=\"hljs-string\"&gt;\"\/todo\"&lt;\/span&gt;\n\n&lt;span class=\"hljs-variable\"&gt;&lt;h1&gt;&lt;\/span&gt;Todo&lt;span class=\"hljs-variable\"&gt;&lt;\/h1&gt;&lt;\/span&gt;\n\n&lt;span class=\"hljs-variable\"&gt;&lt;ul&gt;&lt;\/span&gt;\n    &lt;span class=\"hljs-meta\"&gt;@foreach&lt;\/span&gt; (var todo in todos)\n    {\n        &lt;span class=\"hljs-variable\"&gt;&lt;li&gt;&lt;\/span&gt;&lt;span class=\"hljs-meta\"&gt;@todo.Title&lt;\/li&gt;&lt;\/span&gt;\n    }\n&lt;span class=\"hljs-variable\"&gt;&lt;\/ul&gt;&lt;\/span&gt;\n\n&lt;span class=\"hljs-variable\"&gt;&lt;input placeholder=\"Something todo\" \/&gt;&lt;\/span&gt;\n&lt;span class=\"hljs-variable\"&gt;&lt;button&gt;&lt;\/span&gt;Add todo&lt;span class=\"hljs-variable\"&gt;&lt;\/button&gt;&lt;\/span&gt;\n\n&lt;span class=\"hljs-meta\"&gt;@functions&lt;\/span&gt; {\n    IList&lt;span class=\"hljs-variable\"&gt;&lt;TodoItem&gt;&lt;\/span&gt; todos = new List&lt;span class=\"hljs-variable\"&gt;&lt;TodoItem&gt;&lt;\/span&gt;();\n}\n<\/code><\/pre>\n<p>Nothing happens yet when we click the &#8220;Add todo&#8221; button, because we haven&#8217;t wired up an event handler. Add an <code>AddTodo<\/code> method to the <code>Todo<\/code> component and register it for button click using the <code>@onclick<\/code> attribute.<\/p>\n<pre><code class=\"lang-html\">@page &lt;span class=\"hljs-string\"&gt;\"\/todo\"&lt;\/span&gt;\n\n&lt;span class=\"hljs-params\"&gt;&lt;h1&gt;&lt;\/span&gt;Todo&lt;span class=\"hljs-params\"&gt;&lt;\/h1&gt;&lt;\/span&gt;\n\n&lt;span class=\"hljs-params\"&gt;&lt;ul&gt;&lt;\/span&gt;\n    @foreach (var todo in todos)\n    {\n        &lt;span class=\"hljs-params\"&gt;&lt;li&gt;&lt;\/span&gt;@todo.Title&lt;span class=\"hljs-params\"&gt;&lt;\/li&gt;&lt;\/span&gt;\n    }\n&lt;span class=\"hljs-params\"&gt;&lt;\/ul&gt;&lt;\/span&gt;\n\n&lt;span class=\"hljs-params\"&gt;&lt;input placeholder=\"Something todo\" \/&gt;&lt;\/span&gt;\n&lt;span class=\"hljs-params\"&gt;&lt;button @onclick(AddTodo)&gt;&lt;\/span&gt;Add todo&lt;span class=\"hljs-params\"&gt;&lt;\/button&gt;&lt;\/span&gt;\n\n@&lt;span class=\"hljs-class\"&gt;functions &lt;\/span&gt;{\n    IList&lt;span class=\"hljs-params\"&gt;&lt;TodoItem&gt;&lt;\/span&gt; todos = new List&lt;span class=\"hljs-params\"&gt;&lt;TodoItem&gt;&lt;\/span&gt;();\n\n    void AddTodo()\n    {\n        &lt;span class=\"hljs-comment\"&gt;\/\/ &lt;span class=\"hljs-doctag\"&gt;Todo:&lt;\/span&gt; Add the todo&lt;\/span&gt;\n    }\n}\n<\/code><\/pre>\n<p>The <code>AddTodo<\/code> method will now get called every time the button is clicked. To get the title of the new todo item add a <code>newTodo<\/code> string field and bind it to the value of the text input using the <code>@bind<\/code> attribute. This sets up a two-way bind. We can now update the <code>AddTodo<\/code> method to add the <code>TodoItem<\/code> with the specified title to the list. Don&#8217;t forget to clear the value of the text input by setting <code>newTodo<\/code> to an empty string.<\/p>\n<pre><code class=\"lang-html\">&lt;span class=\"hljs-meta\"&gt;@page&lt;\/span&gt; &lt;span class=\"hljs-string\"&gt;\"\/todo\"&lt;\/span&gt;\n\n&lt;h1&gt;Todo&lt;\/h1&gt;\n\n&lt;ul&gt;\n    &lt;span class=\"hljs-meta\"&gt;@foreach&lt;\/span&gt; (&lt;span class=\"hljs-keyword\"&gt;var&lt;\/span&gt; todo &lt;span class=\"hljs-keyword\"&gt;in&lt;\/span&gt; todos)\n    {\n        &lt;li&gt;&lt;span class=\"hljs-meta\"&gt;@todo&lt;\/span&gt;.Title&lt;\/li&gt;\n    }\n&lt;\/ul&gt;\n\n&lt;input placeholder=&lt;span class=\"hljs-string\"&gt;\"Something todo\"&lt;\/span&gt; &lt;span class=\"hljs-meta\"&gt;@bind&lt;\/span&gt;(newTodo) \/&gt;\n&lt;button &lt;span class=\"hljs-meta\"&gt;@onclick&lt;\/span&gt;(AddTodo)&gt;Add todo&lt;\/button&gt;\n\n&lt;span class=\"hljs-meta\"&gt;@functions&lt;\/span&gt; {\n    IList&lt;TodoItem&gt; todos = &lt;span class=\"hljs-keyword\"&gt;new&lt;\/span&gt; &lt;span class=\"hljs-built_in\"&gt;List&lt;\/span&gt;&lt;TodoItem&gt;();\n    string newTodo;\n\n    &lt;span class=\"hljs-keyword\"&gt;void&lt;\/span&gt; AddTodo()\n    {\n        &lt;span class=\"hljs-keyword\"&gt;if&lt;\/span&gt; (!&lt;span class=\"hljs-built_in\"&gt;String&lt;\/span&gt;.IsNullOrWhiteSpace(newTodo))\n        {\n            todos.Add(&lt;span class=\"hljs-keyword\"&gt;new&lt;\/span&gt; TodoItem { Title = newTodo });\n            newTodo = &lt;span class=\"hljs-string\"&gt;\"\"&lt;\/span&gt;;\n        }\n    }\n}\n<\/code><\/pre>\n<p>Lastly, what&#8217;s a todo list without check boxes? And while we&#8217;re at it we can make the title text for each todo item editable as well. Add a checkbox input and text input for each todo item and bind their values to the <code>Title<\/code> and <code>IsDone<\/code> properties respectively. To verify that these values are being bound, add a count in the header that shows the number of todo items that are not yet done.<\/p>\n<pre><code class=\"lang-html\">&lt;span class=\"hljs-meta\"&gt;@page&lt;\/span&gt; &lt;span class=\"hljs-string\"&gt;\"\/todo\"&lt;\/span&gt;\n\n&lt;h1&gt;Todo (&lt;span class=\"hljs-meta\"&gt;@todos&lt;\/span&gt;.Where(todo =&gt; !todo.IsDone).Count())&lt;\/h1&gt;\n\n&lt;ul&gt;\n    &lt;span class=\"hljs-meta\"&gt;@foreach&lt;\/span&gt; (&lt;span class=\"hljs-keyword\"&gt;var&lt;\/span&gt; todo &lt;span class=\"hljs-keyword\"&gt;in&lt;\/span&gt; todos)\n    {\n        &lt;li&gt;\n            &lt;input type=&lt;span class=\"hljs-string\"&gt;\"checkbox\"&lt;\/span&gt; &lt;span class=\"hljs-meta\"&gt;@bind&lt;\/span&gt;(todo.IsDone) \/&gt;\n            &lt;input &lt;span class=\"hljs-meta\"&gt;@bind&lt;\/span&gt;(todo.Title) \/&gt;\n        &lt;\/li&gt;\n    }\n&lt;\/ul&gt;\n\n&lt;input placeholder=&lt;span class=\"hljs-string\"&gt;\"Something todo\"&lt;\/span&gt; &lt;span class=\"hljs-meta\"&gt;@bind&lt;\/span&gt;(newTodo) \/&gt;\n&lt;button &lt;span class=\"hljs-meta\"&gt;@onclick&lt;\/span&gt;(AddTodo)&gt;Add todo&lt;\/button&gt;\n\n&lt;span class=\"hljs-meta\"&gt;@functions&lt;\/span&gt; {\n    IList&lt;TodoItem&gt; todos = &lt;span class=\"hljs-keyword\"&gt;new&lt;\/span&gt; &lt;span class=\"hljs-built_in\"&gt;List&lt;\/span&gt;&lt;TodoItem&gt;();\n    string newTodo;\n\n    &lt;span class=\"hljs-keyword\"&gt;void&lt;\/span&gt; AddTodo()\n    {\n        &lt;span class=\"hljs-keyword\"&gt;if&lt;\/span&gt; (!&lt;span class=\"hljs-built_in\"&gt;String&lt;\/span&gt;.IsNullOrWhiteSpace(newTodo))\n        {\n            todos.Add(&lt;span class=\"hljs-keyword\"&gt;new&lt;\/span&gt; TodoItem { Title = newTodo });\n            newTodo = &lt;span class=\"hljs-string\"&gt;\"\"&lt;\/span&gt;;\n        }\n    }\n}\n<\/code><\/pre>\n<p>Build and run the app and try adding some todo items.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/aspnet\/wp-content\/uploads\/sites\/16\/2018\/03\/blazor-todo-done-1.png\" alt=\"Finished Blazor todo list\" \/><\/p>\n<h3 id=\"publishing-and-deployment\">Publishing and deployment<\/h3>\n<p>Now let&#8217;s publish our Blazor app to Azure. Right click on the project and select Publish (if you&#8217;re using the ASP.NET Core hosted template make sure you publish the <em>server<\/em> project). In the &#8220;Pick a publish target&#8221; dialog select &#8220;App Service&#8221; and &#8220;Create New&#8221;.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/aspnet\/wp-content\/uploads\/sites\/16\/2018\/03\/blazor-publish-pick-target-1.png\" alt=\"Pick a publish target\" \/><\/p>\n<p>In the &#8220;Create App Service&#8221; dialog pick a name for the application and select the subscription, resource group, and hosting plan that you want to use. Tap &#8220;Create&#8221; to create the app service and publish the app.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/aspnet\/wp-content\/uploads\/sites\/16\/2018\/03\/blazor-publish-create-appservice-1.png\" alt=\"Create app service\" \/><\/p>\n<p>Your app should now be running in Azure.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/aspnet\/wp-content\/uploads\/sites\/16\/2018\/03\/blazor-azure-2.png\" alt=\"Blazor on Azure\" \/><\/p>\n<p>You can mark that todo item to build your first Blazor app as done! Nice job!<\/p>\n<p>For a more involved Blazor sample app check out the <a href=\"https:\/\/github.com\/aspnet\/samples\/tree\/master\/samples\/aspnetcore\/blazor\">Flight Finder sample<\/a> on GitHub.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/aspnet\/wp-content\/uploads\/sites\/16\/2018\/03\/blazor-flight-finder-2.png\" alt=\"Blazor Flight Finder\" \/><\/p>\n<h3 id=\"summary\">Summary<\/h3>\n<p>This is the first preview release of Blazor. Already you can get started building component-based web apps that run in the browser with .NET. We invite you to try out Blazor today and let us know what you think about the experience so far. You can file issues on <a href=\"https:\/\/github.com\/aspnet\/blazor\/issues\">Github<\/a>, take our in-product survey, and chat with us on <a href=\"https:\/\/gitter.im\/aspnet\/blazor\">Gitter<\/a>. But this is just the beginning! We have many new features and improvements planned for future updates. We hope you enjoy trying out this initial release and we look forward to sharing new improvements with you in the near future.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>For up to date instructions on how to get started with Blazor, please go to https:\/\/blazor.net. Today we released our first public preview of Blazor, a new experimental .NET web framework using C#\/Razor and HTML that runs in the browser with WebAssembly. Blazor enables full stack web development with the stability, consistency, and productivity of [&hellip;]<\/p>\n","protected":false},"author":417,"featured_media":21393,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[197,7509,7251],"tags":[4,7205],"class_list":["post-12735","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-aspnet","category-aspnetcore","category-blazor","tag-net","tag-blazor"],"acf":[],"blog_post_summary":"<p>For up to date instructions on how to get started with Blazor, please go to https:\/\/blazor.net. Today we released our first public preview of Blazor, a new experimental .NET web framework using C#\/Razor and HTML that runs in the browser with WebAssembly. Blazor enables full stack web development with the stability, consistency, and productivity of [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/12735","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/417"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=12735"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/12735\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/21393"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=12735"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=12735"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=12735"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}