06-08-2018, 11:37 PM
Blazor 0.4.0 experimental release now available
<div style="margin: 5px 5% 10px 5%;"><img src="http://www.sickgaming.net/blog/wp-content/uploads/2018/06/blazor-0-4-0-experimental-release-now-available.png" width="1282" height="437" title="" alt="" /></div><div><p>Blazor 0.4.0 is now available! This release includes important bug fixes and several new feature enhancements.</p>
<p>New features in Blazor 0.4.0 (details below):</p>
<ul>
<li>Add event payloads for common event types</li>
<li>Use camelCase for JSON handling</li>
<li>Automatic import of core Blazor namespaces in Razor</li>
<li>Send and receive binary HTTP content using HttpClient</li>
<li>Templates run on IIS Express by default with autobuild enabled</li>
<li>Bind to numeric types</li>
<li>JavaScript interop improvements</li>
</ul>
<p>A full list of the changes in this release can be found in the <a href="https://github.com/aspnet/Blazor/releases/tag/0.4.0">Blazor 0.4.0 release notes</a>.</p>
<h2 id="get-blazor-0-4-0">Get Blazor 0.4.0</h2>
<p>To get setup with Blazor 0.4.0:</p>
<ol>
<li>Install the <a href="https://go.microsoft.com/fwlink/?linkid=873092">.NET Core 2.1 SDK</a> (2.1.300 or later).</li>
<li>Install <a href="https://go.microsoft.com/fwlink/?linkid=873093">Visual Studio 2017</a> (15.7) with the <em>ASP.NET and web development</em> workload selected.
<ul>
<li>Note: The Blazor tooling isn’t currently compatible with the VS2017 preview channel (15.8). This will be addressed in a future Blazor release.</li>
</ul>
</li>
<li>Install the latest <a href="https://go.microsoft.com/fwlink/?linkid=870389">Blazor Language Services extension</a> from the Visual Studio Marketplace.</li>
</ol>
<p>To install the Blazor templates on the command-line:</p>
<pre>
<code>dotnet new -<span class="hljs-selector-tag">i</span> Microsoft<span class="hljs-selector-class">.AspNetCore</span><span class="hljs-selector-class">.Blazor</span><span class="hljs-selector-class">.Templates</span>
</code>
</pre>
<p>You can find getting started instructions, docs, and tutorials for Blazor at <a href="https://blazor.net">https://blazor.net</a>.</p>
<h2 id="upgrade-an-existing-project-to-blazor-0-4-0">Upgrade an existing project to Blazor 0.4.0</h2>
<p>To upgrade an existing Blazor project from 0.3.0 to 0.4.0:</p>
<ul>
<li>Install all of the required bits listed above.</li>
<li>Update your Blazor package and .NET CLI tool references to 0.4.0.</li>
</ul>
<p>Your upgraded Blazor project file should look like this:</p>
<pre>
<code class="lang-xml"><span class="hljs-tag"><<span class="hljs-name">Project</span> <span class="hljs-attr">Sdk</span>=<span class="hljs-string">"Microsoft.NET.Sdk.Web"</span>></span> <span class="hljs-tag"><<span class="hljs-name">PropertyGroup</span>></span> <span class="hljs-tag"><<span class="hljs-name">TargetFramework</span>></span>netstandard2.0<span class="hljs-tag"></<span class="hljs-name">TargetFramework</span>></span> <span class="hljs-tag"><<span class="hljs-name">RunCommand</span>></span>dotnet<span class="hljs-tag"></<span class="hljs-name">RunCommand</span>></span> <span class="hljs-tag"><<span class="hljs-name">RunArguments</span>></span>blazor serve<span class="hljs-tag"></<span class="hljs-name">RunArguments</span>></span> <span class="hljs-tag"><<span class="hljs-name">LangVersion</span>></span>7.3<span class="hljs-tag"></<span class="hljs-name">LangVersion</span>></span> <span class="hljs-tag"></<span class="hljs-name">PropertyGroup</span>></span> <span class="hljs-tag"><<span class="hljs-name">ItemGroup</span>></span> <span class="hljs-tag"><<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Microsoft.AspNetCore.Blazor.Browser"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"0.4.0"</span> /></span> <span class="hljs-tag"><<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Microsoft.AspNetCore.Blazor.Build"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"0.4.0"</span> /></span> <span class="hljs-tag"><<span class="hljs-name">DotNetCliToolReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Microsoft.AspNetCore.Blazor.Cli"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"0.4.0"</span> /></span> <span class="hljs-tag"></<span class="hljs-name">ItemGroup</span>></span> <span class="hljs-tag"></<span class="hljs-name">Project</span>></span>
</code>
</pre>
<h2 id="event-payloads-for-common-event-types">Event payloads for common event types</h2>
<p>This release adds payloads for the following event types:</p>
<table>
<thead>
<tr>
<th>Event arguments</th>
<th>Events</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://blazor.net/api/Microsoft.AspNetCore.Blazor.UIMouseEventArgs.html">UIMouseEventArgs</a></td>
<td>onmouseover, onmouseout, onmousemove, onmousedown, onmouseup, oncontextmenu</td>
</tr>
<tr>
<td><a href="https://blazor.net/api/Microsoft.AspNetCore.Blazor.UIDragEventArgs.html">UIDragEventArgs</a></td>
<td>ondrag, ondragend, ondragenter, ondragleave, ondragover, ondragstart, ondrop</td>
</tr>
<tr>
<td><a href="https://blazor.net/api/Microsoft.AspNetCore.Blazor.UIPointerEventArgs.html">UIPointerEventArgs</a></td>
<td>gotpointercapture, lostpointercapture, pointercancel, pointerdown, pointerenter, pointerleave, pointermove, pointerout, pointerover, pointerup</td>
</tr>
<tr>
<td><a href="https://blazor.net/api/Microsoft.AspNetCore.Blazor.UITouchEventArgs.html">UITouchEventArgs</a></td>
<td>ontouchcancel, ontouchend, ontouchmove, ontouchstart, ontouchenter, ontouchleave</td>
</tr>
<tr>
<td><a href="https://blazor.net/api/Microsoft.AspNetCore.Blazor.UIWheelEventArgs.html">UIWheelEventArgs</a></td>
<td>onwheel, onmousewheel</td>
</tr>
<tr>
<td><a href="https://blazor.net/api/Microsoft.AspNetCore.Blazor.UIPointerEventArgs.html">UIKeyboardEventArgs</a></td>
<td>onkeydown, onkeyup</td>
</tr>
<tr>
<td><a href="https://blazor.net/api/Microsoft.AspNetCore.Blazor.UIKeyboardEventArgs.html">UIKeyboardEventArgs</a></td>
<td>onkeydown, onkeyup, onkeypress</td>
</tr>
<tr>
<td><a href="https://blazor.net/api/Microsoft.AspNetCore.Blazor.UIProgressEventArgs.html">UIProgressEventArgs</a></td>
<td>onloadstart, ontimeout, onabort, onload, onloadend, onprogress, onerror</td>
</tr>
</tbody>
</table>
<p>Thank you to Gutemberg Ribeiro (<a href="https://github.com/galvesribeiro">galvesribeiro</a>) for this contribution! If you haven’t checked out Gutemberg’s handy collection of <a href="https://github.com/BlazorExtensions">Blazor extensions</a> they are definitely worth a look.</p>
<h2 id="use-camelcase-for-json-handling">Use camelCase for JSON handling</h2>
<p>The Blazor JSON helpers and utilities now use camelCase by default. .NET objects serialized to JSON are serialized using camelCase for the member names. On deserialization a case-insensitive match is used. The casing of dictionary keys is preserved.</p>
<h2 id="automatic-import-of-core-for-blazor-namespaces-in-razor">Automatic import of core for Blazor namespaces in Razor</h2>
<p>Blazor now automatically imports the Microsoft.AspNetCore.Blazor and Microsoft.AspNetCore.Blazor.Components namespaces in Razor files, so you don’t need to add <code>@using</code> statements for them. One less thing for you to do!</p>
<h2 id="send-and-receive-binary-http-content-using-httpclient">Send and receive binary HTTP content using HttpClient</h2>
<p>You can now use <code>HttpClient</code> to send and receive binary data from a Blazor app (previously you could only handle text content). Thank you Robin Sue (<a href="https://github.com/Suchiman">Suchiman</a>) for this contribution!</p>
<h2 id="bind-to-numeric-types">Bind to numeric types</h2>
<p>Binding now works with numeric types: <code>long</code>, <code>float</code>, <code>double</code>, <code>decimal</code>. Thanks again to Robin Sue (<a href="https://github.com/Suchiman">Suchiman</a>) for this contribution!</p>
<h2 id="templates-run-on-iis-express-by-default-with-autobuild-enabled">Templates run on IIS Express by default with autobuild enabled</h2>
<p>The Blazor project templates are now setup to run on IIS Express by default, while still preserving autobuild support.</p>
<h2 id="javascript-interop-improvements">JavaScript interop improvements</h2>
<h3 id="call-async-javascript-functions-from-net">Call async JavaScript functions from .NET</h3>
<p>With Blazor 0.4.0 you can now call and await registered JavaScript async functions like you would an async .NET method using the new <code>RegisteredFunction.InvokeAsync</code> method. For example, you can register an async JavaScript function so it can be invoked from your Blazor app like this:</p>
<pre>
<code class="lang-JavaScript">Blazor.registerFunction(<span class="hljs-string">'BlazorLib1.DelayedText'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">text</span>) </span>{ <span class="hljs-comment">// Wait 1 sec and then return the specified text</span> <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =></span> { setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =></span> { resolve(text); }, <span class="hljs-number">1000</span>); });
});
</code>
</pre>
<p>You then invoke this async JavaScript function using <code>InvokeAsync</code> like this:</p>
<pre>
<code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">class</span> ExampleJSInterop
{ <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-built_in">Task</span><<span class="hljs-keyword">string</span>> DelayedText(<span class="hljs-keyword">string</span> <span class="hljs-built_in">text</span>) { <span class="hljs-built_in">return</span> RegisteredFunction.InvokeAsync<<span class="hljs-keyword">string</span>>(<span class="hljs-string">"BlazorLib1.DelayedText"</span>, <span class="hljs-built_in">text</span>); }
}
</code>
</pre>
<p>Now you can await the async JavaScript function like you would any normal C# async method:</p>
<pre>
<code class="lang-csharp"><span class="hljs-keyword">var</span> text = <span class="hljs-keyword">await</span> ExampleJSInterop.DelayedText(<span class="hljs-string">"See ya in 1 sec!"</span>);
</code>
</pre>
<h3 id="call-net-methods-from-javascript">Call .NET methods from JavaScript</h3>
<p>Blazor 0.4.0 makes it easy to call sync and async .NET methods from JavaScript. For example, you might call back into .NET when a JavaScript callback is triggered. While calling into .NET from JavaScript was possible with earlier Blazor releases the pattern was low-level and difficult to use. Blazor 0.4.0 provides simpler pattern with the new <code>Blazor.invokeDotNetMethod</code> and <code>Blazor.invokeDotNetMethodAsync</code> functions.</p>
<p>To invoke a .NET method from JavaScript the target .NET method must meet the following criteria:</p>
<ul>
<li>Static</li>
<li>Non-generic</li>
<li>No overloads</li>
<li>Concrete JSON serializable parameter types</li>
</ul>
<p>For example, let’s say you wanted to invoke the following .NET method when a timeout is triggered:</p>
<pre>
<code class="lang-csharp"><span class="hljs-keyword">namespace</span> <span class="hljs-title">Alerts</span>
{ <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Timeout</span> { <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">TimeoutCallback</span>() </span>{ Console.WriteLine(<span class="hljs-string">'Timeout triggered!'</span>); } }
}
</code>
</pre>
<p>You can call this .NET method from JavaScript using <code>Blazor.invokeDotNetMethod</code> like this:</p>
<pre>
<code class="lang-javascript"><span class="hljs-selector-tag">Blazor</span><span class="hljs-selector-class">.invokeDotNetMethod</span>({ <span class="hljs-attribute">type</span>: { assembly: <span class="hljs-string">'MyTimeoutAssembly'</span>, name: <span class="hljs-string">'Alerts.Timeout'</span> }, <span class="hljs-selector-tag">method</span>: { <span class="hljs-attribute">name</span>: <span class="hljs-string">'TimeoutCallback'</span> }
})
</code>
</pre>
<p>When invoking an async .NET method from JavaScript if the .NET method returns a task, then the JavaScript <code>invokeDotNetMethodAsync</code> function will return a <code>Promise</code> that completes with the task result (so JavaScript/TypeScript can also use await on it).</p>
<h3 id="summary">Summary</h3>
<p>We hope you enjoy this latest preview of Blazor. 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 <a href="https://github.com/aspnet/blazor/issues">file issues on GitHub</a>. You can also 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. After you’ve tried out Blazor for a while please also 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>
<p><img src="http://www.sickgaming.net/blog/wp-content/uploads/2018/06/blazor-0-4-0-experimental-release-now-available.png" alt="Blazor survey" /></p>
<p>Thanks for trying out Blazor!</p>
</div>
<div style="margin: 5px 5% 10px 5%;"><img src="http://www.sickgaming.net/blog/wp-content/uploads/2018/06/blazor-0-4-0-experimental-release-now-available.png" width="1282" height="437" title="" alt="" /></div><div><p>Blazor 0.4.0 is now available! This release includes important bug fixes and several new feature enhancements.</p>
<p>New features in Blazor 0.4.0 (details below):</p>
<ul>
<li>Add event payloads for common event types</li>
<li>Use camelCase for JSON handling</li>
<li>Automatic import of core Blazor namespaces in Razor</li>
<li>Send and receive binary HTTP content using HttpClient</li>
<li>Templates run on IIS Express by default with autobuild enabled</li>
<li>Bind to numeric types</li>
<li>JavaScript interop improvements</li>
</ul>
<p>A full list of the changes in this release can be found in the <a href="https://github.com/aspnet/Blazor/releases/tag/0.4.0">Blazor 0.4.0 release notes</a>.</p>
<h2 id="get-blazor-0-4-0">Get Blazor 0.4.0</h2>
<p>To get setup with Blazor 0.4.0:</p>
<ol>
<li>Install the <a href="https://go.microsoft.com/fwlink/?linkid=873092">.NET Core 2.1 SDK</a> (2.1.300 or later).</li>
<li>Install <a href="https://go.microsoft.com/fwlink/?linkid=873093">Visual Studio 2017</a> (15.7) with the <em>ASP.NET and web development</em> workload selected.
<ul>
<li>Note: The Blazor tooling isn’t currently compatible with the VS2017 preview channel (15.8). This will be addressed in a future Blazor release.</li>
</ul>
</li>
<li>Install the latest <a href="https://go.microsoft.com/fwlink/?linkid=870389">Blazor Language Services extension</a> from the Visual Studio Marketplace.</li>
</ol>
<p>To install the Blazor templates on the command-line:</p>
<pre>
<code>dotnet new -<span class="hljs-selector-tag">i</span> Microsoft<span class="hljs-selector-class">.AspNetCore</span><span class="hljs-selector-class">.Blazor</span><span class="hljs-selector-class">.Templates</span>
</code>
</pre>
<p>You can find getting started instructions, docs, and tutorials for Blazor at <a href="https://blazor.net">https://blazor.net</a>.</p>
<h2 id="upgrade-an-existing-project-to-blazor-0-4-0">Upgrade an existing project to Blazor 0.4.0</h2>
<p>To upgrade an existing Blazor project from 0.3.0 to 0.4.0:</p>
<ul>
<li>Install all of the required bits listed above.</li>
<li>Update your Blazor package and .NET CLI tool references to 0.4.0.</li>
</ul>
<p>Your upgraded Blazor project file should look like this:</p>
<pre>
<code class="lang-xml"><span class="hljs-tag"><<span class="hljs-name">Project</span> <span class="hljs-attr">Sdk</span>=<span class="hljs-string">"Microsoft.NET.Sdk.Web"</span>></span> <span class="hljs-tag"><<span class="hljs-name">PropertyGroup</span>></span> <span class="hljs-tag"><<span class="hljs-name">TargetFramework</span>></span>netstandard2.0<span class="hljs-tag"></<span class="hljs-name">TargetFramework</span>></span> <span class="hljs-tag"><<span class="hljs-name">RunCommand</span>></span>dotnet<span class="hljs-tag"></<span class="hljs-name">RunCommand</span>></span> <span class="hljs-tag"><<span class="hljs-name">RunArguments</span>></span>blazor serve<span class="hljs-tag"></<span class="hljs-name">RunArguments</span>></span> <span class="hljs-tag"><<span class="hljs-name">LangVersion</span>></span>7.3<span class="hljs-tag"></<span class="hljs-name">LangVersion</span>></span> <span class="hljs-tag"></<span class="hljs-name">PropertyGroup</span>></span> <span class="hljs-tag"><<span class="hljs-name">ItemGroup</span>></span> <span class="hljs-tag"><<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Microsoft.AspNetCore.Blazor.Browser"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"0.4.0"</span> /></span> <span class="hljs-tag"><<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Microsoft.AspNetCore.Blazor.Build"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"0.4.0"</span> /></span> <span class="hljs-tag"><<span class="hljs-name">DotNetCliToolReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Microsoft.AspNetCore.Blazor.Cli"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"0.4.0"</span> /></span> <span class="hljs-tag"></<span class="hljs-name">ItemGroup</span>></span> <span class="hljs-tag"></<span class="hljs-name">Project</span>></span>
</code>
</pre>
<h2 id="event-payloads-for-common-event-types">Event payloads for common event types</h2>
<p>This release adds payloads for the following event types:</p>
<table>
<thead>
<tr>
<th>Event arguments</th>
<th>Events</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://blazor.net/api/Microsoft.AspNetCore.Blazor.UIMouseEventArgs.html">UIMouseEventArgs</a></td>
<td>onmouseover, onmouseout, onmousemove, onmousedown, onmouseup, oncontextmenu</td>
</tr>
<tr>
<td><a href="https://blazor.net/api/Microsoft.AspNetCore.Blazor.UIDragEventArgs.html">UIDragEventArgs</a></td>
<td>ondrag, ondragend, ondragenter, ondragleave, ondragover, ondragstart, ondrop</td>
</tr>
<tr>
<td><a href="https://blazor.net/api/Microsoft.AspNetCore.Blazor.UIPointerEventArgs.html">UIPointerEventArgs</a></td>
<td>gotpointercapture, lostpointercapture, pointercancel, pointerdown, pointerenter, pointerleave, pointermove, pointerout, pointerover, pointerup</td>
</tr>
<tr>
<td><a href="https://blazor.net/api/Microsoft.AspNetCore.Blazor.UITouchEventArgs.html">UITouchEventArgs</a></td>
<td>ontouchcancel, ontouchend, ontouchmove, ontouchstart, ontouchenter, ontouchleave</td>
</tr>
<tr>
<td><a href="https://blazor.net/api/Microsoft.AspNetCore.Blazor.UIWheelEventArgs.html">UIWheelEventArgs</a></td>
<td>onwheel, onmousewheel</td>
</tr>
<tr>
<td><a href="https://blazor.net/api/Microsoft.AspNetCore.Blazor.UIPointerEventArgs.html">UIKeyboardEventArgs</a></td>
<td>onkeydown, onkeyup</td>
</tr>
<tr>
<td><a href="https://blazor.net/api/Microsoft.AspNetCore.Blazor.UIKeyboardEventArgs.html">UIKeyboardEventArgs</a></td>
<td>onkeydown, onkeyup, onkeypress</td>
</tr>
<tr>
<td><a href="https://blazor.net/api/Microsoft.AspNetCore.Blazor.UIProgressEventArgs.html">UIProgressEventArgs</a></td>
<td>onloadstart, ontimeout, onabort, onload, onloadend, onprogress, onerror</td>
</tr>
</tbody>
</table>
<p>Thank you to Gutemberg Ribeiro (<a href="https://github.com/galvesribeiro">galvesribeiro</a>) for this contribution! If you haven’t checked out Gutemberg’s handy collection of <a href="https://github.com/BlazorExtensions">Blazor extensions</a> they are definitely worth a look.</p>
<h2 id="use-camelcase-for-json-handling">Use camelCase for JSON handling</h2>
<p>The Blazor JSON helpers and utilities now use camelCase by default. .NET objects serialized to JSON are serialized using camelCase for the member names. On deserialization a case-insensitive match is used. The casing of dictionary keys is preserved.</p>
<h2 id="automatic-import-of-core-for-blazor-namespaces-in-razor">Automatic import of core for Blazor namespaces in Razor</h2>
<p>Blazor now automatically imports the Microsoft.AspNetCore.Blazor and Microsoft.AspNetCore.Blazor.Components namespaces in Razor files, so you don’t need to add <code>@using</code> statements for them. One less thing for you to do!</p>
<h2 id="send-and-receive-binary-http-content-using-httpclient">Send and receive binary HTTP content using HttpClient</h2>
<p>You can now use <code>HttpClient</code> to send and receive binary data from a Blazor app (previously you could only handle text content). Thank you Robin Sue (<a href="https://github.com/Suchiman">Suchiman</a>) for this contribution!</p>
<h2 id="bind-to-numeric-types">Bind to numeric types</h2>
<p>Binding now works with numeric types: <code>long</code>, <code>float</code>, <code>double</code>, <code>decimal</code>. Thanks again to Robin Sue (<a href="https://github.com/Suchiman">Suchiman</a>) for this contribution!</p>
<h2 id="templates-run-on-iis-express-by-default-with-autobuild-enabled">Templates run on IIS Express by default with autobuild enabled</h2>
<p>The Blazor project templates are now setup to run on IIS Express by default, while still preserving autobuild support.</p>
<h2 id="javascript-interop-improvements">JavaScript interop improvements</h2>
<h3 id="call-async-javascript-functions-from-net">Call async JavaScript functions from .NET</h3>
<p>With Blazor 0.4.0 you can now call and await registered JavaScript async functions like you would an async .NET method using the new <code>RegisteredFunction.InvokeAsync</code> method. For example, you can register an async JavaScript function so it can be invoked from your Blazor app like this:</p>
<pre>
<code class="lang-JavaScript">Blazor.registerFunction(<span class="hljs-string">'BlazorLib1.DelayedText'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">text</span>) </span>{ <span class="hljs-comment">// Wait 1 sec and then return the specified text</span> <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =></span> { setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =></span> { resolve(text); }, <span class="hljs-number">1000</span>); });
});
</code>
</pre>
<p>You then invoke this async JavaScript function using <code>InvokeAsync</code> like this:</p>
<pre>
<code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">class</span> ExampleJSInterop
{ <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-built_in">Task</span><<span class="hljs-keyword">string</span>> DelayedText(<span class="hljs-keyword">string</span> <span class="hljs-built_in">text</span>) { <span class="hljs-built_in">return</span> RegisteredFunction.InvokeAsync<<span class="hljs-keyword">string</span>>(<span class="hljs-string">"BlazorLib1.DelayedText"</span>, <span class="hljs-built_in">text</span>); }
}
</code>
</pre>
<p>Now you can await the async JavaScript function like you would any normal C# async method:</p>
<pre>
<code class="lang-csharp"><span class="hljs-keyword">var</span> text = <span class="hljs-keyword">await</span> ExampleJSInterop.DelayedText(<span class="hljs-string">"See ya in 1 sec!"</span>);
</code>
</pre>
<h3 id="call-net-methods-from-javascript">Call .NET methods from JavaScript</h3>
<p>Blazor 0.4.0 makes it easy to call sync and async .NET methods from JavaScript. For example, you might call back into .NET when a JavaScript callback is triggered. While calling into .NET from JavaScript was possible with earlier Blazor releases the pattern was low-level and difficult to use. Blazor 0.4.0 provides simpler pattern with the new <code>Blazor.invokeDotNetMethod</code> and <code>Blazor.invokeDotNetMethodAsync</code> functions.</p>
<p>To invoke a .NET method from JavaScript the target .NET method must meet the following criteria:</p>
<ul>
<li>Static</li>
<li>Non-generic</li>
<li>No overloads</li>
<li>Concrete JSON serializable parameter types</li>
</ul>
<p>For example, let’s say you wanted to invoke the following .NET method when a timeout is triggered:</p>
<pre>
<code class="lang-csharp"><span class="hljs-keyword">namespace</span> <span class="hljs-title">Alerts</span>
{ <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Timeout</span> { <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">TimeoutCallback</span>() </span>{ Console.WriteLine(<span class="hljs-string">'Timeout triggered!'</span>); } }
}
</code>
</pre>
<p>You can call this .NET method from JavaScript using <code>Blazor.invokeDotNetMethod</code> like this:</p>
<pre>
<code class="lang-javascript"><span class="hljs-selector-tag">Blazor</span><span class="hljs-selector-class">.invokeDotNetMethod</span>({ <span class="hljs-attribute">type</span>: { assembly: <span class="hljs-string">'MyTimeoutAssembly'</span>, name: <span class="hljs-string">'Alerts.Timeout'</span> }, <span class="hljs-selector-tag">method</span>: { <span class="hljs-attribute">name</span>: <span class="hljs-string">'TimeoutCallback'</span> }
})
</code>
</pre>
<p>When invoking an async .NET method from JavaScript if the .NET method returns a task, then the JavaScript <code>invokeDotNetMethodAsync</code> function will return a <code>Promise</code> that completes with the task result (so JavaScript/TypeScript can also use await on it).</p>
<h3 id="summary">Summary</h3>
<p>We hope you enjoy this latest preview of Blazor. 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 <a href="https://github.com/aspnet/blazor/issues">file issues on GitHub</a>. You can also 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. After you’ve tried out Blazor for a while please also 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>
<p><img src="http://www.sickgaming.net/blog/wp-content/uploads/2018/06/blazor-0-4-0-experimental-release-now-available.png" alt="Blazor survey" /></p>
<p>Thanks for trying out Blazor!</p>
</div>