Sick Gaming
ASP.NET Core updates in .NET Core 3.0 Preview 3 - Printable Version

+- Sick Gaming (https://www.sickgaming.net)
+-- Forum: Programming (https://www.sickgaming.net/forum-76.html)
+--- Forum: C#, Visual Basic, & .Net Frameworks (https://www.sickgaming.net/forum-79.html)
+--- Thread: ASP.NET Core updates in .NET Core 3.0 Preview 3 (/thread-89153.html)



ASP.NET Core updates in .NET Core 3.0 Preview 3 - xSicKxBot - 03-09-2019

ASP.NET Core updates in .NET Core 3.0 Preview 3

<div style="margin: 5px 5% 10px 5%;"><img src="http://www.sickgaming.net/blog/wp-content/uploads/2019/03/asp-net-core-updates-in-net-core-3-0-preview-3.jpg" width="150" height="150" title="" alt="" /></div><div><div class="row justify-content-center">
<div class="col-md-2">
<div><img src="http://www.sickgaming.net/blog/wp-content/uploads/2019/03/asp-net-core-updates-in-net-core-3-0-preview-3.jpg" width="58" height="58" alt="Daniel Roth" class="avatar avatar-58 wp-user-avatar wp-user-avatar-58 alignnone photo"></p>
<p>Daniel</p>
</div>
</div>
</div>
<div class="entry-meta">
<p>March 6th, 2019</p>
<p> &lt;!–<span class="posted-on">Posted on <a href="https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-core-3-0-preview-3/" rel="bookmark"><time class="entry-date published" datetime="2019-03-06T11:15:26+00:00">March 6, 2019</time><time class="updated" datetime="2019-03-07T11:17:32+00:00"> (March 7, 2019) </time></a></span><span class="byline"> by <span class="author vcard"><a class="url fn n" href="https://devblogs.microsoft.com/aspnet/author/danroth27/">Daniel Roth</a></span></span>–&gt; </div>
<p><!-- .entry-meta --> </p>
<p><a href="https://devblogs.microsoft.com/dotnet/announcing-net-core-3-preview-3/">.NET Core 3.0 Preview 3 is now available</a> and it includes a bunch of new updates to ASP.NET Core.</p>
<p>Here’s the list of what’s new in this preview:</p>
<ul>
<li>Razor Components improvements:
<ul>
<li>Single project template</li>
<li>New .razor extension</li>
<li>Endpoint routing integration</li>
<li>Prerendering</li>
<li>Razor Components in Razor Class Libraries</li>
<li>Improved event handling</li>
<li>Forms &amp; validation</li>
</ul>
</li>
<li>Runtime compilation</li>
<li>Worker Service template</li>
<li>gRPC template</li>
<li>Angular template updated to Angular 7</li>
<li>Authentication for Single Page Applications</li>
<li>SignalR integration with endpoint routing</li>
<li>SignalR Java client support for long polling</li>
</ul>
<p>Please see the <a href="https://aka.ms/netcore3releasenotes">release notes</a> for additional details and known issues.</p>
<h2>Get started</h2>
<p>To get started with ASP.NET Core in .NET Core 3.0 Preview 3 <a href="https://aka.ms/netcore3download">install the .NET Core 3.0 Preview 3 SDK</a></p>
<p>If you’re on Windows using Visual Studio, you’ll also want to <a href="https://visualstudio.com/preview">install the latest preview of Visual Studio 2019</a>.</p>
<ul>
<li>Note: To use use this preview of .NET Core 3.0 with the <em>release</em> channel of Visual Studio 2019, you will need to enable the option to use previews of the .NET Core SDK by going to <em>Tools &gt; Options &gt; Projects and Solutions &gt; .NET Core &gt; Use previews of the .NET Core SDK</em></li>
</ul>
<h2>Upgrade an existing project</h2>
<p>To upgrade an existing an ASP.NET Core app to .NET Core 3.0 Preview 3, follow the <a href="https://docs.microsoft.com/en-us/aspnet/core/migration/22-to-30">migrations steps in the ASP.NET Core docs</a>.</p>
<p>Please also see the full list of <a href="https://github.com/aspnet/announcements/issues?utf8=%E2%9C%93&amp;q=is%3Aissue+label%3A3.0.0+label%3A%22Breaking+change%22">breaking changes</a> in ASP.NET Core 3.0.</p>
<h2>Razor Components improvements</h2>
<p>In the previous preview, we introduced Razor Components as a new way to build interactive client-side web UI with ASP.NET Core. This section covers the various improvements we’ve made to Razor Components in this preview update.</p>
<h3>Single project template</h3>
<p>The Razor Components project template is now a single project instead of two projects in the same solution. The authored Razor Components live directly in the ASP.NET Core app that hosts them. The same ASP.NET Core project can contain Razor Components, Pages, and Views. The Razor Components template also has HTTPS enabled by default like the other ASP.NET Core web app templates.</p>
<h3>New .razor extension</h3>
<p>Razor Components are authored using Razor syntax, but are compiled differently than Razor Pages and Views. To clarify which Razor files should be compiled as Razor Components we’ve introduced a new file extension: .razor. In the Razor Components template all component files now use the .razor extension. Razor Pages and Views still use the .cshtml extension.</p>
<p>Razor Components can still be authored using the .cshtml file extension as long as those files are identified as Razor Component files using the <code>_RazorComponentInclude</code> MSBuild property. For example, the Razor Component template in this release specifies that all .cshtml files under the <em>Components</em> folder should be treated as Razor Components.</p>
<pre><code class="xml">&lt;_RazorComponentInclude&gt;Components\**\*.cshtml&lt;/_RazorComponentInclude&gt;
</code></pre>
<p>Please note that there are a number of limitations with .razor files in this release. Please refer to the <a href="https://github.com/aspnet/AspNetCore/releases/tag/v3.0.0-preview3-19153-02">release notes</a> for the list of known issues and available workarounds.</p>
<h3>Endpoint routing integration</h3>
<p>Razor Components are now integrated into ASP.NET Core’s new Endpoint Routing system. To enable Razor Components support in your application, use <code>MapComponentHub&lt;TComponent&gt;</code> within your routing configuration. For example,</p>
<pre><code class="csharp">app.UseRouting(routes =&gt;
{ routes.MapRazorPages(); routes.MapComponentHub&lt;App&gt;("app");
});
</code></pre>
<p>This configures the application to accept incoming connections for interactive Razor Components, and specifies that the root component <code>App</code> should be rendered within a DOM element matching the selector <code>app</code>.</p>
<h3>Prerendering</h3>
<p>The Razor Components project template now does server-side prerendering by default. This means that when a user navigates to your application, the server will perform an initial render of your Razor Components and deliver the result to their browser as plain static HTML. Then, the browser will reconnect to the server via SignalR and switch the Razor Components into a fully interactive mode. This two-phase delivery is beneficial because:</p>
<ul>
<li>It improves the perceived performance of the site, because the UI can appear sooner, without waiting to make any WebSocket connections or even running any client-side script. This makes a bigger difference for users on slow connections, such as 2G/3G mobiles.</li>
<li>It can make your application easily crawlable by search engines.</li>
</ul>
<p>For users on faster connections, such as intranet users, this feature has less impact because the UI should appear near-instantly regardless.</p>
<p>To set up prerendering, the Razor Components project template no longer has a static HTML file. Instead a single Razor Page, <em>/Pages/Index.cshtml</em>, is used to prerender the app content using the <code>Html.RenderComponentAsync&lt;TComponent&gt;()</code> HTML helper. The page also references the <em>components.server.js</em> script to set up the SignalR connection after the content has been prerendered and downloaded. And because this is a Razor Page, features like the environment tag helper just work.</p>
<p><em>Index.cshtml</em></p>
<pre><code class="html">@page "{*clientPath}"
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt; ...
&lt;/head&gt;
&lt;body&gt; &lt;app&gt;@(await Html.RenderComponentAsync&lt;App&gt;())&lt;/app&gt; <a href="http://_framework/components.server.js">http://_framework/components.server.js</a>
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>Besides the app loading faster, you can see that prerendering is happening by looking at the downloaded HTML source in the browser dev tools. The Razor Components are fully rendered in the HTML.</p>
<h3>Razor Components in Razor Class Libraries</h3>
<p>You can now add Razor Components to Razor Class Libraries and reference them from ASP.NET Core projects using Razor Components.</p>
<p>To create reusable Razor Components in a Razor Class Library:</p>
<ol>
<li>
<p>Create an Razor Components app:</p>
<pre><code>dotnet new razorcomponents -o RazorComponentsApp1
</code></pre>
</li>
<li>
<p>Create a new Razor Class Library</p>
<pre><code>dotnet new razorclasslib -o RazorClassLib1
</code></pre>
</li>
<li>
<p>Add a <em>Component1.razor</em> file to the Razor Class Library</p>
</li>
</ol>
<p><em>Component1.razor</em></p>
<pre><code class="html">&lt;h1&gt;Component1&lt;/h1&gt; &lt;p&gt;@message&lt;/p&gt; @functions { string message = "Hello from a Razor Class Library"!;
}
</code></pre>
<ol>
<li>
<p>Reference the Razor Class Library from an ASP.NET Core app using Razor Components:</p>
<pre><code>dotnet add RazorComponentsApp1 reference RazorClassLib1
</code></pre>
</li>
<li>
<p>In the Razor Components app, import all components from the Razor Class Library using the <code>@addTagHelper</code> directive and then use <code>Component1</code> in the app:</p>
</li>
</ol>
<p><em>Index.razor</em></p>
<pre><code class="html">@page "/"
@addTagHelper *, RazorClassLib1 &lt;h1&gt;Hello, world!&lt;/h1&gt; Welcome to your new app. &lt;Component1 /&gt;
</code></pre>
<p>Note that Razor Class Libraries are not compatible with Blazor apps in this release. Also, Razor Class Libraries do not yet support static assets. To create components in a library that can be shared with Blazor and Razor Components apps you still need to use a <a href="https://docs.microsoft.com/en-us/aspnet/core/razor-components/class-libraries">Blazor Class Library</a>. This is something we expect to address in a future update.</p>
<h3>Improved event handling</h3>
<p>The new <code>EventCallback</code> and <code>EventCallback&lt;&gt;</code> types make defining component callbacks much more straightforward. For example consider the following two components:</p>
<p><em>MyButton.razor</em></p>
<pre><code class="html">&lt;button onclick="@OnClick"&gt;Click here and see what happens!&lt;/button&gt; @functions { [Parameter] EventCallback&lt;UIMouseEventArgs&gt; OnClick { get; set; }
}
</code></pre>
<p><em>UsesMyButton.razor</em></p>
<pre><code class="html"><div>@text</div> &lt;MyButton OnClick="ShowMessage" /&gt; @function { string text; void ShowMessage(UIMouseEventArgs e) { text = "Hello, world!"; }
}
</code></pre>
<p>The <code>OnClick</code> callback is of type <code>EventCallback&lt;UIMouseEventArgs&gt;</code> (instead of <code>Action&lt;UIMouseEventArgs&gt;</code>), which <code>MyButton</code> passes off directly to the <code>onclick</code> event handler. The compiler handles converting the delegate to an <code>EventCallback</code>, and will do some other things to make sure that the rendering process has enough information to render the correct target component. As a result an explicit call to <code>StateHasChanged</code> in the <code>ShowMessage</code> event handler isn’t necessary.</p>
<p>By using the <code>EventCallback&lt;&gt;</code> type <code>OnClick</code> handler can now also be asynchronous without any additional code changes to <code>MyButton</code>:</p>
<p><em>UsesMyButton.razor</em></p>
<pre><code class="html"><div>@text</div> &lt;MyButton OnClick="ShowMessageAsync" /&gt; @function { string text; async Task ShowMessageAsync(UIMouseEventArgs e) { await Task.Yield(); text = "Hello, world!"; }
}
</code></pre>
<p>We recommend using <code>EventCallback</code> and <code>EventCallback&lt;T&gt;</code> when you define component parameters for event handling and binding. Use <code>EventCallback&lt;&gt;</code> where possible because it’s strongly typed and will provide better feedback to users of your component. Use <code>EventCallback</code> when there’s no value you will pass to the callback.</p>
<p>Note that consumers don’t have to write different code when using a component because of <code>EventCallback</code>. The same event handling code should still work, while removing some thorny issues and improving the usability of your components.</p>
<h3>Forms &amp; validation</h3>
<p>This preview release adds built-in components and infrastructure for handling forms and validation.</p>
<p>One of the benefits of using .NET for client-side web development is the ability to share the same implementation logic between the client and the server. Validation logic is a prime example. The new forms &amp; validation support in Razor Components includes support for handling validation using data annotations, or you can plug in your preferred validation system.</p>
<p>For example, the following <code>Person</code> type defines validation logic using data annotations:</p>
<pre><code class="csharp">public class Person
{ [Required(ErrorMessage = "Enter a name")] [StringLength(10, ErrorMessage = "That name is too long")] public string Name { get; set; } [Range(0, 200, ErrorMessage = "Nobody is that old")] public int AgeInYears { get; set; } [Required] [Range(typeof(bool), "true", "true", ErrorMessage = "Must accept terms")] public bool AcceptsTerms { get; set; }
}
</code></pre>
<p>Here’s how you can create a validating form based on this <code>Person</code> model:</p>
<pre><code class="html">&lt;EditForm Model="@person" OnValidSubmit="@HandleValidSubmit"&gt; &lt;DataAnnotationsValidator /&gt; &lt;ValidationSummary /&gt; &lt;p class="name"&gt; Name: &lt;InputText bind-Value="@person.Name" /&gt; &lt;/p&gt; &lt;p class="age"&gt; Age (years): &lt;InputNumber bind-Value="@person.AgeInYears" /&gt; &lt;/p&gt; &lt;p class="accepts-terms"&gt; Accepts terms: &lt;InputCheckbox bind-Value="@person.AcceptsTerms" /&gt; &lt;/p&gt; &lt;button type="submit"&gt;Submit&lt;/button&gt;
&lt;/EditForm&gt; @functions { Person person = new Person(); void HandleValidSubmit() { Console.WriteLine("OnValidSubmit"); }
}
</code></pre>
<p>If you add this form to your app and run it you will get a basic form that automatically validates the field inputs when they are changed and when the form is submitted.</p>
<p><img src="http://www.sickgaming.net/blog/wp-content/uploads/2019/03/asp-net-core-updates-in-net-core-3-0-preview-3.png" alt="Validating form"></p>
<p>There are quite a few things going on here, so let’s break it down piece by piece:</p>
<ul>
<li>The form is defined using the new <code>EditForm</code> component. The <code>EditForm</code> sets up an <code>EditContext</code> as a <a href="https://docs.microsoft.com/en-us/aspnet/core/razor-components/components#cascading-values-and-parameters">cascading value</a> that tracks metadata about the edit process (e.g. what’s been modified, current validation messages, etc.). The <code>EditForm</code> also provides convenient events for valid and invalid submits (<code>OnValidSubmit</code>, <code>OnInvalidSubmit</code>). Or you can use <code>OnSubmit</code> directly if you want to trigger the validation yourself.</li>
<li>The <code>DataAnnotationsValidator</code> component attaches validation support using data annotations to the cascaded <code>EditContext</code>. Enabling support for validation using data annotations currently requires this explicit gesture, but we are considering making this the default behavior that you can then override.</li>
<li>Each of the form fields are defined using a set of built-in input components (<code>InputText</code>, <code>InputNumber</code>, <code>InputCheckbox</code>, <code>InputSelect</code>, etc.). These components provide default behavior for validating on edit and changing their CSS class to reflect the field state. Some of them have useful parsing logic (e.g., <code>InputDate</code> and <code>InputNumber</code> handle unparseable values gracefully by registering them as validation errors). The relevant ones also support nullability of the target field (e.g., int?).</li>
<li>The <code>ValidationMessage</code> component displays validation messages for a specific field.</li>
<li>The <code>ValidationSummary</code> component summarizes all validation messages (similar to the validation summary tag helper).</li>
</ul>
<p>There are some limitations with the built-in input components that we expect to improve in future updates. For example, you can’t currently specify arbitrary attributes on the generate input tags. In the future, we plan to enable components that pass through all extra attributes. For now, you’ll need to build your own component subclasses to handle these cases.</p>
<h2>Runtime compilation</h2>
<p>Support for runtime compilation was removed from the ASP.NET Core shared framework in .NET Core 3.0, but you can now enable it by adding a package to your app.</p>
<p>To enable runtime compilation:</p>
<ol>
<li>
<p>Add a package reference to Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation</p>
<pre><code class="xml">&lt;PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="3.0.0-preview3-19153-02" /&gt;
</code></pre>
</li>
<li>
<p>In <code>Startup.ConfigureServices</code> add a call to <code>AddRazorRuntimeCompilation</code></p>
<pre><code class="csharp">services.AddMvc().AddRazorRuntimeCompilation();
</code></pre>
</li>
</ol>
<h2>Worker Service Template</h2>
<p>In 3.0.0-preview3 we are introducing a new template called ‘Worker Service’. This template is designed as a starting point for running long-running background processes like you might run as a Windows Service or Linux Daemon. Examples of this would be producing/consuming messages from a message queue or monitoring a file to process when it appears. It’s intended to provide the productivity features of ASP.NET Core such as Logging, DI, Configuration, etc without carrying any web dependencies.</p>
<p><img src="http://www.sickgaming.net/blog/wp-content/uploads/2019/03/asp-net-core-updates-in-net-core-3-0-preview-3-1.png" alt="Worker Service"></p>
<p>In the coming days we will publish a few blog posts giving more walkthroughs on using the Worker template to get started. We will have dedicated posts about publishing as a Windows/Systemd service, running on ACI/AKS, as well as running as a WebJob.</p>
<h3>Caveats</h3>
<p>Whilst the intent is for the worker template to not have any dependencies on web technologies by default, in preview3 it still uses the Web SDK and is shown after you select ‘ASP.NET Core WebApplication’ in Visual Studio. This is temporary and will be changed in a future preview. This means that for preview3 you will see many options in VS that may not make sense, such as publishing your worker as a web app to IIS.</p>
<h2>Angular template updated to Angular 7</h2>
<p>The Angular template is now updated to Angular 7. We anticipate updating again to Angular 8 before .NET Core 3.0 ships a stable release.</p>
<h2>Authentication for the Single Page Application templates</h2>
<p>This release introduces support for authentication in our Angular and React templates. In this section we show how to create a new Angular or React template that allows us to authenticate users and access a protected API resource.</p>
<p>Our support for authenticating and authorizing users is powered behind the scenes by <a href="https://identityserver.io/">IdentityServer</a>, with some extensions we built to simplify the configuration experience for the scenarios we are targeting.</p>
<p>Note: In this post we showcase authentication support for Angular but the React template offers equivalent functionality.</p>
<h3>Create a new Angular application</h3>
<p>To create a new Angular application with authentication support we invoke the following command:</p>
<pre><code class="console">dotnet new angular -au Individual
</code></pre>
<p>This command creates a new ASP.NET Core application with a hosted client Angular application. The ASP.NET Core application includes an Identity Server instance already configured so that your Angular application can authenticate users and send HTTP requests against the protected resources in the ASP.NET Core application.</p>
<p>The authentication and authorization support is built as an Angular module that gets imported into your application and offers a suite of components and services to enhance the functionality of the main applicaiton module.</p>
<h3>Run the application</h3>
<p>To run the application simply execute the command below and open the browser in the url displayed on the console:</p>
<pre><code class="console">dotnet run
</code></pre>
<pre><code class="console">Hosting environment: Development
Content root path: C:\angularapp
Now listening on: https://localhost:5001
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
</code></pre>
<p><img src="http://www.sickgaming.net/blog/wp-content/uploads/2019/03/asp-net-core-updates-in-net-core-3-0-preview-3-2.png" alt="SPA index"></p>
<p>When we open the application we see the usual Home, Counter and Fetch data menu options and two new options: Register and Login. If we click on Register we get sent to the default Identity UI where (after running migrations and updating the database) we can register as a new user.</p>
<h3>Register a new user</h3>
<p><img src="http://www.sickgaming.net/blog/wp-content/uploads/2019/03/asp-net-core-updates-in-net-core-3-0-preview-3-3.png" alt="SPA register"></p>
<p>After registering as a new user we get redirected back to the application where we can see that we are successfully authenticated</p>
<p><img src="http://www.sickgaming.net/blog/wp-content/uploads/2019/03/asp-net-core-updates-in-net-core-3-0-preview-3-4.png" alt="SPA logged in"></p>
<h3>Call an authenticated API</h3>
<p>If we click on the Fetch data we can see the weather forecast data table</p>
<p><img src="http://www.sickgaming.net/blog/wp-content/uploads/2019/03/asp-net-core-updates-in-net-core-3-0-preview-3-5.png" alt="SPA fetch data"></p>
<h3>Protect an existing API</h3>
<p>To protect an API on the server we simply need to use the <code>[Authorize]</code> attribute on the controller or action that we want to protect.</p>
<pre><code class="csharp">[Authorize]
[Route("api/[controller]")]
public class SampleDataController : Controller
{
...
}
</code></pre>
<h3>Require authentication for a client route.</h3>
<p>To require the user be authenticated when visiting a page in the Angular application we apply the <code>[AuthorizeGuard]</code> to the route we are configuring.</p>
<pre><code class="typescript">import { ApiAuthorizationModule } from 'src/api-authorization/api-authorization.module';
import { AuthorizeGuard } from 'src/api-authorization/authorize.guard';
import { AuthorizeInterceptor } from 'src/api-authorization/authorize.interceptor'; @NgModule({ declarations: [ AppComponent, NavMenuComponent, HomeComponent, CounterComponent, FetchDataComponent ], imports: [ BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }), HttpClientModule, FormsModule, ApiAuthorizationModule, RouterModule.forRoot([ { path: '', component: HomeComponent, pathMatch: 'full' }, { path: 'counter', component: CounterComponent }, { path: 'fetch-data', component: FetchDataComponent, canActivate: [AuthorizeGuard] }, ]) ], providers: [ { provide: HTTP_INTERCEPTORS, useClass: AuthorizeInterceptor, multi: true } ], bootstrap: [AppComponent]
})
export class AppModule { }
</code></pre>
<h3>Get more details by visiting the docs page</h3>
<p>This is a quick introduction to what our new authentication support for Single Page Applications has to offer. For more details check out the <a href="https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity-api-authorization">docs</a>.</p>
<h2>Endpoint Routing with SignalR Hubs</h2>
<p>In 3.0.0-preview3 we are hooking SignalR hubs into the new <a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing">Endpoint Routing</a> feature recently released. SignalR hub wire-up was previously done explicitly:</p>
<pre><code class="csharp">app.UseSignalR(routes =&gt;
{ routes.MapHub&lt;ChatHub&gt;("hubs/chat");
});
</code></pre>
<p>This meant developers would need to wire up controllers, Razor pages, and hubs in a variety of different places during startup, leading to a series of nearly-identical routing segments:</p>
<pre><code class="csharp">app.UseSignalR(routes =&gt;
{ routes.MapHub&lt;ChatHub&gt;("hubs/chat");
}); app.UseRouting(routes =&gt;
{ routes.MapRazorPages();
});
</code></pre>
<p>Now, SignalR hubs can also be routed via endpoint routing, so you’ve got a one-stop place to route nearly everything in ASP.NET Core.</p>
<pre><code class="csharp">app.UseRouting(routes =&gt;
{ routes.MapRazorPages(); routes.MapHub&lt;ChatHub&gt;("hubs/chat");
});
</code></pre>
<h3>Long Polling for Java SignalR Client</h3>
<p>We added long polling support to the Java client which enables it to establish connections even in environments that do not support WebSockets. This also gives you the ability to specifically select the long polling transport in your client apps.</p>
<h2>gRPC Template</h2>
<p>This preview release introduces a new template for building gRPC services with ASP.NET Core using a new gRPC framework we are building in collaboration with Google.</p>
<p><a href="https://grpc.io/">gRPC</a> is a popular RPC (remote procedure call) framework that offers an opinionated contract-first approach to API development. It uses HTTP/2 for transport, Protocol Buffers as the interface description language, and provides features such as authentication, bidirectional streaming and flow control, and cancellation and timeouts.</p>
<p><img src="http://www.sickgaming.net/blog/wp-content/uploads/2019/03/asp-net-core-updates-in-net-core-3-0-preview-3-6.png" alt="gRPC template"></p>
<p>The templates create two projects: a gRPC service hosted inside ASP.NET Core, and a console application to test it with.</p>
<p><img src="http://www.sickgaming.net/blog/wp-content/uploads/2019/03/asp-net-core-updates-in-net-core-3-0-preview-3-7.png" alt="gRPC solution"></p>
<p>This is the first public preview of gRPC for ASP.NET Core and it doesn’t implement all of gRPC’s features, but we’re working hard to make the best gRPC experience for ASP.NET possible. Please try it out and give us feedback at <a href="https://github.com/grpc/grpc-dotnet/issues">grpc/grpc-dotnet</a> on GitHub.</p>
<p>Stay tuned for future blog posts discussing gRPC for ASP.NET Core in more detail.</p>
<h2>Give feedback</h2>
<p>We hope you enjoy the new features in this preview release of ASP.NET Core! Please let us know what you think by filing issues on <a href="https://github.com/aspnet/aspnetcore/issues">Github</a>.</p>
<div class="authorinfoarea">
<div><img src="http://www.sickgaming.net/blog/wp-content/uploads/2019/03/asp-net-core-updates-in-net-core-3-0-preview-3.jpg" width="96" height="96" alt="Daniel Roth" class="avatar avatar-96 wp-user-avatar wp-user-avatar-96 alignnone photo"></div>
<div>
<h5><a class="no-underline" aria-label="Daniel Roth" target="_blank" href="https://devblogs.microsoft.com/aspnet/author/danroth27/" rel="noopener noreferrer">Daniel Roth</a></h5>
<p>Principal Program Manager,&nbsp;ASP.NET</p>
<p><strong>Follow Daniel</strong>&nbsp;&nbsp;&nbsp;<a class="no-underline stayinformed" aria-label="Daniel Roth Twitter profile" target="_blank" href="https://twitter.com/danroth27" rel="noopener noreferrer"><i class="fa fa-twitter"></i></a><a class="no-underline stayinformed" aria-label="Daniel Roth GitHub profile" target="_blank" href="https://github.com/danroth27" rel="noopener noreferrer"><i class="fa fa-github"></i></a><a class="no-underline stayinformed hvr-pop" aria-label="Daniel Roth RSS Feed" target="_blank" href="https://devblogs.microsoft.com/aspnet/author/danroth27//feed/" rel="noopener noreferrer"></a></p>
<p> &lt;!–</p>
<hr class="authorarea">–&gt; </div>
</p></div>
</div>