Quantcast
Channel: ASP.NET Blog
Viewing all 7144 articles
Browse latest View live

Library Manager Release in 15.8

$
0
0

Microsoft Library Manager (LibMan) is now available in the general release of Visual Studio 2017 as of v15.8. LibMan first previewed earlier this year, and now, after a much-anticipated wait, LibMan is available in the stable release of Visual Studio 2017 bundled as a default component in the ASP.NET and web development workload.

In the announcement about the preview, we showed off the LibMan manifest (libman.json), providers for filesystem and CDNJS, and the menu options for Restore, Clean and Enable Restore-on-Build. Included as part of the release in v15.8 we’ve also added:
– a new dialog for adding library files
– a new library provider (UnPkg)
– the LibMan CLI (cross-platform DotNet global tool)

What is LibMan?

LibMan is a tool that helps to find common client-side library files and add them to your web project. If you need to pull JavaScript or CSS files into your project from libraries like jQuery or bootstrap, you can use LibMan to search various global providers to find and download the files you need.

Library Manager in Visual Studio

To learn more about LibMan, refer to the official Microsoft Docs: Client-side library acquisition in ASP.NET Core with LibMan.

What’s new?



New dialog for adding library files

We’ve added tooling inside Visual Studio to add library files to a web project. Inside a web project, you can right-click any folder (or the project root) and select Add–>Client-Side Library…
This will launch the Add Client-Side Library dialog, which provides a convenient interface for browsing the libraries and files available in various providers, as well as setting the target location for files in your project.

LibMan Add Files Dialog

New Provider: UnPkg

Along with CDNJS and FileSystem, we’ve built an UnPkg provider. Based on the UnPkg.com website, which sits on top of the npm repo, the UnPkg provider opens access to many more libraries than just those referenced by the CDNJS catalogue.

LibMan CLI available on NuGet

Timed with the release of Visual Studio 2017 v15.8, the LibMan command line interface (CLI) has been developed as a global tool for the DotNet CLI and is now available on NuGet. Look for Microsoft.Web.LibraryManager.Cli

You can install the LibMan CLI with the following command:

> dotnet tool install -g Microsoft.Web.LibraryManager.Cli

The CLI is cross-platform, so you’ll be able to use it anywhere that .NET Core is supported (Windows, Mac, Linux). You can perform a variety of LibMan operations including install, update, and restore, plus local cache management.

LibMan CLI example

To learn more about the LibMan CLI, see the blog post: LibMan CLI Release or refer to the official Microsoft Docs: Use the LibMan command-line interface (CLI) with ASP.NET Core

Related Links

Happy coding!

Justin Clareburt, Senior Program Manager, Visual Studio

Justin Clareburt (justcla) Profile Pic Justin Clareburt is the Web Tools PM on the Visual Studio team. He has over 20 years of Software Engineering experience and brings to the team his expert knowledge of IDEs and a passion for creating the ultimate development experience.

Follow Justin on Twitter @justcla78


How to get started with Azure and .NET

$
0
0

Azure is a big cloud with lots of services, and for even the most experienced user it can be intimidating to know which service will best meet your needs. This blog post is intended to provide a short overview of the most common concepts and services .NET developers need get started and provide resources to help you learn more.

Key Concepts

Azure Account: Your Azure account is the credentials that you sign into Azure with (e.g. what you would use to log into the Azure Portal). If you to not yet have an Azure account, you can create one for free

Azure Subscription: A subscription is the billing plan that Azure resources are created inside. These can either be individual or managed by your company. Your account can be associated with multiple subscriptions. If this is the case, you need to make sure you are selecting the correct one when creating resources. For more info see understanding Azure accounts, subscriptions and billing. Did you know, if you have a Visual Studio Subscription you have monthly Azure credits just waiting to be activated?

Resource Group: Resource groups are one of the most fundamental primitives you’ll deal with in Azure. At a high level, you can think of a resource group like a folder on your computer. Any resources or service you create in Azure will be stored in a resource group (just like when you save a file on your computer you choose where on disk it is saved).

Hosting: When you want code you’ve written to run in Azure, it needs to be hosted in a service that supports executing user provided code.

Managed Services: Azure provides many services where you provide data or information to Azure, and Azure’s implementation takes the appropriate action. A common example of this is Azure Blob Storage, where you provide files, and Azure handles reading, writing, and persisting them for you.

Choosing a Hosting Option

Hosting in Azure can be divided into three main categories:

  • Infrastructure-as-a-Service (IaaS): With IaaS, you provision the VMs that you need, along with associated network and storage components. Then you deploy whatever software and applications you want onto those VMs. This model is the closest to a traditional on-premises environment, except that Microsoft manages the infrastructure. You still manage the individual VMs (e.g. deciding what operating system you want, install custom software, when to apply security updates, etc.).
  • Platform-as-a-Service (PaaS): Provides a managed hosting environment, where you can deploy your application without needing to manage VMs or networking resources. For example, instead of creating individual VMs, you specify an instance count, and the service will provision, configure, and manage the necessary resources. Azure App Service is an example of a PaaS service.
  • Functions-as-a-Service (FaaS): Often called “Serverless” computing, FaaS goes even further than PaaS in removing the need to worry about the hosting environment. Instead of creating compute instances and deploying code to those instances, you simply deploy your code, and the service automatically runs it. You don’t need to administer the compute resources, the platform seamlessly scales your code up or down to whatever level necessary to handle the traffic and you pay only when your code is running. Azure Functions are a FaaS service.

In general, the further towards Serverless you can host your application, the more benefits you’ll see from running in the cloud. Below is a short cheat sheet for getting started with three common hosting choices in Azure and when to choose them (for a more complete list see Overview of Azure compute options)

  • Azure App Service: If you are looking to host a web application or service we recommend you look at App Service first. To get started with App Service, see the ASP.NET Quickstart (instructions other than project type are applicable to ASP.NET, WCF, and ASP.NET Core apps).
  • Azure Functions: Azure Functions are great for event driven workflows. Examples include responding to Webhooks, processing items placed into Queues or Blob Storage, Timers, etc. To get started with Azure Functions see the Create your first function quickstart.
  • Azure Virtual Machines: If App Service doesn’t meet your needs for hosting an existing application (e.g. you need to install customer software on the machine, or access to operating system APIs that are not available in App Service’s environment) Virtual Machines will be the easiest place to start. To get started with Virtual Machines see our Deploy an ASP.NET app to an Azure virtual machine tutorial (applies equally to WCF).

If you need more help deciding on which hosting/compute option is best for you, see the Decision tree for Azure compute services.

Choosing a Data Storage Service

Azure offers many services for storing your data depending on your needs. The most common data services for .NET developers are:

  • Azure SQL Database: If you are looking to migrate an application that is already using SQL Server to the cloud, then Azure SQL Database is a natural place to start. To get started see the Build an ASP.NET app in Azure with SQL Database tutorial.
  • Azure Cosmos DB: Is a modern database designed for the cloud. If you are looking to start a new application that doesn’t yet have a specific database dependency, you should look at Azure Cosmos DB as a starting point. Cosmos DB is a good choice for new web, mobile, gaming, and IoT applications where automatic scale, predictable performance, fast response times, and the ability to query over schema-free data is important (common use cases for Azure Cosmos DB). To get started See build a .NET web app with Azure Cosmos DB quickstart
  • Blob Storage: Is optimized for storing and retrieving large binary objects (images, files, video and audio streams, large application data objects and documents, etc.). Object stores enable the management of extremely large amounts of unstructured data. To get started see the upload, download, and list blobs using .NET quickstart.

For more help deciding on which data storage service will best meet your needs, see choose the right data store.

Diagnosing Problems in the Cloud

Once you deploy your application to Azure, you’ll likely run into cases where it worked locally but doesn’t in Azure. Below are two good places to start:

  • Remote debug from Visual Studio: Most of the Azure compute services (including all three covered above) support remote debugging with Visual Studio and acquiring logs. To explore Visual Studio’s capabilities for your application type, open the Cloud Explorer tool window (type “Cloud Explorer” into Visual Studio’s Quicklaunch toolbar (in the top right corner), and locate your application in the tree. For details see diagnosing errors in your cloud apps.
  • Enable Application Insights: Application Insights is a complete application performance monitoring (APM) solution that captures diagnostic data, telemetry, and performance data from the application automatically. To get started collecting diagnostic data for your app, see find and diagnose run-time exceptions with Azure Application Insights.

Conclusion and Resources

The above is a short list of what to look at when you’re first starting with Azure. If you are interested in learning more here are a few resources:

As always, we want to see you successful, so if you run into any issues, let me know in the comment section below, or via Twitter and I’ll do my best to get your question answered.

ASP.NET Core 2.2.0-preview2 now available

$
0
0

Today we’re very happy to announce that the second preview of the next minor release of ASP.NET Core and .NET Core is now available for you to try out. We’ve been working hard on this release over the past months, along with many folks from the community, and it’s now ready for a wider audience to try it out and provide the feedback that will continue to shape the release.

How do I get it?

You can download the new .NET Core SDK for 2.2.0-preview2 (which includes ASP.NET 2.2.0-preview2) from https://www.microsoft.com/net/download/dotnet-core/2.2

Visual Studio requirements

Customers using Visual Studio should also install and use the Preview channel of Visual Studio 2017 (15.9 Preview 2) in addition to the SDK when working with .NET Core 2.2 and ASP.NET Core 2.2 projects. Please note that the Visual Studio preview channel can be installed side-by-side with existing an Visual Studio installation without disrupting your current development environment.

Azure App Service Requirements

If you are hosting your application on Azure App Service, you can follow these instructions to install the required site extension for hosting your 2.2.0-preview2 applications.

Impact to machines

Please note that is a preview release and there are likely to be known issues and as-yet-to-be discovered bugs. While the .NET Core SDK and runtime installs are side-by-side, your default SDK will become the latest one. If you run into issues working on existing projects using earlier versions of .NET Core after installing the preview SDK, you can force specific projects to use an earlier installed version of the SDK using a global.json file as documented here. Please log an issue if you run into such cases as SDK releases are intended to be backwards compatible.

What’s new in Preview 2

For a full list of changes, bug fixes, and known issues you can read the release notes.

SignalR Java Client updated to support Azure SignalR Service

The SignalR Java Client, first introduced in preview 1, now has support for the Azure SignalR Service. You can now develop Java and Android applications that connect to a SignalR server using the Azure SignalR Service. To get this new functionality, just update your Maven or Gradle file to reference version 0.1.0-preview2-35174 of the SignalR Client package.

Problem Details support

In 2.1.0, MVC introduced ProblemDetails, based on the RFC 7807 specification for carrying detils of an error with a HTTP Response. In preview2, we’re standardizing around using ProblemDetails for client error codes in controllers attributed with ApiControllerAttribute. An IActionResult returning a client error status code (4xx) will now return a ProblemDetails body. The result additionally includes a correlation ID that can be used to correlate the error using request logs. Lastly, ProducesResponseType for client errors, default to using ProblemDetails as the response type. This will be documented in Open API / Swagger output generated using NSwag or Swashbuckle.AspNetCore. Documentation for configuring the ProblemDetails response can be found here – https://aka.ms/AA2k4zg.

ASP.NET Core Module Improvements

We’ve introduced a new module (aspNetCoreModuleV2) for hosting ASP.NET Core application in IIS in 2.2.0-preview1. This new module adds the ability to host your .NET Core application within the IIS worker process and avoids the additional cost of reverse-proxying your requests over to a separate dotnet process.

ASP.NET Core 2.2.0-preview2 or newer projects default to the new in-process hosting model. If you are upgrading from preview1, you will need to add a new project property to your .csproj file.

<PropertyGroup>
  <TargetFramework>netcoreapp2.2</TargetFramework>
  <AspNetCoreHostingModel>inprocess</AspNetCoreHostingModel>
</PropertyGroup>

Visual Studio 15.9-preview2 adds the ability to switch your hosting model as part of your development-time experience.

Hosting in IIS

To deploy applications targeting ASP.NET Core 2.2.0-preview2 on servers with IIS, you require a new version of the 2.2 Runtime & Hosting Bundle on the target server. The bundle is available at https://www.microsoft.com/net/download/dotnet-core/2.2.

Caveats

There are a couple of caveats with the new in-process hosting model: – You are limited to one application per IIS Application Pool. – No support for .NET Framework. The new module is only capable of hosting .NET Core in the IIS process.

If you have a ASP.NET Core 2.2 app that’s using the in process hosting model, you can turn it off by setting the <AspNetCoreHostingModel> element to outofprocess in your .csproj file.

Template Updates

We’ve cleaned up the Bootstrap 4 project template work that we started in Preview 1. We’ve also added support to the default Identity UI for using both Bootstrap 3 & 4. For compatibility with existing apps the default Bootstrap version for the default UI is now Bootstrap 3, but you can select which version of Boostrap you want to use when calling AddDefaultUI.

HealthCheck Improvements

There are a few small, but important, changes to health checks in preview2.

You can now call AddCheck<T> where T is a type of IHealthCheck:

services.AddHealthChecks()
        .AddCheck<MyHealthCheck>();

This will register your health check as a transient service, meaning that each time the health check service is called a new instance will be created. We allow you to register IHealthCheck implementations with any service lifetime when you register them manually:

services.AddHealthChecks();
services.AddSingleton<IHealthCheck, MySingletonCheck>();

A scope is created for each invocation of the HealthChecksService. As with all DI lifetimes you should be careful when creating singleton objects that depend on services with other lifetimes as described here.

You can filter which checks you want to execute when using the middleware or the HealthCheckService directly. In this example we are executing all our health checks when a request is made on the ready path, but just returning a 200 OK when the live path is hit:

// The readiness check uses all of the registered health checks (default)
app.UseHealthChecks("/health/ready");

// The liveness check uses an 'identity' health check that always returns healthy
app.UseHealthChecks("/health/live", new HealthCheckOptions()
{
    // Exclude all checks, just return a 200.
    Predicate = (check) => false,
});

You might do this if, for example, you are using Kubernetes and want to run a comprehensive set of checks before traffic is sent to your application but otherwise are OK as long as you are reachable and still running.

What’s still to come?

We are investaging adding a tags mechanism to checks, so that they can be set and filtered on. We also want to provide an Entity Framework specific check that will check whatever database has been configured to be used with your DbContext.

Migrating an ASP.NET Core 2.1 project to 2.2

To migrate an ASP.NET Core project from 2.1.x to 2.2.0-preview2, open the project’s .csproj file and change the value of the the element to netcoreapp2.2. You do not need to do this if you’re targeting .NET Framework 4.x.

Giving Feedback

The main purpose of providing previews is to solicit feedback so we can refine and improve the product in time for the final release. Please help provide us feedback by logging issues in the appropriate repository at https://github.com/aspnet or https://github.com/dotnet. We look forward to receiving your feedback!

The future of ASP.NET SignalR

$
0
0

In ASP.NET Core 2.1, we brought SignalR into the ASP.NET Core family. Many of our users have asked what this means for the previous version of SignalR: ASP.NET SignalR.

As a reminder, ASP.NET SignalR is represented by the NuGet package Microsoft.AspNet.SignalR and runs on applications using .NET Framework and System.Web. ASP.NET Core SignalR is part of the ASP.NET Core platform which runs on both .NET Core and .NET Framework and uses the NuGet package Microsoft.AspNetCore.App.

Support for the Azure SignalR Service

This year, we’re planning to release version 2.4.0 of ASP.NET SignalR. This version will contain bug fixes as always, but will also include one major new feature: Support for the Azure SignalR Service.

The Azure SignalR Service is a managed service that handles scaling for SignalR-based applications. In May, we released this service into public preview with support for ASP.NET Core SignalR, and we’re pleased to announce that support for ASP.NET SignalR is also coming to the Azure SignalR Service. We expect the first preview of this to be available in Fall 2018, along with a preview release of SignalR 2.4.0. In order to migrate your application to use the Azure SignalR service, you will need to update both the client and the server to ASP.NET SignalR 2.4.0.

We’re still in the early stages of work on this feature, so we don’t have specific examples yet. However, this support will be similar to how ASP.NET Core SignalR supports the Azure SignalR Service. With minimal modifications to your server application, you will be able to enable support for the service. Once you’re using the Azure SignalR Service, your server application no longer has to manage all of the individual connections. Moving to the service also means you no longer require a scale-out system (such as Redis, Service Bus or SQL Server), as the service handles scaling for you.

Also, as with ASP.NET Core SignalR, as long as your clients are using the latest version of the SignalR Client (2.4.0), they will be able to connect via the service without modification.

If you’re interested in working with the Azure SignalR Service to migrate to this service and provide feedback, please contact the team by email at asrs@microsoft.com.

Client supported frameworks

Another thing we are planning to do in 2.4.0 is simplify the supported frameworks for the SignalR .NET Client. Our plan for 2.4.0 is to move the client to support:

  • .NET Standard 2.0 (which includes Xamarin, and the Universal Windows Platform)
  • .NET Framework 4.5 and higher

This does mean that version 2.4.0 of the .NET client will no longer support Windows 8, Windows Phone, or Silverlight applications. We want some feedback on this though, so if you still have applications using the SignalR client that run on these platforms, let us know by commenting on the GitHub issue tracking this part of the work.

Handling the backlog of issues

While we didn’t forget about ASP.NET SignalR, we did let things get a little messy over there while we were building ASP.NET Core. If you look at the issue tracker you’ll see we have (at the time of publishing) over 500 open issues. We didn’t do a great job keeping on top of the backlog there. In order to get a handle on things, we’re going to have to declare a kind of “Issue Bankruptcy” to get back on top of the work.

So, in order to get back on top of the backlog, we’re going to close all issues that were opened prior to January 1st, 2018. This does not mean we’re not interested in fixing them, it just means they’ve gotten stale and we aren’t able to follow up on them. If one of these issues is affecting you, please feel free to open a new issue with the details and we will be happy to review it. There are a lot of issues in the tracker that are simply no longer relevant, or may have been addressed in a previous release.

Our priorities moving forward

With the release of ASP.NET Core SignalR, it’s necessary to talk about how the team is going to be prioritizing our work on the two variants of SignalR. Our plan moving forward is to shift our focus towards ASP.NET Core SignalR. This means that after the 2.4.0 release, we won’t be investing resources in new features for ASP.NET SignalR. However, this does not mean ASP.NET SignalR will be left unsupported. We will continue to respond to bug reports and fix critical or security-related issues. You should continue to feel confident using ASP.NET SignalR in your applications. Microsoft will also continue to provide product support services for ASP.NET SignalR.

ASP.NET Core in Visual Studio for Mac – Help us build the best experience

$
0
0

We are working to improve the experience for ASP.NET Core developers in Visual Studio for Mac. If you are working on ASP.NET Core apps in Visual Studio for Mac, we would love to hear you feedback. Your feedback is important so that we can help shape the future of ASP.NET Core in Visual Studio for Mac.

At the end of the survey, you can leave your name and email address (optional), so that a member of the team can reach out to you to get more details. The survey should take less than 5 minutes to be completed.

Take the survey now

Thanks,
Sayed Ibrahim Hashimi
@SayedIHashimi

Blazor 0.6.0 experimental release now available

$
0
0

Blazor 0.6.0 is now available! This release includes new features for authoring templated components and enables using server-side Blazor with the Azure SignalR Service. We're also excited to announce our plans to ship the server-side Blazor model as Razor Components in .NET Core 3.0!

Here's what's new in the Blazor 0.6.0 release:

  • Templated components
    • Define components with one or more template parameters
    • Specify template arguments using child elements
    • Generic typed components with type inference
    • Razor templates
  • Refactored server-side Blazor startup code to support the Azure SignalR Service

A full list of the changes in this release can be found in the Blazor 0.6.0 release notes.

Get Blazor 0.6.0

Install the following:

  1. .NET Core 2.1 SDK (2.1.402 or later).
  2. Visual Studio 2017 (15.8 or later) with the ASP.NET and web development workload selected.
  3. The latest Blazor Language Services extension from the Visual Studio Marketplace.
  4. The Blazor templates on the command-line:

    dotnet new -i Microsoft.AspNetCore.Blazor.Templates
    

You can find getting started instructions, docs, and tutorials for Blazor at https://blazor.net.

Upgrade an existing project to Blazor 0.6.0

To upgrade a Blazor 0.5.x project to 0.6.0:

  • Install the prerequisites listed above.
  • Update the Blazor package and .NET CLI tool references to 0.6.0. The upgraded Blazor project file should look like this:

    <Project Sdk="Microsoft.NET.Sdk.Web">
    
    <PropertyGroup>
        <TargetFramework>netstandard2.0</TargetFramework>
        <RunCommand>dotnet</RunCommand>
        <RunArguments>blazor serve</RunArguments>
        <LangVersion>7.3</LangVersion>
    </PropertyGroup>
    
    <ItemGroup>
        <PackageReference Include="Microsoft.AspNetCore.Blazor.Browser" Version="0.6.0" />
        <PackageReference Include="Microsoft.AspNetCore.Blazor.Build" Version="0.6.0" />
        <DotNetCliToolReference Include="Microsoft.AspNetCore.Blazor.Cli" Version="0.6.0" />
    </ItemGroup>
    
    </Project>
    

That's it! You're now ready to try out the latest Blazor features.

Templated components

Blazor 0.6.0 adds support for templated components. Templated components are components that accept one or more UI templates as parameters, which can then be used as part of the component's rendering logic. Templated components allow you to author higher-level components that are more reusable than what was possible before. For example, a list view component could allow the user to specify a template for rending items in the list, or a grid component could allow the user to specify templates for the grid header and for each row.

Template parameters

A templated component is defined by specifying one or more component parameters of type RenderFragment or RenderFragment<T>. A render fragment represents a segment of UI that is rendered by the component. A render fragment optionally take a parameter that can be specified when the render fragment is invoked.

TemplatedTable.cshtml

@typeparam TItem

<table>
    <thead>
        <tr>@TableHeader</tr>
    </thead>
    <tbody>
    @foreach (var item in Items)
    {
        @RowTemplate(item)
    }
    </tbody>
    <tfoot>
        <tr>@TableFooter</tr>
    </tfoot>
</table>

@functions {
    [Parameter] RenderFragment TableHeader { get; set; }
    [Parameter] RenderFragment<TItem> RowTemplate { get; set; }
    [Parameter] RenderFragment TableFooter { get; set; }
    [Parameter] IReadOnlyList<TItem> Items { get; set; }
}

When using a templated component, the template parameters can be specified using child elements that match the names of the parameters.

<TemplatedTable Items="@pets">
    <TableHeader>
        <th>ID</th>
        <th>Name</th>
        <th>Species</th>
    </TableHeader>
    <RowTemplate>
        <td>@context.PetId</td>
        <td>@context.Name</td>
        <td>@context.Species</td>
    </RowTemplate>
</TemplatedTable>

Template context parameters

Component arguments of type RenderFragment<T> passed as elements have an implicit parameter named context, but you can change the parameter name using the Context attribute on the child element.

<TemplatedTable Items="@pets">
    <TableHeader>
        <th>ID</th>
        <th>Name</th>
        <th>Species</th>
    </TableHeader>
    <RowTemplate Context="pet">
        <td>@pet.PetId</td>
        <td>@pet.Name</td>
        <td>@pet.Species</td>
    </RowTemplate>
</TemplatedTable>

Alternatively, you can specify the Context attribute on the component element (e.g., <TemplatedTable Context="pet">). The specified Context attribute applies to all specified template parameters. This can be useful when you want to specify the content parameter name for implicit child content (without any wrapping child element).

Generic-typed components

Templated components are often generically typed. For example, a generic ListView component could be used to render IEnumerable<T> values. To define a generic component use the new @typeparam directive to specify type parameters.

GenericComponent.cshtml

@typeparam TItem

@foreach (var item in Items)
{
    @ItemTemplate(item)
}

@functions {
    [Parameter] RenderFragment<TItem> ItemTemplate { get; set; }
    [Parameter] IReadOnlyList<TItem> Items { get; set; }
}

When using generic-typed components the type parameter will be inferred if possible. Otherwise, it must be explicitly specified using an attribute that matches the name of the type parameter:

<GenericComponent Items="@pets" TItem="Pet">
    ...
</GenericComponent>

Razor templates

Render fragments can be defined using Razor template syntax. Razor templates are a way to define a UI snippet. They look like the following:

@<tag>...<tag>

You can now use Razor templates to define RenderFragment and RenderFragment<T> values like this:

@{ 
    RenderFragment template = @<p>The time is @DateTime.Now.</p>;
    RenderFragment<Pet> petTemplate = (pet) => @<p>Your pet's name is @pet.Name.</p>
}

Render fragments defined using Razor templates can be passed as arguments to templated components or rendered directly. For example, you can render the previous templates directly like this:

@template

@petTemplate(new Pet { Name = "Fido" })

Use server-side Blazor with the Azure SignalR Service

In the previous Blazor release we added support for running Blazor on the server where UI interactions and DOM updates are handled over a SignalR connection. In this release we refactored the server-side Blazor support to enable using server-side Blazor with the Azure SignalR Service. The Azure SignalR Service handles connection scale out for SignalR based apps, scaling up to handle thousands of persistent connections so that you don't have to.

To use the Azure SignalR Service with a server-side Blazor application:

  1. Create a new server-side Blazor app.

    dotnet new blazorserverside -o BlazorServerSideApp1
    
  2. Add the Azure SignalR Server SDK to the server project.

    dotnet add BlazorServerSideApp1/BlazorServerSideApp1.Server package Microsoft.Azure.SignalR
    
  3. Create an Azure SignalR Service resource for your app and copy the primary connection string.

  4. Add a UserSecretsId property to the BlazorServerSideApp1.Server.csproj project file.

    <PropertyGroup>
        <UserSecretsId>BlazorServerSideApp1.Server.UserSecretsId</UserSecretsId>
    <PropertyGroup>
    
  5. Configure the connection string as a user secret for your app.

    dotnet user-secret -p BlazorServerSideApp1/BlazorServerSideApp1.Server set Azure:SignalR:ConnectionString <Your-Connection-String>
    

    NOTE: When deploying the app you'll need to configure the Azure SignalR Service connection string in the target environment. For example, in Azure App Service configure the connection string using an app setting.

  6. In the Startup class for the server project, replace the call to app.UseServerSideBlazor<App.Startup>() with the following code:

    app.UseAzureSignalR(route => route.MapHub<BlazorHub>(BlazorHub.DefaultPath));
    app.UseBlazor<App.Startup>();
    
  7. Run the app.

    If you look at the network trace for the app in the browser dev tools you see that the SignalR traffic is now being routed through the Azure SignalR Service. Congratulations!

Razor Components to ship with ASP.NET Core in .NET Core 3.0

We announced last month at .NET Conf that we've decided to move forward with shipping the Blazor server-side model as part of ASP.NET Core in .NET Core 3.0. About half of Blazor users have indicated they would use the Blazor server-side model, and shipping it in .NET Core 3.0 will make it available for production use. As part of integrating the Blazor component model into the ASP.NET Core we've decided to give it a new name to differentiate it from the ability to run .NET in the browser: Razor Components. We are now working towards shipping Razor Components and the editing in .NET Core 3.0. This includes integrating Razor Components into ASP.NET Core so that it can be used from MVC. We expect to have a preview of this support early next year after the ASP.NET Core 2.2 release has wrapped up.

Our primary goal remains to ship support for running Blazor client-side in the browser. Work on running Blazor client-side on WebAssembly will continue in parallel with the Razor Components work, although it will remain experimental for a while longer while we work through the issues of running .NET on WebAssembly. We will however keep the component model the same regardless of whether you are running on the server or the client. You can switch your Blazor app to run on the client or the server by changing a single line of code. See the Blazor .NET Conf talk to see this in action and to learn more about our plans for Razor Components:

Give feedback

We hope you enjoy this latest preview release of Blazor. As with previous releases, your feedback is important to us. If you run into issues or have questions while trying out Blazor, file issues on GitHub. You can also chat with us and the Blazor community on Gitter if you get stuck or to share how Blazor is working for you. After you've tried out Blazor for a while please let us know what you think by taking our in-product survey. Click the survey link shown on the app home page when running one of the Blazor project templates:

Blazor survey

Thanks for trying out Blazor!

Announcing ASP.NET SignalR 2.4.0 Preview 1

$
0
0

We recently released the first preview of the upcoming 2.4.0 release of ASP.NET SignalR. As we mentioned in our previous blog post on the future of ASP.NET SignalR we are releasing a new minor update to ASP.NET SignalR (the version of SignalR for System.Web and/or OWIN-based applications) that includes, support for the Azure SignalR Service, as well as some bug fixes and minor features.

We recommend you try upgrading to the preview even if you’re not interested in adopting the Azure SignalR Service at this time. Your feedback is critical to making sure we produce a stable and compatible update! You can find details about the release on the releases page of the ASP.NET SignalR GitHub repository.

Azure SignalR Service support

The Azure SignalR Service is a fully-managed service that can handle all your real-time experiences and allow you to easily scale your real-time web application. The Azure SignalR Service takes the load off your application so that you don’t have to handle all the persistent connections directly in your application. Instead, clients are re-routed to the service, which takes the burden of those persistent connections so your app can scale based on the actual throughput you need.

Moving to the Azure SignalR Service provides major benefits to your application:

  1. Your app does not need a SignalR “backplane” (Redis, SQL Server, Azure Service Bus, etc.) anymore. You can completely remove this configuration from your application and scale without having to manage your backplane.
  2. SignalR traffic runs through the Azure SignalR Service, which takes the load off your app servers. The messages still flow to your app servers, but the persistent connections themselves are made to the service, which means you can scale based on the message throughput instead of having to scale based on the number of concurrent users.
  3. Since clients connect to the service, you no longer have to worry about concurrent connection limits on your server or in browsers.

Convert an ASP.NET SignalR app to use the Azure SignalR Service

Converting your existing ASP.NET SignalR app to use the Azure SignalR Service just takes a few steps and requires no changes to your client other than updating them to the latest version of ASP.NET SignalR.

Before you can convert to use the Azure SignalR Service, you need to update your SignalR Server and Client to the latest preview build of ASP.NET SignalR 2.4.0 on NuGet.org (the latest build at the time of publishing is 2.4.0-preview1-20180920-03 but we’ll be shipping more previews so you should make sure you use the latest prerelease build).

After updating to SignalR 2.4.0, install the Microsoft.Azure.SignalR.AspNet NuGet package and change your app.MapSignalR() to app.MapAzureSignalR() and you’re using the Azure SignalR service. You just need to provision an Azure SignalR instance and provide the connection string in your Web.config file and you’re good to go!

For a detailed guide, see the aspnet-samples/ChatRoom Sample in the AzureSignalR-samples GitHub repo. The sample walks through converting an existing ASP.NET SignalR app (the aspnet-samples/ChatRoomLocal Sample) to use the Azure SignalR Service.

Limitations

  • The JSONP protocol is not supported in Azure SignalR. Your browser clients must run on browsers that support Cross-Origin Resource Sharing in order to use Azure SignalR.
  • The Azure SignalR Service does not support Persistent Connections at this time.
  • The Azure SignalR SDK requires .NET Framework 4.6.1 or higher on the server.

Conclusion

We hope you’ll try out ASP.NET SignalR 2.4.0 Preview 1 and give us feedback! Even if you aren’t interested in migrating to Azure SignalR, there are a few bug fixes that are worth getting, and we’d appreciate it if you could try updating and let us know if you encounter any issues!

As always, if you have issues, bugs or feature requests, please file them on GitHub. If you’re having an issue with the Azure SignalR SDK specifically, file it on the Azure SignalR SDK Repository. If you’re having an issue with SignalR on-premise, file it on the SignalR Repository. If you’re not sure where your issue should go, that’s OK, just file it in either one and we’ll figure out where it belongs :).

Also, if you’re interested in migrating your ASP.NET SignalR application to the Azure SignalR Service, the team would love to hear from you, please let us know at asrs@microsoft.com so we can learn more about your scenario!

Use Hybrid Connections to Incrementally Migrate Applications to the Cloud

$
0
0

As the software industry shifts to running software in the cloud, organizations are looking to migrate existing applications from on-premises to the cloud. Last week at Microsoft’s Ignite conference, Paul Yuknewicz and I delivered a talk focused on how to get started migrating applications to Azure (watch the talk free) where we walked through the business case for migrating to the cloud, and choosing the right hosting and data services.

If your application is a candidate for running in App Service, one of the most useful pieces of technology that we showed was Hybrid Connections. Hybrid Connections let you host a part of your application in Azure App Service, while calling back into resources and services not running in Azure (e.g. still on-premises). This enables you to try running a small part of your application in the cloud without the need to move your entire application and all of its dependencies at once; which is usually time consuming, and extremely difficult to debug when things don’t work. So, in this post I’ll show you how to host an ASP.NET front application in the cloud, and configure a hybrid connection to connect back to a service on your local machine.

Publishing Our Sample App to the Cloud

For the purposes of this post, I’m going to use the Smart Hotel 360 App sample that uses an ASP.NET front end that calls a WCF service which then accesses a SQL Express LocalDB instance on my machine.

The first thing I need to do is publish the ASP.NET application to App Service. To do this, right click on the “SmartHotel.Registration.Web” project and choose “Publish”

clip_image001

The publish target dialog is already on App Service, and I want to create a new one, so I will just click the “Publish” button.

This will bring up the “Create App Service” dialog.  Next, I will click “Create” and wait for a minute while the resources in the cloud are created and the application is published.

clip_image003

When it’s finished publishing, my web browser will open to my published site. At this point, there will be an error loading the page since it cannot connect to the WCF service. To fix this we’ll add a hybrid connection.

image

Create the Hybrid Connection

To create the Hybrid Connection, I navigate to the App Service I just created in the Azure Portal. One quick way to do this is to click the “Managed in Cloud Explorer” link on the publish summary page

clip_image005

Right click the site, and choose “Open in Portal” (You can manually navigate to the page by logging into the Azure portal, click App Services, and choose your site).

clip_image006

To create the hybrid connection:

Click the “Networking” tab in the Settings section on the left side of the App Service page

Click “Configure your hybrid connection endpoints” in the “Hybrid connections” section

image

Next, click “Add a hybrid connection”

Then click “Create a new hybrid connection”

clip_image010

Fill out the “Create new hybrid connection” form as follows:

  • Hybrid connection Name: any unique name that you want
  • Endpoint Host: This is the machine URL your application is currently using to connect to the on-premises resource. In this case, this is “localhost” (Note: per the documentation, use the hostname rather than a specific IP address if possible as it’s more robust)
  • Endpoint Port: The port the on-premises resource is listening on. In this case, the WCF service on my local machine is listening on 2901
  • Servicebus namespace: If you’ve previously configured hybrid connections you can re-use an existing one, in this case we’ll create a new one, and give it a name

clip_image011

Click “OK”. It will take about 30 seconds to create the hybrid connection, when it’s done you’ll see it appear on the Hybrid connections page.

Configure the Hybrid Connection Locally

Now we need to install the Hybrid Connection Manager on the local machine. To do this, click the “Download connection manager” on the Hybrid connections page and install the MSI.

clip_image013

After the connection manager finishes installing, launch the “Hybrid Connections Manager UI”, it should appear in your Windows Start menu if you type “Hybrid Connections”. (If for some reason it doesn’t appear on the Start Menu, launch it manually from “C:\Program Files\Microsoft\HybridConnectionManager <version#>”)

Click the “Add a new Hybrid Connection” button in the Hybrid Connections Manager UI and login with the same credentials you used to publish your application.

clip_image015

Choose the subscription you used published your application from the “Subscription” dropdown, choose the hybrid connection you just created in the portal, and click “Save”.

clip_image017

In the overview, you should see the status say “Connected”. Note: If the state won’t change from “Not Connected”, I’ve found that rebooting my machine fixes this (it can take a few minutes to connect after the reboot).

clip_image019

Make sure everything is running correctly on your local machine, and then when we open the site running in App Service we can see that it loads with no error. In fact, we can even put a breakpoint in the GetTodayRegistrations() method of Service.svc.cs, hit F5 in Visual Studio, and when the page loads in App Service the breakpoint on the local machine is hit!

clip_image021

Conclusion

If you are looking to move applications to the cloud, I hope that this quick introduction to Hybrid Connections will enable you to try moving things incrementally. Additionally, you may find these resources helpful:

As always, if you have any questions, or problems let me know via Twitter, or in the comments section below.


ASP.NET Core 2.2.0-preview3 now available

$
0
0

Today we’re very happy to announce that the third preview of the next minor release of ASP.NET Core and .NET Core is now available for you to try out. We’ve been working hard on this release, along with many folks from the community, and it’s now ready for a wider audience to try it out and provide the feedback that will continue to shape the release.

How do I get it?

You can download the new .NET Core SDK for 2.2.0-preview3 (which includes ASP.NET 2.2.0-preview3) from https://www.microsoft.com/net/download/dotnet-core/2.2

Visual Studio requirements

Customers using Visual Studio should also install and use the Preview channel of Visual Studio 2017 (15.9 Preview 3 or later) in addition to the SDK when working with .NET Core 2.2 and ASP.NET Core 2.2 projects. Please note that the Visual Studio preview channel can be installed side-by-side with existing an Visual Studio installation without disrupting your current development environment.

Azure App Service Requirements

If you are hosting your application on Azure App Service, you can follow these instructions to install the required site extension for hosting your 2.2.0-preview3 applications.

Impact to machines

Please note that is a preview release and there are likely to be known issues and as-yet-to-be discovered bugs. While the .NET Core SDK and runtime installs are side-by-side, your default SDK will become the latest one. If you run into issues working on existing projects using earlier versions of .NET Core after installing the preview SDK, you can force specific projects to use an earlier installed version of the SDK using a global.json file as documented here. Please log an issue if you run into such cases as SDK releases are intended to be backwards compatible.

What’s new in Preview 3

For a full list of changes, bug fixes, and known issues you can read the release announcement.

Routing

We’ve introduced the concept of Parameter Transformers to routing in ASP.NET Core 2.2. A parameter transformer customizes the route generated by transforming parameter’s route values, and gives developers new options when generating routes. For example, a custom slugify parameter transformer in route pattern blog\{article:slugify} with Url.Action(new { article = "MyTestArticle" }) generates blog\my-test-article. Parameter transformers implement Microsoft.AspNetCore.Routing.IOutboundParameterTransformer and are configured using ConstraintMap.

These features are specific to the new endpoint routing system used in MVC by default in 2.2.

Parameter transformers are also used by frameworks to transform the URI to which an endpoint resolves. For example, ASP.NET Core MVC uses parameter transformers to transform the route value used to match an area, controller, action, and page.

routes.MapRoute(
    name: "default",
    template: "{controller=Home:slugify}/{action=Index:slugify}/{id?}");

With the preceding route, the action SubscriptionManagementController.GetAll() is matched with the URI /subscription-management/get-all. A parameter transformer doesn’t change the route values used to generate a link. Url.Action("GetAll", "SubscriptionManagement") outputs /subscription-management/get-all.

ASP.NET Core provides API conventions for using a parameter transformers with generated routes:

  • MVC has the Microsoft.AspNetCore.Mvc.ApplicationModels.RouteTokenTransformerConvention API convention. This convention applies a specified parameter transformer to all attribute routes in the app. The parameter transformer will transform attribute route tokens as they are replaced. For more information, see Use a parameter transformer to customize token replacement.
  • Razor pages has the Microsoft.AspNetCore.Mvc.ApplicationModels.PageRouteTransformerConvention API convention. This convention applies a specified parameter transformer to all automatically discovered Razor pages. The parameter transformer will transform the folder and file name segments of Razor page routes. For more information, see Use a parameter transformer to customize page routes.

Link Generation

Added a new service called LinkGenerator, it is a singleton service that supports generating paths and absolute URIs both with and without an HttpContext. If you need to generate links in Middleware or somewhere outside of Razor then this new service will be useful to you. You can use it in Razor, but the existing APIs like Url.Action are already backed by the new service so you can continue to use those.

return _linkGenerator.GetPathByAction(
     httpContext,
     controller: "Home",
     action: "Index",
     values: new { id=42 });

For now this is useful to link to MVC actions and pages from outside of MVC. We will add additional features in the next release targeting non-MVC scenarios.

Health Checks

DbContextHealthCheck

We added a new DbContext based check for when you are using Entity Framework Core:

// Registers required services for health checks
services.AddHealthChecks()
        // Registers a health check for the MyContext type. By default the name of the health check will be the
        // name of the DbContext type. There are other options available through AddDbContextCheck to configure
        // failure status, tags, and custom test query.
        .AddDbContextCheck<MyContext>();

This check will make sure that the application can communicate with the database you configured for MyContext. By default the DbContextHealthCheck will call the CanConnectAsync method that is being added to Entity Framework Core 2.2. You can customize what operation is run when checking health using overloads of the AddDbContextCheck method.

Health Check Publisher

We added the IHealthCheckPublisher interface that has a single method you can implement:

Task PublishAsync(HealthReport report, CancellationToken cancellationToken);

If you add an IHealthCheckPublisher to DI then the health checks system will periodically execute your health checks and call PublishAsync with the result. We expect this to be useful when you are interacting with a push based health system that expects each process to call it periodically in order to determine health.

Tags

In preview3 we added the ability to tag health checks with a list of strings when you register them:

services.AddHealthChecks()
        .AddDbContextCheck<MyContext>(tags: new[] { "db" });

Once you’ve done this then you can filter execution of your checks via tag:

app.UseHealthChecks("/liveness", new HealthCheckOptions
{
    Predicate = (_) => false
});

app.UseHealthChecks("/readiness", new HealthCheckOptions
{
    Predicate = (check) => check.Tags.Contains("db")
});

We see tags as a way for consumers of health checks, application authors, to use as a convenient grouping and filtering mechanism for their health checks. Not something that health check authors will pre-populate.

You can also customize what status a failure of this check means for your application, for example if your application is written such that it can handle the database not being available then a database being down might mean Degraded rather than UnHealthy.

Validation Performance Improvements

MVC’s validation system is designed to be extensible and flexible allowing developer to determine on a per request basis what validators apply to a given model. This is great for authoring complex validation providers. However, in the most common case your application only uses the built-in validation pieces such as DataAnnotations ([Required], [StringLength] etc, or IValidatableObject) and don’t require this extra flexability.

In 2.2.0-preview3, we’re adding a feature that allows MVC to short-circuit validation if it can determine that a given model graph would not require any validation. This results in significant improvements when validating models that cannot or do not have any associated validators. This includes objects such as collections of primitives (byte[], string[], Dictionary<string, string> etc), or complex object graphs without many validators.

For this model – https://github.com/aspnet/Mvc/blob/release/2.2/benchmarkapps/BasicApi/Models/Pet.cs – the table below compares the difference in Requests Per Second (RPS) with and without the enhancement:

Description RPS Memory (MB) Avg. Latency (ms) Startup (ms) First Request (ms) Ratio
Baseline 78,738 398 3.5 547 111.3 1.00
Validation changes 90,167 401 2.9 541 115.9 1.15

HTTP Client Performance Improvements

Some significant performance improvements have been made to SocketsHttpHandler by improving the connection pool locking contention. For applications making many outgoing HTTP requests, such as some Microservices architectures, throughput should be significantly improved. Our internal benchmarks show that under load HttpClient throughput has improved by 60% on Linux and 20% on Windows. At the same time the 90th percentile latency was cut down by two on Linux. See Github #32568 for the actual code change that made this improvement.

Requests Per Second Linux (higher is better)

image

Requests Per Second Windows (higher is better)

image

Request Latency Linux (lower is better)

image

Request Latency Windows (lower is better)

image

ASP.NET Core Module

We added support for the ability to detect client disconnects when you’re using the new IIS in-process hosting model. The HttpContext.RequestAborted cancellation token now gets tripped when your client disconnnects.

The ASP.NET Core Module also features enhanced diagnostics logs that configurable via the new handler settings or environment variables that expose a higher fidelity of diagnostic information.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <handlers>
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
      </handlers>
      <aspNetCore processPath="dotnet" arguments=".\clientdisconnect.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess">
        <handlerSettings>
          <handlerSetting name="debugFile" value="debug.txt" />
          <handlerSetting name="debugLevel" value="TRACE" />
        </handlerSettings> 
      </aspNetCore>
    </system.webServer>
  </location>
</configuration>

SignalR Java Client

Preview 3 includes a few notable changes to the SignalR Java Client as we progress towards a 1.0 release:

The “groupId” for the Maven package has changed to com.microsoft.signalr. To reference the new package from a Maven POM file, add the following dependency:

<dependency>
    <groupId>com.microsoft.signalr</groupId>
    <artifactId>signalr</artifactId>
    <version>1.0.0-preview3-35501</version>
</dependency>

Or in Gradle:

implementation 'com.microsoft.signalr:signalr:1.0.0-preview3-35501'

In Preview 3 we’ve changed all the APIs to be asynchronous, using RxJava. Our Java Client documentation will be updated to show the new usage patterns. We also have support for the invoke method, allowing the client code to wait for the server method to complete. This version also includes support for serializing custom types in method arguments and return values.

The Java Client currently requires Android API Level 26 (or higher). We are investigating moving down to a lower API level before RTM. If you are planning to use SignalR in an Java-based Android application, please comment on the GitHub issue tracking our Android API level support so we know what API level would work well for our users.

Migrating an ASP.NET Core 2.1 project to 2.2

To migrate an ASP.NET Core project from 2.1.x to 2.2.0-preview3, open the project’s .csproj file and change the value of the the element to netcoreapp2.2. You do not need to do this if you’re targeting .NET Framework 4.x.

Giving Feedback

The main purpose of providing previews is to solicit feedback so we can refine and improve the product in time for the final release. Please help provide us feedback by logging issues in the appropriate repository at https://github.com/aspnet or https://github.com/dotnet. We look forward to receiving your feedback!

ASP.NET SignalR 2.4.0 Preview 2

$
0
0

We’ve just released the second preview of the upcoming 2.4.0 release of ASP.NET SignalR. As we mentioned in our previous blog post on the future of ASP.NET SignalR we are releasing a minor update to ASP.NET SignalR (the version of SignalR for System.Web and/or OWIN-based applications) that includes, support for the Azure SignalR Service, as well as some bug fixes and minor features.

We recommend you try upgrading to the preview even if you’re not interested in adopting the Azure SignalR Service at this time. Your feedback is critical to making sure we produce a stable and compatible update! You can find details about the release on the releases page of the ASP.NET SignalR GitHub repository.

Highlights

This preview mostly contains further bug fixes and changes to support the Azure SignalR service. Some of the major fixes include:

Other minor fixes are included, for a full list see our GitHub issue tracker

Announcing CosmosDB Table Async OutputCache Provider Release and ASP.NET Providers Connected Service Extension Update

$
0
0

Through the years, ASP.NET team have been releasing new ASP.NET SessionState and OutputCache providers to help developers make their web applications ready for the cloud environment. Today we are announcing a new OutputCache provider, Microsoft.AspNet.OutputCache.CosmosDBTableAsyncOutputCacheProvider,  to enable your applications store the OutputCache data into CosmosDB. It supports both Azure CosmosDB Table and Azure Storage Table.

How to Use CosmosDBTableAsyncOutputCacheProvider

  1. Open the NuGet package manager and search for Microsoft.AspNet.OutputCache.CosmosDBTableAsyncOutputCacheProvider and install. Make sure that your application is targeted to .NET Framework 4.6.2 or higher version. Download the .NET Framework 4.6.2 Developer Pack if you do not already have it installed.
  2. The package has dependency on Microsoft.AspNet.OutputCache.OutputCacheModuleAsync Nuget package and Microsoft.Azure.CosmosDB.Table Nuget package. After you install the package, both Microsoft.AspNet.OutputCache.CosmosDBTableAsyncOutputCacheProvider.dll and dependent assemblies will be copied to the Bin folder.
  3. Open the web.config file, you will see two new configuration sections are added, caching and appSettings. The first one is to configure the OutputCache provider, you may want to update the table name. The provider will create the table if it doesn’t exist on the configured Azure service instance. The second one is the appSettings for the storage connection string. Depends on the connection string you use, the provider can work with either Azure CosmosDB Table or Azure Storage Table.

    ASP.NET Providers Connected Service Extension Update

    5 months ago, we released ASP.NET Providers Connected Service Visual Studio Extension to help the developers to pick the right ASP.NET provider and configure it properly to work with Azure resources. Today we are releasing an update for this extension which enables you configure ComosDB table OutputCache provider and Redis cache OutputCache.

    Summary

    The new CosmosDBTableAsyncOutputCacheProvider Nuget package enables your ASP.NET application leverage Azure CosmosDB and Azure Storage to store the OutputCache data. The new ASP.NET Providers Connected Service extension adds more Azure ready ASP.NET providers support. Please try it today and let us know you feedback.

A first look at changes coming in ASP.NET Core 3.0

$
0
0

While we continue to work on finalizing the next minor version of ASP.NET Core, we’re also working on major updates to our next release that will include some changes in how projects are composed with frameworks, tighter .NET Core integration, and 3rd party open source integration, all with the goal of making it easier and faster for you to develop. For broader context around .NET Core 3.0, we encourage you to check out our previous announcements around the addition of WinForms and WPF support to .NET Core 3.0 on Windows. We’ll publish more details about new features coming in ASP.NET Core 3.0 in the near future.

Packages vs. Frameworks

For historical context, the way projects reference and run on ASP.NET Core has changed through the versions and years. In 1.0, ASP.NET Core itself was “just packages”, and appeared in projects like any other NuGet package reference. This had benefits and drawbacks, and over time we’ve evolved this model to try and balance the advantages of modular references with those of larger, prerequisite frameworks. In 2.1, ASP.NET Core eventually evolved to be available as a .NET Core “shared framework” (like the base of .NET Core itself, Microsoft.NETCore.App, has been since 1.0). This blog post by ASP.NET Core team member Nate McMaster does a good job of explaining how the shared framework works while also highlighting some of the issues with the current approach. Updates we’re introducing in 3.0 are designed to reduce these issues for all our users.

As part of this change, some notable sub-components will be removed from the ASP.NET Core shared framework in 3.0:

  • Json.NET (Newtonsoft.Json)
  • Entity Framework Core (Microsoft.EntityFrameworkCore.*)

See this announcement for more details regarding the addition of JSON APIs in .NET Core. For places in ASP.NET Core that rely on Json.NET features today (e.g. the JSON formatter in MVC), we’ll continue to ship packages that provide that integration moving forward, however the default experiences will change to use the upcoming in-box JSON APIs.

Entity Framework Core will ship as “pure” NuGet packages in 3.0. This makes its shipping model the same as all other data access libraries on .NET, and allows it the simplest path to continue innovation while providing support for all the various .NET platforms customers enjoy it on today. Note, Entity Framework Core moving out of the shared framework has no impact on its status as a Microsoft developed, supported, and serviceable library, and it will continue to be covered by the .NET Core support policy.

Fully leveraging .NET Core

As announced on the .NET Blog earlier this month, .NET Framework will get fewer of the newer platform and language features that come to .NET Core moving forward, due to the in-place update nature of .NET Framework and the desire to limit changes there that might break existing applications. To ensure ASP.NET Core can fully leverage the improvements coming to .NET Core moving forward, ASP.NET Core will only run on .NET Core starting from 3.0. Moving forward, you can simply think of ASP.NET Core as being part of .NET Core.

Customers utilizing ASP.NET Core on .NET Framework today can continue to do so in a fully supported fashion using the 2.1 LTS release. Support and servicing for 2.1 will continue until at least August 21, 2021 (3 years after its declaration as an LTS release) in accordance with the .NET Core support policy.

For more information about porting from .NET Framework to .NET Core, see this documentation.

Delivering more value with focused 3rd party open-source integration

At the same time we’re drawing a clearer distinction between what constitutes the “platform” in 3.0, and in doing so removing 3rd party components from that layer, we recognize that many higher-level scenarios are best assisted by established, capable, and well supported open-source components, and that we can provide support and assistance to the community and our customers by helping to ensure these components integrate as well as possible into ASP.NET Core applications.

This support will take different forms, including first-class integration APIs & packages built by our team, contributions made to existing libraries by our engineers, project templates in the default experiences that utilize these libraries, documentation that lives on the official ASP.NET Core docs site, and processes for dealing with critical issues and bug fixes, including security.

We’ve already begun this in the 2.2 wave, with new integration being developed for the popular IdentityServer library, which will help us deliver a simple and functional story for API Authorization in ASP.NET Core applications, while allowing customers to leverage the full power of IdentityServer when they need to.

We’re also working on streamlining the experience for building HTTP APIs, with new API Conventions and analyzers that make working with popular Open API libraries like Swashbuckle and NSwag easier, and a new API client generation system that allows for simple integration with code generators like AutoRest and NSwag.

For folks excited by our new Health Checks feature, the owners of the BeatPulse library are working to port their extensive library of checks over.

We intend to bring these experiences together in a new project template to be made available in the period after 2.2 ships.

Conclusion

Stay tuned for more updates as we continue working on ASP.NET Core in .NET Core 3.0, including a summary of the new features we’re working to enable as part of this release. We also regularly post details of changes and other information on our announcements repo, which we encourage you to subscribe to.

When should you right click publish

$
0
0

Some people say ‘friends don’t let friends right click publish’ but is that true? If they mean that there are great benefits to setting up a CI/CD workflow, that’s true and we will talk more about these benefits in just a minute. First, let’s remind ourselves that the goal isn’t always coming up with the best long-term solution.

Technology moves fast and as developers we are constantly learning and experimenting with new languages, frameworks and platforms. Sometimes we just need to prototype something rather quickly in order to evaluate its capabilities. That’s a classic scenario where right click publish in Visual Studio provides the right balance between how much time you are going to spend (just a few seconds) and the options that become available to you (quite a few depending on the project type) such as publish to IIS, FTP  & Folder (great for xcopy deployments and integration with other tools).

Continuing with the theme of prototyping and experimenting, right click publish is the perfect way for existing Visual Studio customers to evaluate Azure App Service (PAAS). By following the right click publish flow you get the opportunity to provision new instances in Azure and publish your application to them without leaving Visual Studio:

When the right click publish flow has been completed, you immediately have a working application running in the cloud:

Platform evaluations and experiments take time and during that time, right click publish helps you focus on the things that matter. When you are ready and the demand rises for automation, repeatability and traceability that’s when investing into a CI/CD workflow starts making a lot of sense:

  • Automation: builds are kicked off and tests are executed as soon as you check in your code
  • Repeatability: it’s impossible to produce binaries without having the source code checked in
  • Traceability: each build can be traced back to a specific version of the codebase in source control which can then be compared with another build and figure out the differences

The right time to adopt CI/CD typically coincides with a milestone related to maturity; either and application milestone or the team’s that is building it. If you are the only developer working on your application you may feel that setting up CI/CD is overkill, but automation and traceability can be extremely valuable even to a single developer once you start shipping to your customers and you have to support multiple versions in production.

With a CI/CD workflow you are guaranteed that all binaries produced by a build can be linked back to the matching version of the source code. You can go from a customer bug report to looking at the matching source code easily, quickly and with certainty. In addition, the automation aspects of CI/CD save you valuable time performing common tasks like running tests and deploying to testing and pre-production environments, lowering the overhead of good practices that ensure high quality.

As always, we want to see you successful, so if you run into any issues using publish in Visual Studio or setting up your CI/CD workload, let me know in the comment section below and I’ll do my best to get your question answered.

ASP.NET SignalR 2.4.0

$
0
0

We’ve just shipped the final 2.4.0 version of ASP.NET SignalR, the version of SignalR for System.Web and/or OWIN-based applications. As we mentioned in a previous post on the future of ASP.NET SignalR, 2.4.0 is a minor release which contains some small bug fixes and updates. The majority of the features and fixes we implemented for ASP.NET SignalR were outlined in the 2.4.0 Preview 2 post.

Support for StackExchange Redis 2.0

In 2.4.0 we’re adding support for the new 2.0 release of the StackExchange.Redis package. If you’re using StackExchange’s Redis package in your SignalR apps and you want to update to the StackExchange Redis 2.0 version, you’ll need to remove your existing package reference to Microsoft.AspNet.SignalR.Redis, then add a reference to the new Microsoft.AspNet.SignalR.StackExchangeRedis package.

Once you make the package reference changes, you’ll also want to replace calls to the UseRedis method with UseStackExchangeRedis.

Your Feedback is Welcome and Appreciated

We recommend you try upgrading to 2.4.0. Your feedback is critical to making sure we produce a stable and compatible update, and has contributed to the continued success of our real-time libraries! You can find details about the release on the releases page of the ASP.NET SignalR GitHub repository.

Blazor 0.7.0 experimental release now available

$
0
0

Blazor 0.7.0 is now available! This release focuses on enabling component coordination across ancestor-descendent relationships. We've also added some improvements to the debugging experience.

Here's what's new in the Blazor 0.7.0 release:

  • Cascading values and parameters
  • Debugging improvements

A full list of the changes in this release can be found in the Blazor 0.7.0 release notes.

Get Blazor 0.7.0

Install the following:

  1. .NET Core 2.1 SDK (2.1.500 or later).
  2. Visual Studio 2017 (15.9 or later) with the ASP.NET and web development workload selected.
  3. The latest Blazor Language Services extension from the Visual Studio Marketplace.
  4. The Blazor templates on the command-line:

    dotnet new -i Microsoft.AspNetCore.Blazor.Templates
    

You can find getting started instructions, docs, and tutorials for Blazor at https://blazor.net.

Upgrade an existing project to Blazor 0.7.0

To upgrade a Blazor 0.6.0 project to 0.7.0:

  • Install the prerequisites listed above.
  • Update the Blazor packages and .NET CLI tool references to 0.7.0. The upgraded Blazor project file should look like this:

    <Project Sdk="Microsoft.NET.Sdk.Web">
    
    <PropertyGroup>
        <TargetFramework>netstandard2.0</TargetFramework>
        <RunCommand>dotnet</RunCommand>
        <RunArguments>blazor serve</RunArguments>
        <LangVersion>7.3</LangVersion>
    </PropertyGroup>
    
    <ItemGroup>
        <PackageReference Include="Microsoft.AspNetCore.Blazor.Browser" Version="0.7.0" />
        <PackageReference Include="Microsoft.AspNetCore.Blazor.Build" Version="0.7.0" />
        <DotNetCliToolReference Include="Microsoft.AspNetCore.Blazor.Cli" Version="0.7.0" />
    </ItemGroup>
    
    </Project>
    

That's it! You're now ready to try out the latest Blazor features.

Cascading values and parameters

Blazor components can accept parameters that can be used to flow data into a component and impact the component's rendering. Parameter values are provided from parent component to child component. Sometimes, however, it's inconvenient to flow data from an ancestor component to a descendent component, especially when there are many layers in between. Cascading values and parameters solve this problem by providing a convenient way for an ancestor component to provide a value that is then available to all descendent components. They also provide a great way for components to coordinate.

For example, if you wanted to provide some theme information for a specific part of your app you could flow the relevant styles and classes from component to component, but this would be tedious and cumbersome. Instead, a common ancestor component can provide the theme information as a cascading value that descendents can accept as a cascading parameter and then consume as needed.

Let's say the following ThemeInfo class specifies all of the theme information that you want to flow down the component hierarchy so that all of the buttons within that part of your app share the same look and feel:

public class ThemeInfo 
{
    public string ButtonClass { get; set; }
}

An ancestor component can provide a cascading value using the CascadingValue component. The CascadingValue component wraps a subtree of the component hierarchy and specifies a single value that will be available to all components within that subtree. For example, we could specify the theme info in our application layout as a cascading parameter for all components that make up the layout body like this:

@inherits BlazorLayoutComponent

<div class="sidebar">
    <NavMenu />
</div>

<div class="main">
    <div class="top-row px-4">
        <a href="http://blazor.net" target="_blank" class="ml-md-auto">About</a>
    </div>

    <CascadingValue Value="@theme">
        <div class="content px-4">
            @Body
        </div>
    </CascadingValue>
</div>

@functions {
    ThemeInfo theme = new ThemeInfo { ButtonClass = "btn-success" };
}

To make use of cascading values, components can declare cascading parameters using the [CascadingParameter] attribute. Cascading values are bound to cascading parameters by type. In the following example the Counter component is modified to have a cascading parameter that binds to the ThemeInfo cascading value, which is then used to set the class for the button.

@page "/counter"

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn @ThemeInfo.ButtonClass" onclick="@IncrementCount">Click me</button>

@functions {
    int currentCount = 0;

    [CascadingParameter] protected ThemeInfo ThemeInfo { get; set; }

    void IncrementCount()
    {
        currentCount++;
    }
}

When we run the app we can see that the new style is applied:

Counter with cascading parameter

Cascading parameters also enable components to collaborate across the component hierarchy. For example, let's say you have a TabSet component that contains a number of Tab components, like this:

<TabSet>
    <Tab Title="First tab">
        <h4>First tab</h4>
        This is the first tab.
    </Tab>

    @if (showSecondTab)
    {
        <Tab Title="Second">
            <h4>Second tab</h4>
            You can toggle me.
        </Tab>
    }

    <Tab Title="Third">
        <h4>Third tab</h4>

        <label>
            <input type="checkbox" bind=@showSecondTab />
            Toggle second tab
        </label>
    </Tab>
</TabSet>

In this example the child Tab components are not explicitly passed as parameters to the TabSet. Instead they are simply part of the child content of the TabSet. But the TabSet still needs to know about each Tab so that it can render the headers and the active tab. To enable this coordination without requiring any specific wire up from the user, the TabSet component can provide itself as a cascading value that can then be picked up by the descendent Tab components:

In TabSet.cshtml

<!-- Display the tab headers -->
<CascadingValue Value=this>
    <ul class="nav nav-tabs">
        @ChildContent
    </ul>
</CascadingValue>

This allows the descendent Tab components to capture the containing TabSet as a cascading parameter, so they can add themselves to the TabSet and coordinate on which Tab is active:

In Tab.cshtml

[CascadingParameter] TabSet ContainerTabSet { get; set; }

Check out the full TabSet sample here.

Debugging improvements

In Blazor 0.5.0 we added some very preliminary support for debugging client-side Blazor apps in the browser. While this initial debugging support demonstrated that debugging .NET apps in the browser was possible, it was still a pretty rough experience. Blazor 0.7.0 picks up the latest runtime updates, which includes some fixes that makes the debugging experience more reliable. You can now more reliably set and remove breakpoints, and the reliability of step debugging has been improved.

Improved Blazor debugging

Give feedback

We hope you enjoy this latest preview release of Blazor. As with previous releases, your feedback is important to us. If you run into issues or have questions while trying out Blazor, file issues on GitHub. You can also chat with us and the Blazor community on Gitter if you get stuck or to share how Blazor is working for you. After you've tried out Blazor for a while please let us know what you think by taking our in-product survey. Click the survey link shown on the app home page when running one of the Blazor project templates:

Blazor survey

Thanks for trying out Blazor!


Razor support in Visual Studio Code now in Preview

$
0
0

Earlier this week we released a preview of support for working with Razor files (.cshtml) in the C# extension for Visual Studio Code (1.17.1). This initial release introduces C# completions, directive completions, and basic diagnostics (red squiggles for errors) for ASP.NET Core projects.

Prerequisites

To use this preview of Razor support in Visual Studio Code install the following:

If you already installed VS Code and the C# extension in the past, make sure you have updated to the latest versions of both.

Get started

To try out the new Razor tooling, create a new ASP.NET Core web app and then edit any Razor (.cshtml) file.

  1. Open Visual Studio Code
  2. Select Terminal > New Terminal
  3. In the new terminal run:

    dotnet new webapp -o WebApp1`
    code -r WebApp1
    
  4. Open About.cshtml

  5. Try out HTML completions

    HTML completions

  6. And Razor directive completions

    Directive completions

  7. And C# completions

    C# completions

  8. You also get diagnostics (red squiggles)

    C# diagnostics

Limitations and known issues

This is the first alpha release of the Razor tooling for Visual Studio Code, so there are a number of limitations and known issues:

  • Razor editing is currently only supported in ASP.NET Core projects (no support for ASP.NET projects or Blazor projects yet)
  • Support for tag helpers and formatting is not yet implemented
  • Limited support for colorization
  • Loss of HTML completions following C# less than (<) operator
  • Error squiggles misaligned for expressions near the start of a new line
  • Incorrect errors in Blazor projects for event bindings
  • Emmet based abbreviation expansion is not yet supported

Note that if you need to disable the Razor tooling for any reason:

  • Open the Visual Studio Code User Settings: File -> Preferences -> Settings
  • Search for "razor"
  • Check the "Razor: Disabled" checkbox

Feedback

Even though the functionality of Razor tooling is currently pretty limited, we are shipping this preview now so that we can start collecting feedback. Any issues or suggestions for the Razor tooling in Visual Studio Code should be reported on the https://github.com/aspnet/Razor.VSCode repo.

To help us diagnose any reported issues please provide the following information in the GitHub issue:

  1. Razor (cshtml) file content
  2. Generated C# code from the Razor CSharp output
    • Right-click inside your .cshtml file and select "Command Palette"
    • Search for and select "Razor: Show Razor CSharp"
  3. Verbose Razor log output
    • See instructions for capturing the Razor log output here
  4. OmniSharp log output
    • Open VS Code's "Output" pane
    • In the dropdown choose "OmniSharp Log"

What's next?

Next up we are working on tag helper support. This will include support for tag helper completions and IntelliSense. Once we have tag helper tooling support in place we can then start work on enabling Blazor tooling support as well. Follow our progress and join in the conversation on the https://github.com/aspnet/Razor.VSCode repo.

Thanks for trying out this early preview!

Announcing ASP.NET Core 2.2, available today!

$
0
0

I’m happy to announce that ASP.NET Core 2.2 is available as part of .NET Core 2.2 today!

How to get it

You can download the new .NET Core SDK (2.2.100) for your dev machine and build servers from the .NET Core 2.2 download page. New Windows Server hosting, runtime installers and binary archives are also available from this page for updating servers.

This release updates .NET Core, ASP.NET Core, and Entity Framework Core to version 2.2.0. The new SDK version is 2.2.100. Visual Studio requirements are as follows:

Visual Studio 2019 16.0 Preview 1, also available today, includes the .NET Core SDK 2.2.100 as an optional component.

What’s new?

The main theme for this ASP.NET Core release was to improve developer productivity and platform functionality with regard to building Web/HTTP APIs. As usual, we made some performance improvements as well. We’ve posted about these features as part of the preview releases and you as such you can read about them by following the links below:

Health Checks integration with BeatPulse

We’re happy to announce that the BeatPulse project now supports the new Health Checks API, which means you can easily add checks for dozens of popular systems and dependencies using their great support. Here’s a message from the BeatPulse team about their support for our new Health Checks API:

BeatPulse is a community driven project that was created to provide health checking mechanisms for systems, networking and a wide variety of services that are common within the enterprise, e.g. SqlServer, MySql,Postgress, Redis, Kafka and many more . When Microsoft announced ASP.NET Core Health Checks for the 2.2 roadmap, the BeatPulse team ported all the existing liveness packages and features to work with the new Microsoft Health Checks abstractions at the repository AspNetCore.Diagnostics.HealthChecks. Apart from all the health checking packages, the BeatPulse team also incorporates other features like pulse tracking (Application Insights and Prometheus), failure notifications and a UI interface were we can configure different monitored systems and have a global view of health status. This UI is available as a Docker image published in Docker Hub.

More coming soon

When we announced planning for ASP.NET Core 2.2, we mentioned a number of features that aren’t detailed above, including API Authorization with IdentityServer4, Open API (Swagger) driven client code generation, and the HTTP REPL command line tool. These features are still being worked on and aren’t quite ready for release, however we expect to make them available as add-ons in the coming months. Thanks for your patience while we complete these experiences and get them ready for you all to try out.

Migrating a project to ASP.NET Core 2.2

To migrate an ASP.NET Core project from 2.1 to 2.2, open the project’s .csproj file and change the value of the TargetFramework element to netcoreapp2.2. You do not need to do this if you’re targeting .NET Framework 4.x.

Finish by updating your NuGet package references to the latest stable versions. Note that projects targeting .NET Core (rather than .NET Framework) should not have a package version specified for the Microsoft.AspNetCore.App package reference as this will be managed automatically by the SDK. Doing so will now result in a build warning.

For more information on upgrading to ASP.NET Core 2.2 see here.

Support life cycle

ASP.NET Core 2.2 is the latest release in the “Current” .NET Core train. This represents the first release since the declaration of 2.1 LTS that reestablishes a separate LTS and Current train. The Current train is where new features, enhancements, and regular bug fixes are applied and is recommended for most customers. Note that both LTS and Current releases receive servicing updates for security and critical stability fixes. It is currently expected that 2.2 will the last non-servicing release in the 2.x life cycle, and as such customers not using an LTS release will need to migrate to 3.0 GA, within 3 months of its release in the second half of 2019 in order to remain supported.

Read more about the .NET Core support policy here.

Availability in Azure App Service

The .NET Core 2.2 SDK, runtime, and updated ASP.NET Core IIS Module are in the process of being deployed to Azure App Service regions around the world. We expect this to be completed before the end of December 2018.

Some regions may receive the updated runtime before the updated ASP.NET Core IIS Module (ANCM), which is required by default for projects targeting ASP.NET Core 2.2. It’s also a requirement for the new in-process hosting feature. If you receive startup errors after deploying to Azure App Service, try configuring your project to use the existing version of ANCM by setting the AspNetCoreModule property to the value “AspNetCoreModule”, e.g.:

<PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <AspNetCoreModuleName>AspNetCoreModule</AspNetCoreModuleName>
    <AspNetCoreHostingModel>OutOfProcess</AspNetCoreHostingModel>
</PropertyGroup>

Once the target region has been updated with the latest ANCM version, you can remove that property altogether and redeploy the application to have it switch to using the new ANCM.

This release also adds better 64-bit support for .NET Core in Azure App Service. If you’re running your ASP.NET Core application on .NET Core 2.2 with in-process hosting, you can simply enable the 64-bit option in the Azure Portal and the site will now run in a 64-bit process. For other information on how to run your ASP.NET Core application in a 64-bit process in Azure App Service with other configurations, see this article.

Giving feedback

As always, please provide us feedback by logging issues at https://github.com/aspnet/AspNetCore. We look forward to hearing from you!

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

$
0
0

.NET Core 3.0 Preview 2 is now available and it includes a bunch of new updates to ASP.NET Core.

Here's the list of what's new in this preview:

  • Razor Components
  • SignalR client-to-server streaming
  • Pipes on HttpContext
  • Generic host in templates
  • Endpoint routing updates

Get started

To get started with ASP.NET Core in .NET Core 3.0 Preview 2 install the .NET Core 3.0 Preview 2 SDK

If you're on Windows using Visual Studio, you'll also want to install the latest preview of Visual Studio 2019.

Upgrade an existing project

To upgrade an existing an ASP.NET Core app to .NET Core 3.0 Preview 2, follow the migrations steps in the ASP.NET Core docs.

Add package for Json.NET

As part of the work to tidy up the ASP.NET Core shared framework, Json.NET is being removed from the shared framework and now needs to be added as a package.

To add back Json.NET support to an ASP.NET Core 3.0 project:

Runtime compilation removed

As a consequence of cleaning up the ASP.NET Core shared framework to not depend on Roslyn, support for runtime compilation of pages and views has also been removed in this preview release. Instead compilation of pages and views is performed at build time. In a future preview update we will provide a NuGet packages for optionally enabling runtime compilation support in an app.

Other breaking changes and announcements

For a full list of other breaking changes and announcements for this release please see the ASP.NET Core Announcements repo.

Build modern web UI with Razor Components

Razor Components are a new way to build interactive client-side web UI with ASP.NET Core. This release of .NET Core 3.0 Preview 2 adds support for Razor Components to ASP.NET Core and for hosting Razor Components on the server. For those of you who have been following along with the experimental Blazor project, Razor Components represent the integration of the Blazor component model into ASP.NET Core along with the server-side Blazor hosting model. ASP.NET Core Razor Components is a new capability in ASP.NET Core to host Razor Components on the server over a real-time connection.

Working with Razor Components

Razor Components are self-contained chunks of user interface (UI), such as a page, dialog, or form. Razor Components are normal .NET classes that define UI rendering logic and client-side event handlers, so you can write rich interactive web apps without having to write any JavaScript. Razor components are typically authored using Razor syntax, a natural blend of HTML and C#. Razor Components are similar to Razor Pages and MVC Views in that they both use Razor. But unlike pages and views, which are built around a request/reply model, components are used specifically for handling UI composition.

To create, build, and run your first ASP.NET Core app with Razor Components run the following from the command line:

dotnet new razorcomponents -o WebApplication1
cd WebApplication1
dotnet run

Or create an ASP.NET Core Razor Components in Visual Studio 2019:

Razor Components template

The generated solution has two projects: a server project (WebApplication1.Server), and a project with client-side web UI logic written using Razor Components (WebApplication1.App). The server project is an ASP.NET Core project setup to host the Razor Components.

Razor Components solution

Why two projects? In part it's to separate the UI logic from the rest of the application. There is also a technical limitation in this preview that we are using the same Razor file extension (.cshtml) for Razor Components that we also use for Razor Pages and Views, but they have different compilation models, so they need to kept separate. In a future preview we plan to introduce a new file extension for Razor Components (.razor) so that you can easily host your components, pages, and views all in the same project.

When you run the app you should see multiple pages (Home, Counter, and Fetch data) on different tabs. On the Counter page you can click a button to increment a counter without any page refresh. Normally this would require writing JavaScript, but here everything is written using Razor Components in C#!

Razor Components app

Here's what the Counter component code looks like:

@page "/counter"

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" onclick="@IncrementCount">Click me</button>

@functions {
    int currentCount = 0;

    void IncrementCount()
    {
        currentCount+=1;
    }
}

Making a request to /counter, as specified by the @page directive at the top, causes the component to render its content. Components render into an in-memory representation of the render tree that can then be used to update the UI in a very flexible and efficient way. Each time the "Click me" button is clicked the onclick event is fired and the IncrementCount method is called. The currentCount gets incremented and the component is rendered again. The runtime compares the newly rendered content with what was rendered previously and only the changes are then applied to the DOM (i.e. the updated count).

You can use components from other components using an HTML-like syntax where component parameters are specified using attributes or child content. For example, you can add a Counter component to the app's home page like this:

@page "/"

<h1>Hello, world!</h1>

Welcome to your new app.

<Counter />

To add a parameter to the Counter component update the @functions block to add a property decorated with the [Parameter] attribute:

@functions {
    int currentCount = 0;

    [Parameter] int IncrementAmount { get; set; } = 1;

    void IncrementCount()
    {
        currentCount+=IncrementAmount;
    }
}

Now you can specify IncrementAmount parameter value using an attribute like this:

<Counter IncrementAmount="10" />

The Home page then has it's own counter that increments by tens:

Count by tens

This is just an intro to what Razor Components are capable of. Razor Components are based on the Blazor component model and they support all of the same features (parameters, child content, templates, lifecycle events, component references, etc.). To learn more about Razor Components check out the component model docs and try out building your first Razor Components app yourself.

Hosting Razor Components

Because Razor Components decouple a component's rendering logic from how the UI updates get applied, there is a lot of flexibility in how Razor Components can be hosted. ASP.NET Core Razor Components in .NET Core 3.0 adds support for hosting Razor Components on the server in an ASP.NET Core app where all UI updates are handled over a SignalR connection. The runtime handles sending UI events from the browser to the server and then applies UI updates sent by the server back to the browser after running the components. The same connection is also used to handle JavaScript interop calls.

ASP.NET Core Razor Components

Alternatively, Blazor is an experimental single page app framework that runs Razor Components directly in the browser using a WebAssembly based .NET runtime. In Blazor apps the UI updates from the Razor Components are all applied in process directly to the DOM.

Blazor

Support for the client-side Blazor hosting model using WebAssembly won't ship with ASP.NET Core 3.0, but we are working towards shipping it with a later release.

Regardless of which hosting model you use for your Razor Components, the component model is the same. The same Razor Components can be used with either hosting model. You can even switch your app back and forth from being a client-side Blazor app or Razor Components running in ASP.NET Core using the same components as long as your components haven't taken any server specific dependencies.

JavaScript interop

Razor Components can also use client-side JavaScript if needed. From a Razor Component you can call into any browser API or into an existing JavaScript library running in the browser. .NET library authors can use JavaScript interop to provide .NET wrappers for JavaScript APIs, so that they can be conveniently called from Razor Components.

public class ExampleJsInterop
{
    public static Task<string> Prompt(this IJSRuntime js, string text)
    {
        // showPrompt is implemented in wwwroot/exampleJsInterop.js
        return js.InvokeAsync<string>("exampleJsFunctions.showPrompt", text);
    }
}
@inject IJSRuntime JS

<button onclick="@OnClick">Show prompt</button>

@functions {
    string name;

    async Task OnClick() {
        name = await JS.Prompt("Hi! What's you're name?");
    }
}

Both Razor Components and Blazor share the same JavaScript interop abstraction, so .NET libraries relying on JavaScript interop are usable by both types of apps. Check out the JavaScript interop docs for more details on using JavaScript interop and the Blazor community page for existing JavaScript interop libraries.

Sharing component libraries

Components can be easily shared and reused just like you would normal .NET classes. Razor Components can be built into component libraries and then shared as NuGet packages. You can find existing component libraries on the Blazor community page.

The .NET Core 3.0 Preview 2 SDK doesn't include a project template for Razor Component Class Libraries yet, but we expect to add one in a future preview. In meantime, you can use Blazor Component Class Library template.

dotnet new -i Microsoft.AspNetCore.Blazor.Templates
dotnet new blazorlib

In this preview release ASP.NET Core Razor Components don't yet support using static assets in component libraries, so the support for component class libraries is pretty limited. However, in a future preview we expect to add this support for using static assets from a library just like you can in Blazor today.

Integration with MVC Views and Razor Pages

Razor Components can be used with your existing Razor Pages and MVC apps. There is no need to rewrite existing views or pages to use Razor Components. Components can be used from within a view or page. When the page or view is rendered, any components used will be prerendered at the same time.

To render a component from a Razor Page or MVC View in this release, use the RenderComponentAsync<TComponent> HTML helper method:

<div id="Counter">
    @(await Html.RenderComponentAsync<Counter>(new { IncrementAmount = 10 }))
</div>

Components rendered from pages and views will be prerendered, but are not yet interactive (i.e. clicking the Counter button doesn't do anything in this release). This will get addressed in a future preview, along with adding support for rendering components from pages and views using the normal element and attribute syntax.

While views and pages can use components the converse is not true: components can't use views and pages specific features, like partial views and sections. If you want to use a logic from partial view in a component you'll need to factor that logic out first as a component.

Cross platform tooling

Visual Studio 2019 comes with built-in editor support for Razor Components including completions and diagnostics in the editor. You don't need to install any additional extensions.

Razor Components tooling

Razor Component tooling isn't available yet in Visual Studio for Mac or Visual Studio Code, but it's something we are actively working on.

A bright future for Blazor

In parallel with the ASP.NET Core 3.0 work, we will continue ship updated experimental releases of Blazor to support hosting Razor Components client-side in the browser (we'll have more to share on the latest Blazor update shortly!). While in ASP.NET Core 3.0 we will only support hosting Razor Components in ASP.NET Core, we are also working towards shipping Blazor and support for running Razor Components in the browser on WebAssembly in a future release.

SignalR client-to-server streaming

With ASP.NET Core SignalR we added Streaming support, which enables streaming return values from server-side methods. This is useful for when fragments of data will come in over a period of time.

With .NET Core 3.0 Preview 2 we've added client-to-server streaming. With client-to-server streaming, your server-side methods can take instances of a ChannelReader<T>. In the C# code sample below, the StartStream method on the Hub will receive a stream of strings from the client.

public async Task StartStream(string streamName, ChannelReader<string> streamContent)
{
    // read from and process stream items
    while (await streamContent.WaitToReadAsync(Context.ConnectionAborted))
    {
        while (streamContent.TryRead(out var content))
        {
            // process content
        }
    }
}

Clients would use the SignalR Subject (or an RxJS Subject) as an argument to the streamContent parameter of the Hub method above.

let subject = new signalR.Subject();
await connection.send("StartStream", "MyAsciiArtStream", subject);

The JavaScript code would then use the subject.next method to handle strings as they are captured and ready to be sent to the server.

subject.next("example");
subject.complete();

Using code like the two snippets above, you can create real-time streaming experiences. For a preview of what you can do with client-side streaming with SignalR, take a look at the demo site, streamr.azurewebsites.net. If you create your own stream, you can stream ASCII art representations of image data being captured by your local web cam to the server, where it will be bounced out to other clients who are watching your stream.

Client-to-server Streaming with SignalR

System.IO.Pipelines on HttpContext

In ASP.NET Core 3.0, we're working on consuming the System.IO.Pipelines API and exposing it in ASP.NET Core to allow you to write more performant applications.

In Preview 2, we're exposing the request body pipe and response body pipe on the HttpContext that you can directly read from and write to respectively in addition to maintaining the existing Stream-based APIs.
While these pipes are currently just wrappers over the existing streams, we will directly expose the underlying pipes in a future preview.

Here's an example that demonstrates using both the request body and response body pipes directly.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseRouting(routes =>
    {
        routes.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Hello World");
        });

        routes.MapPost("/", async context =>
        {
            while (true)
            {
                var result = await context.Request.BodyPipe.ReadAsync();
                var buffer = result.Buffer;

                if (result.IsCompleted)
                {
                    break;
                }

                context.Request.BodyPipe.AdvanceTo(buffer.End);
            }
        });
    });
}

Generic host in templates

The templates have been updated to use the Generic Host instead of WebHostBuilder as they have in the past:

public static void Main(string[] args)
{
    CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

This is part of the ongoing plan started in 2.0 to better integrate ASP.NET Core with other server scenarios that are not web specific.

What about IWebHostBuilder?

The IWebHostBuilder interface that is used with WebHostBuilder today will be kept, and is the type of the webBuilder used in the sample code above. We intend to deprecate and eventually remove WebHostBuilder itself as its functionality will be replaced by HostBuilder, though the interface will remain.

The biggest difference between WebHostBuilder and HostBuilder is that you can no longer inject arbitrary services into your Startup.cs. Instead you will be limited to the IHostingEnvironment and IConfiguration interfaces. This removes a behavior quirk related to injecting services into Startup.cs before the ConfigureServices method is called. We will publish more details on the differences between WebHostBuilder and HostBuilder in a future deep-dive post.

Endpoint routing updates

We're excited to start introducing more of the Endpoint Routing story that began in 2.2. Endpoint routing allows frameworks like MVC as well as other routable things to mix with middleware in a way that hasn't been possible before. This is now present in the project templates in 3.0.0-preview-2, we'll continue to add more richness as we move closer to a final release.

Here's an example:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseStaticFiles();

    app.UseRouting(routes =>
    {
        routes.MapApplication();

        routes.MapGet("/hello", context =>
        {
            return context.Response.WriteAsync("Hi there!");    
        });

        routes.MapHealthChecks("/healthz");
    });

    app.UseAuthentication();
    app.UseAuthorization();
}

There's a few things to unpack here.

First, the UseRouting(...) call adds a new Endpoint Routing middleware. UseRouting is at the core of many of the templates in 3.0 and replaces many of the features that were implemented inside UseMvc(...) in the past.

Also notice that inside UseRouting(...) we're setting up a few things. MapApplication() brings in MVC controllers and pages for routing. MapGet(...) shows how to wire up a request delegate to routing. MapHealthChecks(...) hooks up the health check middleware, but by plugging it into routing.

What might be surprising to see is that some middleware now come after UseRouting. Let's tweak this example to demonstrate why that is valuable.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseStaticFiles();

    app.UseRouting(routes =>
    {
        routes.MapApplication();

        routes.MapGet("/hello", context =>
        {
            return context.Response.WriteAsync("Hi there! Here's your secret message");    
        })
        .RequireAuthorization(new AuthorizeAttribute(){ Roles = "secret-messages", });

        routes.MapHealthChecks("/healthz").RequireAuthorization("admin");
    });

    app.UseAuthentication();
    app.UseAuthorization();
}

Now I've added an AuthorizeAttribute to my request delegate. This is just like placing [Authorize(Roles = "secret-messages")] on an action method in a controller. We've also given the health checks middleware an authorization policy as well (by policy name).

This works because the following steps happen in order (ignoring what happens before routing):

  1. UseRouting(...) makes a routing decision – selecting an Endpoint
  2. UseAuthorization() looks at the Endpoint that was selected and runs the corresponding authorization policy
  3. hidden… At the end of the middleware pipeline the Endpoint is executed (if no endpoint was matched then a 404 response is returned)

So think of UseRouting(...) as making a deferred routing decision – where middleware that appear after it run in the middle. Any middleware that run after routing can see the results and read or modify the route data and chosen endpoint. When processing reaches the end of the pipeline, then the endpoint is invoked.

What is an Endpoint and why did we add this?

An Endpoint is a new primitive to help frameworks (like MVC) be friends with middleware. Fundamentally an Endpoint is a request delegate (something that can execute) plus a bag of metadata (policies).

Here's an example middleware – you can use this to examine endpoints in the debugger or by printing to the console:

app.Use(next => (context) =>
{
    var endpoint = context.GetEndpoint();
    if (endpoint != null)
    {
        Console.WriteLine("Name: " + endpoint.DisplayName);
        Console.WriteLine("Route: " + (endpoint as RouteEndpoint)?.RoutePattern);
        Console.WriteLine("Metadata: " + string.Join(", ", endpoint.Metadata));
    }

    return next(context);
});

In the past we haven't had a good solution when we've wanted to implement a policy like CORS or Authorization in both middleware and MVC. Putting a middleware in the pipeline feels very good because you get to configure the order. Putting filters and attributes on methods in controllers feels really good when you need to apply policies to different parts of the application. Endpoints bring togther all of these advantages.

As an addition problem – what do you do if you're writing the health checks middleware? You might want to secure your middleware in a way that developers can customize. Being able to leverage the ASP.NET Core features for this directly avoids the need to build in support for cross-cutting concerns in every component that serves HTTP.

In addition to removing code duplication from MVC, the Endpoint + Middleware solution can be used by any other ASP.NET Core-based technologies. You don't even need to use UseRouting(...) – all that is required to leverage the enhancements to middleware is to set an Endpoint on the HttpContext.

What's integrated with this?

We added the new authorize middleware so that you can start doing more powerful security things with just middleware. The authorize middleware can accept a default policy that applies when there's no endpoint, or the endpoint doesn't specify a policy.

CORS is also now endpoint routing aware and will use the CORS policy specified on an endpoint.

MVC also plugs in to endpoint routing and will create endpoints for all of your controllers and pages. MVC can now be used with the CORS and authorize features and will largely work the same. We've long had confusion about whether to use the CORS middleware or CORS filters in MVC, the updated guidance is to use both. This allows you to provide CORS support to other middleware or static files, while still applying more granular CORS policies with the existing attributes.

Health checks also provide methods to register the health checks middleware as a router-ware (as shown above). This allows you to specify other kinds of policies for health checks.

Finally, new in ASP.NET Core 3.0 preview 2 is host matching for routes. Placing the HostAttribute on an MVC controller or action will prompt the routing system to require the specified domain or port. Or you can use RequireHost in your Startup.cs:

app.UseRouting(routes =>
{
    routes.MapGet("/", context => context.Response.WriteAsync("Hi Contoso!"))
        .RequireHost("contoso.com");

    routes.MapGet("/", context => context.Response.WriteAsync("Hi AdventureWorks!"))
        .RequireHost("adventure-works.com");

    routes.MapHealthChecks("/healthz").RequireHost("*:8080");
});

Do you think that there are things that are missing from the endpoint story? Are there more things we should make smarter or more integrated? Please let us know what you'd like to see.

Give feedback

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 Github.

Make the most of your monthly Azure Credits

$
0
0

If you weren’t aware, Visual Studio subscribers have free monthly Azure credits, that are ideal for experimenting with and learning about Azure services. When you activate this benefit, it creates a separate Azure subscription with a monthly credit balance that renews each month while you remain an active Visual Studio subscriber. If the credits run out before the end of the month the subscription is suspended until more credits are available. No surprises, no cost, and no credit card required for any of it!

The table below shows you how many Azure credits you get based on your type of Visual Studio subscription:

Visual Studio subscription type Monthly Azure Credits Activate Credits
Visual Studio Professional (standard subscription) $50 activate
Visual Studio Test Professional $50 activate
MSDN Platforms $100 activate
Visual Studio Enterprise (standard subscription) $150 activate
Visual Studio Enterprise (BizSpark) $150 activate
Visual Studio Enterprise (MPN) $150 activate

Now that you know how many Azure Credits you get every month for free, you are probably wondering what you can spend it on! We have put together the following simple table to help you get going:

Azure Service Tier Estimated Monthly Cost
App Service Shared $9.49
Storage General Purpose V2 (1GB) $1.06
SQL Single DB (5DTUs, 2GB) $4.90
CosmosDB 1GB $23.61
Functions Dynamic First 10k executions free
Monitor Application Insights First 1GB free
Key Vault Standard $0.03 (per 10k operations)
Service Bus Basic $0.05 (per 1M operations)
Redis Basic (C0: 250MB Cache) $16.06

Hopefully, you found this information helpful and you are on your way to make use of your Azure credits. If you are interested in the cost of an Azure service you didn’t see in the table above, try the Azure price calculator. If you have any questions or problems just leave us a comment below.

Blazor 0.8.0 experimental release now available

$
0
0

Blazor 0.8.0 is now available! This release updates Blazor to use Razor Components in .NET Core 3.0 and adds some critical bug fixes.

Get Blazor 0.8.0

To get started with Blazor 0.8.0 install the following:

  1. .NET Core 3.0 Preview 2 SDK (3.0.100-preview-010184)
  2. Visual Studio 2019 (Preview 2 or later) with the ASP.NET and web development workload selected.
  3. The latest Blazor extension from the Visual Studio Marketplace.
  4. The Blazor templates on the command-line:

    dotnet new -i Microsoft.AspNetCore.Blazor.Templates::0.8.0-preview-19104-04
    

You can find getting started instructions, docs, and tutorials for Blazor at https://blazor.net.

Upgrade to Blazor 0.8.0

To upgrade your existing Blazor apps to Blazor 0.8.0 first make sure you've installed the prerequisites listed above.

To upgrade a standalone Blazor 0.7.0 project to 0.8.0:

  • Update the Blazor packages and .NET CLI tool references to 0.8.0-preview-19104-04.
  • Replace any package reference to Microsoft.AspNetCore.Blazor.Browser with a reference to Microsoft.AspNetCore.Blazor.
  • Replace BlazorComponent with ComponentBase.
  • Update overrides of SetParameters on components to override SetParametersAsync instead.
  • Replace BlazorLayoutComponent with LayoutComponentBase
  • Replace IBlazorApplicationBuilder with IComponentsApplicationBuilder.
  • Replace any using statements for Microsoft.AspNetCore.Blazor.* with Microsoft.AspNetCore.Components.*, except leave Microsoft.AspNetCore.Blazor.Hosting in Program.cs
  • In index.html update the script reference to reference components.webassembly.js instead of blazor.webassembly.js

To upgrade an ASP.NET Core hosted Blazor app to 0.8.0:

  • Update the client-side Blazor project as described previously.
  • Update the ASP.NET Core app hosting the Blazor app to .NET Core 3.0 by following the migrations steps in the ASP.NET Core docs.
    • Update the target framework to be netcoreapp3.0
    • Remove any package reference to Microsoft.AspNetCore.App or Microsoft.AspNetCore.All
    • Upgrade any non-Blazor Microsoft.AspNetCore.* package references to version 3.0.0-preview-19075-0444
    • Remove any package reference to Microsoft.AspNetCore.Razor.Design
    • To enable JSON support, add a package reference to Microsoft.AspNetCore.Mvc.NewtonsoftJson and updateStartup.ConfigureServices to call services.AddMvc().AddNewtonsoftJson()
  • Upgrade the Microsoft.AspNetCore.Blazor.Server package reference to 0.8.0-preview-19104-04
  • Add a package reference to Microsoft.AspNetCore.Components.Server
  • In Startup.ConfigureServices simplify any call to app.AddResponseCompression to call the default overload without specifying WebAssembly or binary data as additional MIME types to compress.
  • In Startup.Configure add a call to app.UseBlazorDebugging() after the existing call to app.UseBlazor<App.Startup>()
  • Remove any unnecessary use of the Microsoft.AspNetCore.Blazor.Server namespace.

To upgrade a Blazor class library to 0.8.0:

  • Replace the package references to Microsoft.AspNetCore.Blazor.Browser and Microsoft.AspNetCore.Blazor.Build with references to Microsoft.AspNetCore.Components.Browser and Microsoft.AspNetCore.Components.Build and update the versions to 3.0.0-preview-19075-0444.

Server-side Blazor is now ASP.NET Core Razor Components in .NET Core 3.0

As was recently announced, server-side Blazor is now shipping as ASP.NET Core Razor Components in .NET Core 3.0. We've integrated the Blazor component model into ASP.NET Core 3.0 and renamed it to Razor Components. Blazor 0.8.0 is now built on Razor Components and enables you to host Razor Components in the browser on WebAssembly.

Upgrade a server-side Blazor project to ASP.NET Core Razor Components in .NET Core 3.0

If you've been working with server-side Blazor, we recommend upgrading to use ASP.NET Core Razor Components in .NET Core 3.0.

To upgrade a server-side Blazor app to ASP.NET Core Razor Components:

  • Update the client-side Blazor project as described previously, except replace the script reference to blazor.server.js with components.server.js
  • Update the ASP.NET Core app hosting the Razor Components to .NET Core 3.0 as described previously.
  • In the server project:
    • Upgrade the Microsoft.AspNetCore.Blazor.Server package reference to 0.8.0-preview-19104-04
    • Add a package reference to Microsoft.AspNetCore.Components.Server version 3.0.0-preview-19075-0444
    • Replace the using statement for Microsoft.AspNetCore.Blazor.Server with Microsoft.AspNetCore.Components.Server
    • Replace services.AddServerSideBlazor with services.AddRazorComponents and app.UseServerSideBlazor with app.UseRazorComponents.
    • In the Startup.Configure method add app.UseStaticFiles() just prior to calling app.UseRazorComponents.
    • Move the wwwroot folder from the Blazor app project to the ASP.NET Core server project

Switching between ASP.NET Core Razor Components and client-side Blazor

Sometimes it's convenient to be able to switch between running your Razor Components on the server (ASP.NET Core Razor Components) and on the client (Blazor). For example, you might run on the server during development so that you can easily debug, but then publish your app to run on the client.

To update an ASP.NET Core hosted Blazor app so that it can be run as an ASP.NET Core Razor Components app:

  • Move the wwwroot folder from the client-side Blazor project to the ASP.NET Core server project.
  • In the server project:
    • Update the script tag in index.html to point to components.server.js instead of components.webassembly.js.
    • Add a call to services.AddRazorComponents<Client.Startup>() in the Startup.ConfigureServices method.
    • Add a call to app.UseStaticFiles() in the Startup.Configure method prior to the call to UseMvc.
    • Replace the call to UseBlazor with app.UseRazorComponents<Client.Startup>()
  • If you're using dependency injection to inject an HttpClient into your components, then you'll need to add an HttpClient as a service in your server's Startup.ConfigureServices method.

Tooling for Blazor projects is now included with Visual Studio 2019

Previously to get tooling support for Blazor projects you needed to install the Blazor extension for Visual Studio. Starting with Visual Studio 2019 Preview 2, tooling support for Razor Components (and hence Blazor apps) is already included without having to install anything else. The Blazor extension is now only needed to install the Blazor project templates in Visual Studio.

Runtime improvements

Blazor 0.8.0 includes some .NET runtime improvements like improved runtime performance on Chrome and an improved IL linker. In our performance benchmarks, Blazor 0.8.0 performance on Chrome is now about 25% faster. You can now also reference existing libraries like Json.NET from a Blazor app without any additional linker configuration:

@functions {
    WeatherForecast[] forecasts;

    protected override async Task OnInitAsync()
    {
        var json = await Http.GetStringAsync("api/SampleData/WeatherForecasts");
        forecasts = Newtonsoft.Json.JsonConvert.DeserializeObject<WeatherForecast[]>(json);
    }
}

Known issues

There are a couple of known issues with this release that you may run into:

  • "It was not possible to find any compatible framework version. The specified framework 'Microsoft.NETCore.App', version '2.0.0' was not found.": You may see this error when building a Blazor app because the IL linker currently requires .NET Core 2.x to run. To work around this issue, either install .NET Core 2.2 or disable IL linking by setting the <BlazorLinkOnBuild>false</BlazorLinkOnBuild> property in your project file.
  • "Unable to generate deps.json, it may have been already generated.": You may see this error when running a standalone Blazor app and you haven't yet restored packages for any .NET Core apps. To workaround this issue create any .NET Core app (ex dotnet new console) and then rerun the Blazor app.

These issues will be addressed in a future Blazor update.

Future updates

This release of Blazor was primarily focused on first integrating Razor Components into ASP.NET Core 3.0 and then rebuilding Blazor on top of that. Going forward, we plan to ship Blazor updates with each .NET Core 3.0 update.

Blazor, and support for running Razor Components on WebAssembly in the browser, won't ship with .NET Core 3.0, but we continue to work towards shipping Blazor some later date.

Give feedback

We hope you enjoy this latest preview release of Blazor. As with previous releases, your feedback is important to us. If you run into issues or have questions while trying out Blazor, file issues on GitHub. You can also chat with us and the Blazor community on Gitter if you get stuck or to share how Blazor is working for you. After you've tried out Blazor for a while please let us know what you think by taking our in-product survey. Click the survey link shown on the app home page when running one of the Blazor project templates:

Blazor survey

Thanks for trying out Blazor!

Viewing all 7144 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>