ASP.NET Core updates in .NET 5 Release Candidate 1
.NET 5 Release Candidate 1 (RC1) is now available and is ready for evaluation. .NET 5 RC1 is a “go live” release; you are supported using it in production. Here’s what’s new in this release:
- Blazor WebAssembly performance improvements
- Blazor component virtualization
- Blazor WebAssembly prerendering
- Browser compatibility analyzer for Blazor WebAssembly
- Blazor JavaScript isolation and object references
- Blazor file input support
- Custom validation class attributes in Blazor
- Blazor support for
ontoggle
event IAsyncDisposable
support for Blazor components- Model binding
DateTime
as UTC - Control
Startup
class activation - Open API Specification (Swagger) on-by-default in ASP.NET Core API projects
- Better F5 Experience for ASP.NET Core API Projects
- SignalR parallel hub invocations
- Added Messagepack support in SignalR Java client
- Kestrel endpoint-specific options via configuration
See the .NET 5 release notes for additional details and known issues.
Get started
To get started with ASP.NET Core in .NET 5 RC1 install the .NET 5 SDK. .NET RC1 also is included with Visual Studio 2019 16.8 Preview 3.
You need to use Visual Studio 2019 16.8 Preview 3 or newer to use .NET 5 RC1. .NET 5 is also supported with the latest preview of Visual Studio for Mac. To use .NET 5 with Visual Studio Code, install the latest version of the C# extension.
Upgrade an existing project
To upgrade an existing ASP.NET Core app from .NET 5 Preview 8 to .NET 5 RC1:
- Update all Microsoft.AspNetCore.* package references to
5.0.0-rc.1.*
.- If you’re using the new Microsoft.AspNetCore.Components.Web.Extensions package, update to version
5.0.0-preview.9.*
. This package doesn’t have an RC version number yet because we expect to make a few more design changes to the components it contains before it’s ready to ship.
- If you’re using the new Microsoft.AspNetCore.Components.Web.Extensions package, update to version
- Update all Microsoft.Extensions.* package references to
5.0.0-rc.1.*
. - Update System.Net.Http.Json package references to
5.0.0-rc.1.*
.
In Blazor WebAssembly projects, also make the follwowing updates to the project file:
- Update the SDK from “Microsoft.NET.Sdk.Web” to “Microsoft.NET.Sdk.BlazorWebAssembly”
- Remove the
<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
and<UseBlazorWebAssembly>true</UseBlazorWebAssembly>
properties.
That’s it! You should be all ready to go.
See also the full list of breaking changes in ASP.NET Core for .NET 5.
What’s new?
Blazor WebAssembly performance improvements
For .NET 5, we’ve made significant improvements to Blazor WebAssembly runtime performance, with a specific focus on complex UI rendering and JSON serialization. In our performance tests, Blazor WebAssembly in .NET 5 is 2-3x faster for most scenarios.
Runtime code execution in Blazor WebAssembly in .NET 5 is generally faster than Blazor WebAssembly 3.2 due to optimizations in the core framework libraries and improvements to the .NET IL interpreter. Things like string comparisons, dictionary lookups, and JSON handling are generally much faster in .NET 5 on WebAssembly.
As shown in the chart below, JSON handling is almost twice as fast in .NET 5 on WebAssembly:
We also optimized the performance of Blazor component rendering, particularly for UI involving lots of components, like when using high-density grids.
To test the performance of grid component rendering in .NET 5, we used three different grid component implementations, each rendering 200 rows with 20 columns:
- Fast Grid: A minimal, highly optimized implementation of a grid
- Plain Table: A minimal but not optimized implementation of a grid.
- Complex Grid: A maximal, not optimized implementation of a grid, using a wide range of Blazor features at once, deliberately intended to create a bad case for the renderer.
From our tests, grid rendering is 2-3x faster in .NET 5:
You can find the code for these performance tests in the ASP.NET Core GitHub repo.
You can expect ongoing work to improve Blazor WebAssembly performance. Besides optimizing the Blazor WebAssembly runtime and framework, the .NET team is also working with browser implementers to further speed up WebAssembly execution. And for .NET 6, we expect to ship support for ahead-of-time (AoT) compilation to WebAssembly, which should further improve performance.
Blazor component virtualization
You can further improve the perceived performance of component rendering using the new built-in virtualization support. Virtualization is a technique for limiting the UI rendering to just the parts that are currently visible, like when you have a long list or table with many rows and only a small subset is visible at any given time. Blazor in .NET 5 adds a new Virtualize
component that can be used to easily add virtualization to your components.
A typical list or table-based component might use a C# foreach loop to render each item in the list or each row in the table, like this:
@foreach (var employee in employees)
{
<tr>
<td>@employee.FirstName</td>
<td>@employee.LastName</td>
<td>@employee.JobTitle</td>
</tr>
}
If the list grew to include thousands of rows, then rendering it may take a while, resulting in a noticeable UI lag.
Instead, you can replace the foreach loop with the Virtualize
component, which only renders the rows that are currently visible.
<Virtualize Items="employees" Context="employee">
<tr>
<td>@employee.FirstName</td>
<td>@employee.LastName</td>
<td>@employee.JobTitle</td>
</tr>
</Virtualize>
The Virtualize
component calculates how many items to render based on the height of the container and the size of the rendered items.
If you don’t want to load all items into memory, you can specify an ItemsProvider
, like this:
<Virtualize ItemsProvider="LoadEmployees" Context="employee">
<tr>
<td>@employee.FirstName</td>
<td>@employee.LastName</td>
<td>@employee.JobTitle</td>
</tr>
</Virtualize>
An items provider is a delegate method that asynchronously retrieves the requested items on demand. The items provider receives an ItemsProviderRequest
, which specifies the required number of items starting at a specific start index. The items provider then retrieves the requested items from a database or other service and returns them as an ItemsProviderResult<TItem>
along with a count of the total number of items available. The items provider can choose to retrieve the items with each request, or cache them so they are readily available.
async ValueTask<ItemsProviderResult<Employee>> LoadEmployees(ItemsProviderRequest request)
{
var numEmployees = Math.Min(request.Count, totalEmployees - request.StartIndex);
var employees = await EmployeesService.GetEmployeesAsync(request.StartIndex, numEmployees, request.CancellationToken);
return new ItemsProviderResult<Employee>(employees, totalEmployees);
}
Because requesting items from a remote data source might take some time, you also have the option to render a placeholder until the item data is available.
<Virtualize ItemsProvider="LoadEmployees" Context="employee">
<ItemContent>
<tr>
<td>@employee.FirstName</td>
<td>@employee.LastName</td>
<td>@employee.JobTitle</td>
</tr>
</ItemContent>
<Placeholder>
<tr>
<td>Loading...</td>
</tr>
</Placeholder>
</Virtualize>
Blazor WebAssembly prerendering
The component tag helper now supports two additional render modes for prerendering a component from a Blazor WebAssembly app:
- WebAssemblyPrerendered: Prerenders the component into static HTML and includes a marker for a Blazor WebAssembly app to later use to make the component interactive when loaded in the browser.
- WebAssembly: Renders a marker for a Blazor WebAssembly app to use to include an interactive component when loaded in the browser. The component is not prerendered. This option simply makes it easier to render different Blazor WebAssembly components on different
cshtml
pages.
To setup prerendering in an Blazor WebAssembly app:
- Host the Blazor WebAssembly app in an ASP.NET Core app.
- Replace the default static index.html file in the client project with a _Host.cshtml file in the server project.
- Update the server startup logic to fallback to _Host.cshtml instead of index.html (similar to how the Blazor Server template is set up).
-
Update _Host.cshtml to use the component tag helper to prerender the root
App
component:<component type="typeof(App)" render-mode="WebAssemblyPrerendered" />
You can also pass parameters to the component tag helper when using the WebAssembly-based render modes if the parameters are serializable. The parameters must be serializable so that they can be transferred to the client and used to initialize the component in the browser. If prerendering, you’ll also need to be sure to author your components so that they can gracefully execute server-side without access to the browser.
<component type="typeof(Counter)" render-mode="WebAssemblyPrerendered" param-IncrementAmount="10" />
In additional to improving the perceived load time of a Blazor WebAssembly app, you can also use the component tag helper with the new render modes to add multiple components on different pages and views. You don’t need to configure these components as root components in the app or add your own marker tags on the page – the framework handles that for you.
Browser compatibility analyzer for Blazor WebAssembly
Blazor WebAssembly apps in .NET 5 target the full .NET 5 API surface area, but not all .NET 5 APIs are supported on WebAssembly due to browser sandbox constraints. Unsupported APIs throw PlatformNotSupportedException
when running on WebAssembly. .NET 5 now includes a platform compatibility analyzer that will warn you when your app uses APIs that are not supported by your target platforms. For Blazor WebAssembly apps, this means checking that APIs are supported in browsers.
We haven’t added all of the annotations yet to the core libraries in .NET 5 to indicate which APIs are not supported in browsers, but some APIs, mostly Windows specific APIs, are already annotated:
To enable browser compatibilty checks for libraries, add “browser” as a supported platform in your project file (Blazor WebAssembly projects and Razor class library projects do this for you):
<SupportedPlatform Include="browser" />
When authoring a library, you can optionally indicate that a particular API is not supported in browsers by applying the UnsupportedOSPlatformAttribute
:
[UnsupportedOSPlatform("browser")]
private static string GetLoggingDirectory()
{
// ...
}
Blazor JavaScript isolation and object references
Blazor now enables you to isolate your JavaScript as standard JavaScript modules. This has a couple of benefits:
- Imported JavaScript no longer pollutes the global namespace.
- Consumers of your library and components no longer need to manually import the related JavaScript.
For example, the following JavaScript module exports a simple JavaScript function for showing a browser prompt:
export function showPrompt(message) {
return prompt(message, 'Type anything here');
}
You can add this JavaScript module to your .NET library as a static web asset (wwwroot/exampleJsInterop.js) and then import the module into your .NET code using the IJSRuntime
service:
var module = await jsRuntime.InvokeAsync<JSObjectReference>("import", "./_content/MyComponents/exampleJsInterop.js");
The “import” identifier is a special identifier used specifically for importing a JavaScript module. You specify the module using its stable static web asset path: _content/[LIBRARY NAME]/[PATH UNDER WWWROOT].
The IJSRuntime
imports the module as a JSObjectReference
, which represents a reference to a JavaScript object from .NET code. You can then use the JSObjectReference
to invoke exported JavaScript functions from the module:
public async ValueTask<string> Prompt(string message)
{
return await module.InvokeAsync<string>("showPrompt", message);
}
JSObjectReference
greatly simplifies interacting with JavaScript libraries where you want to capture JavaScript object references, and then later invoke their functions from .NET.
Blazor file input support
Blazor now offers an InputFile
component for handling file uploads, or more generally for reading browser file data into your .NET code.
The InputFile
component renders as an HTML input of type “file”. By default, the user can select single files, or if you add the “multiple” attribute then the user can supply multiple files at once. When one or more files is selected by the user, the InputFile
component fires an OnChange
event and passes in an InputFileChangeEventArgs
that provides access to the selected file list and details about each file.
<InputFile OnChange="OnInputFileChange" multiple />
<div class="image-list">
@foreach (var imageDataUrl in imageDataUrls)
{
<img src="@imageDataUrl" />
}
</div>
@code {
IList<string> imageDataUrls = new List<string>();
async Task OnInputFileChange(InputFileChangeEventArgs e)
{
var imageFiles = e.GetMultipleFiles();
var format = "image/png";
foreach (var imageFile in imageFiles)
{
var resizedImageFile = await imageFile.RequestImageFileAsync(format, 100, 100);
var buffer = new byte[resizedImageFile.Size];
await resizedImageFile.OpenReadStream().ReadAsync(buffer);
var imageDataUrl = $"data:{format};base64,{Convert.ToBase64String(buffer)}";
imageDataUrls.Add(imageDataUrl);
}
}
}
To read data from a user-selected file, you call OpenReadStream
on the file and read from the returned stream. In a Blazor WebAssembly app, the data is streamed directly into your .NET code within the browser. In a Blazor Server app, the file data is streamed to your .NET code on the server as you read from the stream. In case you’re using the component to receive an image file, Blazor also provides a RequestImageFileAsync
convenience method for resizing images data within the browser’s JavaScript runtime before they’re streamed into your .NET application.
Custom validation class attributes in Blazor
You can now specify custom validation class names in Blazor. This is useful when integrating with CSS frameworks, like Bootstrap.
To specify custom validation class names, create a class derived from FieldCssClassProvider
and set it on the EditContext
instance.
var editContext = new EditContext(model);
editContext.SetFieldCssClassProvider(new MyFieldClassProvider());
// ...
class MyFieldClassProvider : FieldCssClassProvider
{
public override string GetFieldCssClass(EditContext editContext, in FieldIdentifier fieldIdentifier)
{
var isValid = !editContext.GetValidationMessages(fieldIdentifier).Any();
return isValid ? "legit" : "totally-bogus";
}
}
Blazor support for ontoggle
event
Blazor now has support for the ontoggle
event:
<div>
@if (detailsExpanded)
{
<p>Read the details carefully!</p>
}
<details id="details-toggle" @ontoggle="OnToggle">
<summary>Summary</summary>
<p>Detailed content</p>
</details>
</div>
@code {
bool detailsExpanded;
string message { get; set; }
void OnToggle()
{
detailsExpanded = !detailsExpanded;
}
}
Thank you Vladimir Samoilenko for this contribution!
IAsyncDisposable
support for Blazor components
Blazor components now support the IAsyncDisposable
interface for the asynchronous release of allocated resources.
Model binding DateTime
as UTC
Model binding in ASP.NET Core now supports correctly binding UTC time strings to DateTime
. If the request contains a UTC time string (for example https://example.com/mycontroller/myaction?time=2019-06-14T02%3A30%3A04.0576719Z
), model binding will correctly bind it to a UTC DateTime
without the need for further customization.
Control Startup
class activation
We’ve provided an additional UseStartup
overload that lets you provide a factory method for controlling Startup
class activation. This is useful if you want to pass additional parameters to Startup
that are initialized along with the host.
public class Program
{
public static async Task Main(string[] args)
{
var logger = CreateLogger();
var host = Host.CreateDefaultBuilder()
.ConfigureWebHost(builder =>
{
builder.UseStartup(context => new Startup(logger));
})
.Build();
await host.RunAsync();
}
}
Open API Specification On-by-default
Open API Specification is a industry-adopted convention for describing HTTP APIs and integrating them into complex business processes or with 3rd parties. Open API is widely supported by all cloud providers and many API registries, so developers who emit Open API documents from their Web APIs have a variety of new opportunities in which those APIs can be used. In partnership with the maintainers of the open-source project Swashbuckle.AspNetCore, we’re excited to announce that the ASP.NET Core API template in RC1 comes pre-wired with a NuGet dependency on Swashbuckle, a popular open-source NuGet package that emits Open API documents dynamically. Swashbuckle does this by introspecting over your API Controllers and generating the Open API document at run-time, or at build time using the Swashbuckle CLI.
In .NET 5 RC1, running dotnet new webapi
will result in the Open API output being enabled by default, but if you prefer to have Open API disabled, use dotnet new webapi --no-openapi true
. All .csproj
files that are created for Web API projects will come with the NuGet package reference.
<ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.5.1" />
</ItemGroup>
In addition to the NuGet package reference being in the .csproj
file we’ve added code to both the ConfigureServices
method in Startup.cs
that activates Open API document generation.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "WebApplication1", Version = "v1" });
});
}
The Configure
method is also pre-wired to enlist in the Swashbuckle middleware. This lights up the document generation process and turns on the Swagger UI page by default in development mode. This way you’re confident that the out-of-the-box experience doesn’t accidentally expose your API’s description when you publish to production.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebApplication1 v1"));
}
// ...
}
Azure API Management Import
When ASP.NET Core API projects are wired to output Open API in this way, the Visual Studio 2019 version 16.8 Preview 2.1 publishing experience will automatically offer an additional step in the publishing flow. Developers who use Azure API Management have an opportunity to automatically import their APIs into Azure API Management during the publish flow.
This additional publishing step reduces the number of steps HTTP API developers need to execute to get their APIs published and used with Azure Logic Apps or PowerApps.
Better F5 Experience for Web API Projects
With Open API enabled by default, we were able to significantly improve the F5 experience for Web API developers. With .NET 5 RC1, the Web API template comes pre-configured to load up the Swagger UI page. The Swagger UI page provides both the documentation you’ve added for your API, but enables you to test your APIs with a single click.
SignalR parallel hub invocations
In .NET 5 RC1, ASP.NET Core SignalR is now capable of handling parallel hub invocations. You can change the default behavior and allow clients to invoke more than one hub method at a time.
public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR(options =>
{
options.MaximumParallelInvocationsPerClient = 5;
});
}
Added Messagepack support in SignalR Java client
We’re introducing a new package, com.microsoft.signalr.messagepack
, that adds messagepack support to the SignalR java client. To use the messagepack hub protocol, add .withHubProtocol(new MessagePackHubProtocol())
to the connection builder.
HubConnection hubConnection = HubConnectionBuilder.create("http://localhost:53353/MyHub")
.withHubProtocol(new MessagePackHubProtocol())
.build();
Kestrel endpoint-specific options via configuration
We have added support for configuring Kestrel’s endpoint-specific options via configuration. The endpoint-specific configurations includes the Http protocols used, the TLS protocols used, the certificate selected, and the client certificate mode.
You are able to configure the which certificate is selected based on the specified server name as part of the Server Name Indication (SNI) extension to the TLS protocol as indicated by the client. Kestrel’s configuration also support a wildcard prefix in the host name.
The example belows shows you how to specify endpoint-specific using a configuration file:
{
"Kestrel": {
"Endpoints": {
"EndpointName": {
"Url": "https://*",
"Sni": {
"a.example.org": {
"Protocols": "Http1AndHttp2",
"SslProtocols": [ "Tls11", "Tls12"],
"Certificate": {
"Path": "testCert.pfx",
"Password": "testPassword"
},
"ClientCertificateMode" : "NoCertificate"
},
"*.example.org": {
"Certificate": {
"Path": "testCert2.pfx",
"Password": "testPassword"
}
},
"*": {
// At least one subproperty needs to exist per SNI section or it
// cannot be discovered via IConfiguration
"Protocols": "Http1",
}
}
}
}
}
}
Give feedback
We hope you enjoy this release of ASP.NET Core in .NET 5! We are eager to hear about your experiences with this latest .NET 5 release. Let us know what you think by filing issues on GitHub.
Thanks for trying out ASP.NET Core!
102 comments
Nice update !!
Is the build/compilation performance still going to be improved? We hace four people working on a blazor server side project, and to test each change, as minimum as it can be (i.e: change a letter in a razor component), the rebuild process takes 10 to 15 seconds. We have currently around 70 razor components.
Regards!
10 to 15 seconds for an incremental build does sound excessive. Could you please file a GitHub issue for this so that we can take a look?: https://github.com/dotnet/aspnetcore/issues.
It’s fun to see .NET 5 and Blazor, which are evolving every day.
By the way, I also use a project consisting of 88 Razor files and 10 components.
By simply changing and saving the style in the Razor file, the first 22 seconds should endure approximately 18 seconds of compilation time from the second.
In other words, I feel that the time of the top person is not an unusual case, but a general case.
Is it incremental compilation for each Razor page? If not, I wonder when will it be possible?
For me, Blazor development is a pleasure, but it doesn’t seem like I can see and edit it right now.
Ah. I checked the time again and it took 14 seconds. It seemed to be considerably faster than the previous comment, so I commented again. Background processing specific to Razor in the latest Visual Studio 2019 Preview may apply.
It seems to take about 18 seconds to occur because the Visual Studio 2019 Preview has not yet stabilized. This is because Visual Studio 2019 takes up almost 100% CPU usage.
Anyway, 14 seconds is too long. Please reflect immediately after correction. Or, as soon as you change it, only the page design is reflected. You need such a development environment.
We are very interested in investigating these build performance issues. If it’s possible to share with us a project that reproduces the problem, please open a GitHub issue so that we can investigate: https://github.com/dotnet/aspnetcore/issues.
Ok Daniel,
as per your suggestion I opened e new issue to git hub, following the title:
Net Core 5 RC1 – Blazor ‘System.ArgumentNullException’ in System.Private.CoreLib.dll Value cannot be null #26046
Bye
Piercarlo
This happens to me for any server-side/web-assembly project I develop, regardless of complexity – 8-15 seconds every time.
Hi Matt. To help us investigate what’s going on here, could you please create a GitHub issue with detailed steps on how to reproduce the issue? Please include details like: VS version, .NET SDK version, repro project, whether nullability checks are enabled, etc. https://github.com/dotnet/aspnetcore/issues.
It keeps getting better. Love this
What happened to css isolation and lazy loading assemblies. i thought they would be here!
CSS isolation and lazy loading support for Blazor were both shipped with .NET 5 Preview 8, so they are available in the NET 5 RC1 as well. You can learn all about these features here: https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-5-preview-8/.
After updating I get the following error when trying to debug a ASP.net core hosted Web Assembly app. Both on updated existing apps and newly created apps.
An unhandled exception of type ‘System.ArgumentNullException’ occurred in System.Private.CoreLib.dll
Value cannot be null.
Hi Cody! Can you confirm that you don’t have any processes listening on port 9300 in your machine? If so, ensure that these processes are removed.
This issue will be fixed in RC2 and you should be able to debug even if port 9300 is already used.
Thanks, that fixed the issue!
Same issue here, ever time I run the project I got this error , killing the process .NET Host ( he is the one using the port 9300) solves the problem until I run the project again.
Also been having the same issue, the way I fixed it was to log out and back in again. This proved quite time consuming but now I know to end task in the task manager after every debug session its now mildly annoying. RC2 seems a long wait for a fix for something that’s incredibly time consuming. Makes testing RC1 very difficult.
We do apologize for the inconvenience! If you want to try out an RC2 build you can grab one from https://github.com/dotnet/installer.
How is it possible to use RC2 package without VS update and exciting RC2 Nuget packages?
Since I have installed RC2 SDK changed nothing on my existing projects and getting build error:
If I update the Nuget packages versions in .csproj file, then getting more errors since none of the packages are existing on Nuget…
Thanks.
Hello Guys,
I´m facing with this issue too and it is very frustrating, but I can suggest the following workaround waiting the RC2 release wich the install is not working because will missing the RC2 other packagings.
After each Debug and before to start a new one you need to kill the process to port 9300 that is starting to listening by dotnet with the start of debug itself (so every debug)
To do it quickly I´m using the Developer PowerShell.
To open it you need to go to Tools->CommandLine->DeveloperPowerShell
copy the following script:
and press enter, it will work.
It is a little boring but waiting the next fix it will help.
Bye
Piercarlo
To use the .NET 5 RC2 builds, you’ll also need to add the following NuGet package feed:
Hello daniel,
I installed the RC2 with:
Now is working, but the error is sitll there:
Some suggestion ?
Thank you
Piercarlo, are you seeing this with a newly created project with RC2, or an existing project migrated to RC2?
Actually, since this discussion is getting more involved, it probably would be better to discuss this in a GitHub issue: https://github.com/dotnet/aspnetcore/issues.
Many thanks for your help!! I have installed RC2 and its all working well again. Thank you so much for all the work you are putting into this amazing framework.
Ok Daniel,
as per your suggestion I opened e new issue to git hub, following the title:
Net Core 5 RC1 – Blazor ‘System.ArgumentNullException’ in System.Private.CoreLib.dll Value cannot be null #26046
Bye
Piercarlo
It’s all awesome for Core & Blazor! Daniel, are you able to cast a chink of light on Maui so we get the overall picture? Thank you.
Great features and updates!
Im confused when did deserializing 1kb in 2.6ms become classed as “fast”?
Hi Matt. Blazor WebAssembly runs on a .NET IL interpreter without any JIT so it’s not going to win any speed competitions. We have made some significant speed improvements though in .NET 5, and we expect to improve things further for .NET 6.
Thanks for explanation. Probably worthy of a note somwhere, I was looking for the reference to weather this was 1,000 or 10,000 times.
If Blazor client side ran into a real speed issue long term, is there not a case for Anders H to transpile C# to JavaScript along the lines of the TypeScript project? I never quite understood why MS should not attempt this going back, and coupled with Razor, I don’t think it would be a bad fallback.
No. Javascript is dead slow compared to WebAssermbly. The concept is rather to ahead of time compile into WebAssembly – which is pülanned for the .NET 6.0 timeframe. Until then, basically there is a WebAssembly interpreter that interprets the bytecode. Good enough for “light” stuff – not something you want to run a game engine in.
But JavaScript would be 3 steps back – the end goal for WebAssembly is getting rid of all the performance issues of Javascript (which is text and basically needs runtime parsing). I would rather expect Javascript in the future to run on WebAssembly.
Thomas, how can JS be dead slow when you’re talking about something which is a year behind the blocks and is currently out-performed? And if JS ran on WebAssembly, if Anders H transpiled C# it would just work?
Dan, I couldn’t really get the new Blazor Virtualize component to work without it auto-scrolling until the bottom of the list. I tried setting the ItemSize (and the same size in the ItemContent). I tried using Table markup; then tried just using Div markup, setting it to style with max-height and autoflow:scroll. I spend 1.5 hours but simply could not get it to crazily continue scrolling through the list without any action myself. For example, I would try to scroll a little bit (with 1000 items in the list), then without any action it would just enumerate the list and keep scrolling down itself. I am guessing this is very fussy and you need to have very specific and perfect markup. If your team has this working with a specific style of markup, could you please share?
Hi David. That’s an issue that is getting fixed for the upcoming RC2 release. To work around the issue with RC1 be sure to put the @key directive attribute on your list items.
Good stuff Dan. It is working now, thanks. The javascript isolation works really well too.
I’m having problems with the Virtualize component…. it only seems to work if all the items are exactly the same height.
In the provided example (Table), if a row has a text that wraps to the next line, the whole virtualization breaks. It doesn’t throw an exception but it starts rendering unrelated items, and the scroll goes anywhere.
Is a requirement that the items inside the Virtualize are always exactly the same height? Or is this a bug I can report in github?
Regards
Hi Mr. Charles. Please open a GitHub issue for this and we can discuss options there: https://github.com/dotnet/aspnetcore/issues.
I’m trying to upgrade my existing project (hosted WebAssembly) but it says “This localhost page can’t be found” if I debug the host project. I think my fallback mapping to index.html is not working. My web startup is identical to RC1 template:
. How can I check if WebAssemblyClient has been properly built and put in the wwwroot of the host web project?
I’ve the same issue with trying to upgrade 2 Preview 8 Blazor WASM solutions to RC1. Doesn’t serve any static file (e.g. favicon.ico, *.jpg) as well. Maybe it has something to do with the SSL configuration I use in both projects to get a Qualys SSL Labs A+ score. And maybe I’ve missed this but has IndentityServer4 been upgraded in RC 1 from 3.0.0.0 to 4.0.4+… ?
When I build a new Blazor WASM solution from scratch in VS 2019 Preview it works. So probably I’ve to do some more digging but If anybody has encountered the same problem and has a solution it’d be very much appreciated.
I see the the same thing: Requests not only to static files but Controller actions timing out after 60s. Did you find an open issue on GitHub for this?
Serving static files works for my existing server app, also other Razor pages. If I create a new default Blazor app it works. Just not my existing project, I followed each upgrade step carefully and compared files between new project and my existing Preview 8 project. Any help would be appreciated!
Still haven’t found the problem and something strange is happening: I created a new Blazor WASM project and then copied all of the code from the old Preview 8 solution step by step to the new (RC1) solution to look when I would fail, so I could find the bug.
But now I have copied all code and the app just works. And I don’t know why, it’s pretty frustrating.
I searched open and closed issues at GitHub as well (yesterday) couldn’t find anything.
I’VE GOT IT! 😉
1) Look at the 1st line in [yourapp].Client.csproj
2) When it looks like:
3) Change it to:
Be sure to clean the project (delete .bin & .obj directories), build it and then run it.
I had 2 projects with this problem, and recreated one, step by step, to find the bug, but when I finished that the app just worked so then I compared the code file by file and I noticed this. When I changed this in the other “Preview 8” project, that project worked too!!
Happy programming!
Ahhh, I knew I was overlooking something. Thanks for getting back and letting us know!
You’re welcome! 👍
(It took me two days to find this, should’ve been mentioned somewhere imho, or was it? I can’t find it, but anyways, it works again 😉)
Perhaps it would be a good idea to move the Blazor updates to a separate blog post as it really is very different to the rest of ASP.NET Core.
Hi Rehan. Blazor is part of ASP.NET Core, just like MVC, Razor Pages, and SignalR. For example, the Blazor component model ships in the ASP.NET Core shared framework. We’ve always had a solid server-side rendering story with ASP.NET Core, but for client-side functionality you’ve had to rely on JavaScript. With Blazor, our goal is to enable full stack web development with ASP.NET Core and .NET in a single integrated web framework. To learn more about how you can integrate Blazor into existing MVC and Razor Pages based apps take a look at https://docs.microsoft.com/aspnet/core/blazor/components/integrate-components as well as the new Blazor WebAssembly prerendering support in .NET 5 RC1.