Create an account


Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
ASP.NET Core and Blazor updates in .NET Core 3.0 Preview 7

#1
ASP.NET Core and Blazor updates in .NET Core 3.0 Preview 7

<div style="margin: 5px 5% 10px 5%;"><img src="https://www.sickgaming.net/blog/wp-content/uploads/2019/07/asp-net-core-and-blazor-updates-in-net-core-3-0-preview-7.jpg" width="150" height="150" title="" alt="" /></div><div><div class="row justify-content-center">
<div class="col-md-4">
<div><img src="https://www.sickgaming.net/blog/wp-content/uploads/2019/07/asp-net-core-and-blazor-updates-in-net-core-3-0-preview-7.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>July 23rd, 2019</p>
</p></div>
<p><!-- .entry-meta --> </p>
<p><a href="https://devblogs.microsoft.com/dotnet/announcing-net-core-3-0-preview-7/">.NET Core 3.0 Preview 7 is now available</a> and it includes a bunch of new updates to ASP.NET Core and Blazor.</p>
<p>Here’s the list of what’s new in this preview:</p>
<ul>
<li>Latest Visual Studio preview includes .NET Core 3.0 as the default runtime</li>
<li>Top level ASP.NET Core templates in Visual Studio</li>
<li>Simplified web templates</li>
<li>Attribute splatting for components</li>
<li>Data binding support for TypeConverters and generics</li>
<li>Clarified which directive attributes expect HTML vs C#</li>
<li>EventCounters</li>
<li>HTTPS in gRPC templates</li>
<li>gRPC Client Improvements</li>
<li>gRPC Metapackage</li>
<li>CLI tool for managing gRPC code generation</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 7 <a href="https://aka.ms/netcore3download">install the .NET Core 3.0 Preview 7 SDK</a></p>
<p>If you’re on Windows using Visual Studio, <a href="https://visualstudio.com/preview">install the latest preview of Visual Studio 2019</a>.</p>
<p><em>Note: .NET Core 3.0 Preview 7 requires Visual Studio 2019 16.3 Preview 1, which is being released later this week.</em></p>
<p>To install the latest client-side Blazor templates also run the following command:</p>
<pre><code>dotnet new -i Microsoft.AspNetCore.Blazor.Templates::3.0.0-preview7.19365.7
</code></pre>
<p>Installing the Blazor Visual Studio extension is no longer required and it can be uninstalled if you’ve installed a previous version. Installing the Blazor WebAssembly templates from the command-line is now all you need to do to get them to show up in Visual Studio.</p>
<h2>Upgrade an existing project</h2>
<p>To upgrade an existing an ASP.NET Core app to .NET Core 3.0 Preview 7, 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>
<p>To upgrade an existing ASP.NET Core 3.0 Preview 6 project to Preview 7:</p>
<ul>
<li>Update Microsoft.AspNetCore.* package references to 3.0.0-preview7.19365.7.</li>
</ul>
<p>That’s it! You should be ready to go.</p>
<h2>Latest Visual Studio preview includes .NET Core 3.0 as the default runtime</h2>
<p>The latest preview update for Visual Studio (16.3) includes .NET Core 3.0 as the default .NET Core runtime version. This means that if you install the latest preview of Visual Studio then you already have .NET Core 3.0. New project by default will target .NET Core 3.0</p>
<h3>Top level ASP.NET Core templates in Visual Studio</h3>
<p>The ASP.NET Core templates now show up as top level templates in Visual Studio in the “Create a new project” dialog.</p>
<p><img src="https://www.sickgaming.net/blog/wp-content/uploads/2019/07/asp-net-core-and-blazor-updates-in-net-core-3-0-preview-7.png" alt="ASP.NET Core templates"></p>
<p>This means you can now search for the various ASP.NET Core templates and filter by project type (web, service, library, etc.) to find the one you want to use.</p>
<h2>Simplified web templates</h2>
<p>We’ve taken some steps to further simplify the web app templates to reduce the amount of code that is frequently just removed.</p>
<p>Specifically:</p>
<ul>
<li>The cookie consent UI is no longer included in the web app templates by default.</li>
<li>Scripts and related static assets are now referenced as local files instead of using CDNs based on the current environment.</li>
</ul>
<p>We will provide samples and documentation for adding these features to new apps as needed.</p>
<h2>Attribute splatting for components</h2>
<p>Components can now capture and render additional attributes in addition to the component’s declared parameters. Additional attributes can be captured in a dictionary and then “splatted” onto an element as part of the component’s rendering using the new <code>@attributes</code> Razor directive. This feature is especially valuable when defining a component that produces a markup element that supports a variety of customizations. For instance if you were defining a component that produces an <code>&lt;input&gt;</code> element, it would be tedious to define all of the attributes <code>&lt;input&gt;</code> supports like <code>maxlength</code> or <code>placeholder</code> as component parameters.</p>
<h3>Accepting arbitrary parameters</h3>
<p>To define a component that accepts arbitrary attributes define a component parameter using the <code>[Parameter]</code> attribute with the <code>CaptureUnmatchedAttributes</code> property set to true. The type of the parameter must be assignable from <code>Dictionary&lt;string, object&gt;</code>. This means that <code>IEnumerable&lt;KeyValuePair&lt;string, object&gt;&gt;</code> or <code>IReadOnlyDictionary&lt;string, object&gt;</code> are also options.</p>
<pre><code class="razor">@code { [Parameter(CaptureUnmatchedAttributes = true)] Dictionary&lt;string, object&gt; Attributes { get; set; }
}
</code></pre>
<p>The <code>CaptureUnmatchedAttributes</code> property on <code>[Parameter]</code> allows that parameter to match all attributes that do not match any other parameter. A component can only define a single parameter with <code>CaptureUnmatchedAttributes</code>.</p>
<h3>Using @attributes to render arbitrary attributes</h3>
<p>A component can pass arbitrary attributes to another component or markup element using the <code>@attributes</code> directive attribute. The <code>@attributes</code> directive allows you to specify a collection of attributes to pass to a markup element or component. This is valuable because the set of key-value-pairs specified as attributes can come from a .NET collection and do not need to be specified in the source code of the component.</p>
<pre><code class="razor">&lt;input class="form-field" @attributes="Attributes" type="text" /&gt; @code { [Parameter(CaptureUnmatchedAttributes = true)] Dictionary&lt;string, object&gt; Attributes { get; set; }
}
</code></pre>
<p>Using the <code>@attributes</code> directive the contents of the <code>Attribute</code> property get “splatted” onto the input element. If this results in duplicate attributes, then evaluation of attributes occurs from left to right. In the above example if <code>Attributes</code> also contained a value for <code>class</code> it would supersede <code>class="form-field"</code>. If <code>Attributes</code> contained a value for <code>type</code> then that would be superseded by <code>type="text"</code>.</p>
<h2>Data binding support for TypeConverters and generics</h2>
<p>Blazor now supports data binding to types that have a string <code>TypeConverter</code>. Many built-in framework types, like <code>Guid</code> and <code>TimeSpan</code> have a string <code>TypeConverter</code>, or you can define custom types with a string <code>TypeConverter</code> yourself. These types now work seamlessly with data binding:</p>
<pre><code class="razor">&lt;input @bind="guid" /&gt; &lt;p&gt;@guid&lt;/p&gt; @code { Guid guid;
}
</code></pre>
<p>Data binding also now works great with generics. In generic components you can now bind to types specified using generic type parameters.</p>
<pre><code class="razor">@typeparam T &lt;input @bind="value" /&gt; &lt;p&gt;@value&lt;/p&gt; @code { T value;
}
</code></pre>
<h2>Clarified which directive attributes expect HTML vs C</h2>
<p>In Preview 6 we introduced directive attributes as a common syntax for Razor compiler related features like specifying event handlers (<code>@onclick</code>) and data binding (<code>@bind</code>). In this update we’ve cleaned up which of the built-in directive attributes expect C# and HTML. Specifically, event handlers now expect C# values so a leading <code>@</code> character is no longer required when specifying the event handler value:</p>
<pre><code class="razor">@* Before *@
&lt;button @onclick="@OnClick"&gt;Click me&lt;/button&gt; @* After *@
&lt;button @onclick="OnClick"&gt;Click me&lt;/button&gt;
</code></pre>
<h2>EventCounters</h2>
<p>In place of Windows perf counters, .NET Core introduced a new way of emitting metrics via <a href="https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.tracing.eventcounter?view=netcore-3.0">EventCounters</a>. In preview7, we now emit EventCounters ASP.NET Core. You can use the <code>dotnet counters</code> global tool to view the metrics we emit.</p>
<p>Install the latest preview of <code>dotnet counters</code> by running the following command:</p>
<pre><code>dotnet tool install --global dotnet-counters --version 3.0.0-preview7.19365.2
</code></pre>
<h3>Hosting</h3>
<p>The Hosting EventSourceProvider (<code>Microsoft.AspNetCore.Hosting</code>) now emits the following request counters:</p>
<ul>
<li><code>requests-per-second</code></li>
<li><code>total-requests</code></li>
<li><code>current-requests</code></li>
<li><code>failed-requests</code></li>
</ul>
<h3>SignalR</h3>
<p>In addition to hosting, SignalR (<code>Microsoft.AspNetCore.Http.Connections</code>) also emits the following connection counters:</p>
<ul>
<li><code>connections-started</code></li>
<li><code>connections-stopped</code></li>
<li><code>connections-timed-out</code></li>
<li><code>connections-duration</code></li>
</ul>
<p>To view all the counters emitted by ASP.NET Core, you can start dotnet counters and specify the desired provider. The example below shows the output when subscribing to events emitted by the <code>Microsoft.AspNetCore.Hosting</code> and <code>System.Runtime</code> providers.</p>
<pre><code>dotnet counters monitor -p &lt;PID&gt; Microsoft.AspNetCore.Hosting System.Runtime
</code></pre>
<p><img src="https://www.sickgaming.net/blog/wp-content/uploads/2019/07/asp-net-core-and-blazor-updates-in-net-core-3-0-preview-7-1.png" alt="D8GX-5oV4AASKwM"></p>
<h2>New Package ID for SignalR’s JavaScript Client in NPM</h2>
<p>The <a href="https://docs.microsoft.com/en-us/azure/azure-signalr/signalr-overview">Azure SignalR Service</a> made it easier for non-.NET developers to make use of SignalR’s real-time capabilities. A frequent question we would get from potential customers who wanted to enable their applications with SignalR via the Azure SignalR Service was “does it only work with ASP.NET?” The former identity of the ASP.NET Core SignalR – which included the <code>@aspnet</code> organization on NPM, only further confused new SignalR users.</p>
<p>To mitigate this confusion, beginning with 3.0.0-preview7, the SignalR JavaScript client will change from being <code>@aspnet/signalr</code> to <code>@microsoft/signalr</code>. To react to this change, you will need to change your references in package.json files, require statements, and ECMAScript import statements. If you’re interested in providing feedback on this move or to learn the thought process the team went through to make the change, read and/or contribute to <a href="https://github.com/aspnet/AspNetCore/issues/11637">this GitHub issue</a> where the team engaged in an open discussion with the community.</p>
<h2>New Customizable SignalR Hub Method Authorization</h2>
<p>With Preview 7, SignalR now provides a custom resource to authorization handlers when a hub method requires authorization. The resource is an instance of <code>HubInvocationContext</code>. The <code>HubInvocationContext</code> includes the <code>HubCallerContext</code>, the name of the hub method being invoked, and the arguments to the hub method.</p>
<p>Consider the example of a chat room allowing multiple organization sign-in via Azure Active Directory. Anyone with a Microsoft account can sign in to chat, but only members of the owning organization should be able to ban users or view users’ chat histories. Furthermore, we might want to restrict certain functionality from certain users. Using the updated features in Preview 7, this is entirely possible. Note how the <code>DomainRestrictedRequirement</code> serves as a custom <code>IAuthorizationRequirement</code>. Now that the <code>HubInvocationContext</code> resource parameter is being passed in, the internal logic can inspect the context in which the Hub is being called and make decisions on allowing the user to execute individual Hub methods.</p>
<pre><code class="csharp">public class DomainRestrictedRequirement : AuthorizationHandler&lt;DomainRestrictedRequirement, HubInvocationContext&gt;, IAuthorizationRequirement
{ protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, DomainRestrictedRequirement requirement, HubInvocationContext resource) { if (IsUserAllowedToDoThis(resource.HubMethodName, context.User.Identity.Name) &amp;&amp; context.User != null &amp;&amp; context.User.Identity != null &amp;&amp; context.User.Identity.Name.EndsWith("@jabbr.net", StringComparison.OrdinalIgnoreCase)) { context.Succeed(requirement); } return Task.CompletedTask; } private bool IsUserAllowedToDoThis(string hubMethodName, string currentUsername) { return !(currentUsername.Equals("[email protected]", StringComparison.OrdinalIgnoreCase) &amp;&amp; hubMethodName.Equals("banUser", StringComparison.OrdinalIgnoreCase)); }
}
</code></pre>
<p>Now, individual Hub methods can be decorated with the name of the policy the code will need to check at run-time. As clients attempt to call individual Hub methods, the <code>DomainRestrictedRequirement</code> handler will run and control access to the methods. Based on the way the <code>DomainRestrictedRequirement</code> controls access, all logged-in users should be able to call the <code>SendMessage</code> method, only users who’ve logged in with a <code>@jabbr.net</code> email address will be able to view users’ histories, and – with the exception of <code>[email protected]</code> – will be able to ban users from the chat room.</p>
<pre><code class="csharp">[Authorize]
public class ChatHub : Hub
{ public void SendMessage(string message) { } [Authorize("DomainRestricted")] public void BanUser(string username) { } [Authorize("DomainRestricted")] public void ViewUserHistory(string username) { }
}
</code></pre>
<p>Creating the <code>DomainRestricted</code> policy is as simple as wiring it up using the authorization middleware. In <code>Startup.cs</code>, add the new policy, providing the custom <code>DomainRestrictedRequirement</code> requirement as a parameter.</p>
<pre><code class="csharp">services .AddAuthorization(options =&gt; { options.AddPolicy("DomainRestricted", policy =&gt; { policy.Requirements.Add(new DomainRestrictedRequirement()); }); });
</code></pre>
<p>It must be noted that in this example, the <code>DomainRestrictedRequirement</code> class is not only a <code>IAuthorizationRequirement</code> but also it’s own <code>AuthorizationHandler</code> for that requirement. It is fine to split these into separate classes to separate concerns. Yet, in this way, there’s no need to inject the <code>AuthorizationHandler</code> during <code>Startup</code>, since the requirement and the handler are the same thing, there’s no need to inject the handler separately.</p>
<h2>HTTPS in gRPC templates</h2>
<p>The gRPC templates have been now been updated to use HTTPS by default. At development time, we continue the same certificate generated by the <code>dotnet dev-certs</code> tool and during production, you will still need to supply your own certificate.</p>
<h2>gRPC Client Improvements</h2>
<p>The managed gRPC client (<code>Grpc.Net.Client</code>) has been updated to target .NET Standard 2.1 and no longer depends on types present only in .NET Core 3.0. This potentially gives us the ability to run on other platforms in the future.</p>
<h2>gRPC Metapackage</h2>
<p>In 3.0.0-preview7, we’ve introduced a new package <code>Grpc.AspNetCore</code> that transitively references all other runtime and tooling dependencies required for building gRPC projects. Reasoning about a single package version for the metapackage should make it easier for developers to deal with as opposed multiple dependencies that version independently.</p>
<h2>CLI tool for managing gRPC code generation</h2>
<p>The new <code>dotnet-grpc</code> global tool makes it easier to manage protobuf files and their code generation settings. The global tool manages adding and removing protobuf files as well adding the required package references required to build and run gRPC applications.</p>
<p>Install the latest preview of <code>dotnet-grpc</code> by running the following command:</p>
<pre><code>dotnet tool install --global dotnet-grpc --version 0.1.22-pre2
</code></pre>
<p>As an example, you can run following commands to generate a protobuf file and add it to your project for code generation. If you attempt this on a non-web project, we will default to generating a client and add the required package dependencies.</p>
<pre><code class="cmd">dotnet new proto -o .\Protos\mailbox.proto
dotnet grpc add-file .\Protos\mailbox.proto
</code></pre>
<h2>Give feedback</h2>
<p>We hope you enjoy the new features in this preview release of ASP.NET Core and Blazor! Please let us know what you think by filing issues on <a href="https://github.com/aspnet/aspnetcore/issues">GitHub</a>.</p>
<p>Thanks for trying out ASP.NET Core and Blazor!</p>
<div class="authorinfoarea">
<div><img src="https://www.sickgaming.net/blog/wp-content/uploads/2019/07/asp-net-core-and-blazor-updates-in-net-core-3-0-preview-7.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></div>
</p></div>
</div>
Reply



Forum Jump:


Users browsing this thread:
2 Guest(s)

Forum software by © MyBB Theme © iAndrew 2016