Posted on Leave a comment

Use Hybrid Connections to Incrementally Migrate Applications to the Cloud

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.

Posted on Leave a comment

Blazor 0.6.0 experimental release now available

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!

Posted on Leave a comment

SKIP Programming Language Released By Facebook

SKIP, previously known as Reflex, is a general purpose programming language developed as a research project at Facebook over the last 3 years.  Facebook have finished development and authorized the language lead developer to release the project as open source.  SKIP is available on Github under the MIT source license.

The leader developer made the following Tweet announcing the release today:

image

You can learn more about the language at http://skiplang.com/.  The language can be downloaded as a Docker image, with full installation instructions available here.  There is also a web based playground application for trying out SKIP on the website.  SKIP is described as:

Skip is a general-purpose programming language that tracks side effects to provide caching with reactive invalidation, ergonomic and safe parallelism, and efficient garbage collection. Skip is statically typed and ahead-of-time compiled using LLVM to produce highly optimized executables.

[embedded content]

Programming News


Posted on Leave a comment

ASP.NET Core 2.2.0-preview2 now available

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!

Posted on Leave a comment

Library Manager Released in 15.8

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

Posted on Leave a comment

ASP.NET Core 2.2.0-preview1: Endpoint Routing

What is it?

We’re making a big investment in routing starting in 2.2 to make it interoperate more seamlessly with middleware. For 2.2 this will start with us making a few changes to the routing model, and adding some minor features. In 3.0 the plan is to introduce a model where routing and middleware operate together naturally. This post will focus on the 2.2 improvements, we’ll discuss 3.0 a bit further in the future.

So, without further ado, here are some changes coming to routing in 2.2.

How to use it?

The new routing features will be on by default for 2.2 applications using MVC. UseMvc and related methods with the 2.2 compatibility version will enable the new ‘Endpoint Routing’ feature set. Existing conventional routes (using MapRoute) or attribute routes will be mapped into the new system.

public void ConfigureServices(IServiceProvider services)
{
 ...
 
 services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

public void Configure(IApplicationBuilder app)
{
 ....
 
 app.UseMvc();
}

If you need to specifically revert the new routing features, this can be done by setting an option. We’ve tried to make the new endpoint routing system as backwards compatible as is feasible. Please log issues at https://github.com/aspnet/Routing if you encounter problems.

We don’t plan to provide an experience in 2.2 for using the new features without MVC – our focus for right now is to make sure we can successfully shift MVC applications to the new infrastructure.

Link Generator Service

We’re introducing a new singleton service that will support generating a URL. This new service can be used from middleware, and does not require an HttpContext. For right now the set of things you can link to is limited to MVC actions, but this will expand in 3.0.

public class MyMiddleware
{
 public MyMiddleware(RequestDelegate next, LinkGenerator linkGenerator) { ... }
 
 public async Task Invoke(HttpContext httpContext)
 {
 var url = _linkGenerator.GenerateLink(new { controller = "Store",
 action = "ListProducts" });
 
 httpContext.Response.ContentType = "text/plain";
 return httpContext.Response.WriteAsync($"Go to {url} to see some cool stuff.");
 }
}

This looks a lot like MVC’s link generation support (IUrlHelper) for now — but it’s usable anywhere in your application. We plan to expand the set of things that are possible during 2.2.

Performance Improvements

One of the biggest reasons for us to revisit routing in 2.2 is to improve the performance of routing and MVC’s action selection.

We still have more work to, but the results so far are promising:
image

This chart shows the trend of Requests per Second (RPS) of our MVC implementation of the TechEmpower plaintext benchmark. We’ve improved the RPS of this benchmark about 10% from 445kRPS to 515kRPS.

To test more involved scenarios, we’ve used the Swagger/OpenAPI files published by Azure and Github to build code-generated routing benchmarks. The Azure API benchmark has 5160 distinct HTTP endpoints, and the Github benchmark has 243. The new routing system is significantly faster at processing the route table of these real world APIs than anything we’ve had before. In particular MVC’s features that select actions such as matching on HTTP methods and [Consumes(...)] are significantly less costly.

Improvements to link generation behavior for attribute routing

We’re also using this opportunity to revisit some of the behaviors that users find confusing when using attribute routing. Razor Pages is based on MVC’s attribute routing infrastructure and so many new users have become familiar with these problems lately. Inside the team, we refer to this feature as ‘route value invalidation’.

Without getting into too many details, conventional routing always invalidates extra route values when linking to another action. Attribute routing didn’t have this behavior in the past. This can lead to mistakes when linking to another action that uses the same route parameter names. Now both forms of routing invalidate values when linking to another action.

A conceptual understanding

The new routing system is called ‘Endpoint Routing’ because it represents the route table as a set of Endpoints that can be selected by the the routing system. If you’ve ever thought about how attribute routing might work in MVC, the above description should not be surprising. The new part is that a bunch of concerns traditionally handled by MVC have been pushed down to a very low level of the routing system. Endpoint routing now processes HTTP methods, [Consumes(...)], versioning, and other policies that used to be part of MVC’s action selection process.

In contrast to this, the existing routing system models the application is a list of ‘Routes’ that need to be processed in order. What each route does is a black-box to the routing system – you have to run the route to see if it will match.

To make MVC’s conventional routing work, we flatten the list of actions multiplied by the number of routes into a list of endpoints. This flattening allows us to process all of MVC’s requirements very efficiently inside the routing system.


The list of endpoints gets compiled into a tree that’s easy for us to walk efficiently. This is similar to what attribute routing does today but using a different algorithm and much lower complexity. Since routing builds a graph based on the endpoints, this means that the complexity of the tree scales very directly with your usage of features. We’re confident that we can scale up this design nicely while retaining the pay-for-play characteristics.

New round-tripping route parameter syntax

We are introducing a new catch-all parameter syntax {**myparametername}. During link generation, the routing system will encode all the content in the value captured by this parameter except the forward slashes.
Note that the old parameter syntax {*myparametername} will continue to work as it did before. Examples:

  • For a route defined using the old parameter syntax : /search/{*page},
    a call to Url.Action(new { category = "admin/products" }) would generate a link /search/admin%2Fproducts (notice that the forward slash is encoded)
  • For a route defined using the new parameter syntax : /search/{**page},
    a call to Url.Action(new { category = "admin/products" }) would generate a link /search/admin/products

What is coming next?

Expect more refinement and polish on the LinkGenerator API in the next preview. We want to make sure that this new API will support a variety of scenarios for the foreseeable future.

How can you help?

There are a few areas where you can provide useful feedback during this preview. We’re interested in any thoughts you have of course, these are a few specific things we’d like opinions on. The best place to provide feedback is by opening issues at https://github.com/aspnet/Routing

What are you using IRouter for? The ‘Endpoint Routing’ system doesn’t support IRouter-based extensibility, including inheriting from Route. We want what you’re using IRouter for today so we can figure out how to accomplish those things in the future.

What are you using IActionConstraint for? ‘Endpoint Routing’ supports IActionConstraint-based extensibility from MVC, but we’re trying to find better ways to accomplish these tasks.

What are your ‘most wanted’ issues from Routing? We’ve revisited a bunch of old closed bugs and brought back a few for reconsideration. If you feel like there are missing details or bugs in routing that we should consider please let us know.

Caveats and notes

We’ve worked to make the new routing system backwards compatible where possible. If you run into issues we’d love for you to report them at https://github.com/aspnet/Routing.

DataTokens are not supported in 2.2.0-preview1. We plan to address this for the next preview.

By nature the new routing system does not support IRouter based extensibility.

Generating links inside MVC to conventionally routed actions that don’t yet exist will fail (resulting in the empty string). This is in contrast to the current MVC behavior where linking usually succeeds even if the action being linked hasn’t been defined yet.

We know that the performance of link generation will be bad in 2.2.0-preview1. We worked hard to get the API definitions in so that you could try it out, and ignored performance. Expect the performance of URL generation to improve significantly for the next preview.

Endpoint routing does not support WebApiCompatShim. You must use the 2.1 compatibility switch to continue using the compat shim.

Posted on Leave a comment

ASP.NET Core 2.20-preview1: Open API Analyzers & Conventions

What is it?

Open API (alternatively known as Swagger) is a language-agnostic specification for describing REST APIs. The Open API ecosystem has tools that allows for discovering, testing and producing client code using the specification. Support for generating and visualizing Open API documents in ASP.NET Core MVC is provided via community driven projects such as NSwag, and Swashbuckle.AspNetCore. Visit https://docs.microsoft.com/en-us/aspnet/core/tutorials/web-api-help-pages-using-swagger?view=aspnetcore-2.1 to learn more about Open API Swagger and for details on configuring your applications to use it.

For 2.2, we’re investing in tooling and runtime experiences to to allow developers to produce better Open API documents. This work ties in with ongoing work to perform client code SDK generation during build.

How to use it?

Analyzer

For 2.2, we’re introducing a new API-specific analyzers NuGet package – Microsoft.AspNetCore.Mvc.Api.Analyzers. These analyzers work with controllers annotated with ApiController introduced in 2.1, while building on API conventions that we’re also introducing in this release. To start using this, install the package:


<PackageReference Include="Microsoft.AspNetCore.Mvc.Api.Analyzers"
 Version="2.2.0-preview1-35029"
 PrivateAssets="All" />

Open API documents contain each status code and response type an operation may return. In MVC, you use attributes such as ProducesResponseType and Produces to document these. The analyzer inspects controllers annotated with ApiController and identifies actions that do not entirely document their responses. You should see this as warnings (squiggly lines) highlighting return types that aren’t documented as well as warnings in the output. In Visual Studio, this should additionally appear under the “Warnings” tab in the “Error List” dialog. You now have the opportunity to address these warnings using code fixes.

Let’s look at the analyzer in action:

The analyzer identified that the action returned a 404 but did not document it using a ProducesResponseTypeAttribute. We used a code fix to document this. The added attributes would now become available for Swagger / Open API tools to consume. It’s a great way to identify areas of your application that are lacking swagger documentation and correct it.

Conventions

If your controllers follows some common patterns, e.g. they are all primarily CRUD endpoints, and you aren’t already using ProducesResponseType or Produces to document them, you could consider using API conventions. Conventions let you define the most common “conventional” return types and status codes that you return from your action, and apply them to individual actions or controllers, or all controllers in an assembly. Conventions are a substitute to decorating individual actions with ProducesResponseType attributes.

By default, ASP.NET Core MVC 2.2 ships with a set of default conventions – DefaultApiConventions – that’s based on the controller that ASP.NET Core scaffolds. If your actions follow the pattern that scaffolding produces, you should be successful using the default conventions.

At runtime, ApiExplorer understand conventions. ApiExplorer is MVC’s abstraction to communicate with Open API document generators. Attributes from the applied convention get associated with an action and will be included in action’s Swagger documentation. API analyzers also understand conventions. If your action is unconventional i.e. it returns a status code that is not documented by the applied convention, it will produce a warning, encouraging you to document it.

There are 3 ways to apply a convention to a controller action:

  • Applying the ApiConventionType attribute as an assembly level attribute. This applies the specified convention to all controllers in an assembly.
[assembly: ApiConvention(typeof(DefaultApiConventions))]
  • Using the ApiConventionType attribute on a controller.
[ApiConvention(typeof(DefaultApiConventions))]
[ApiController]
[Route("/api/[controller]")]
public class PetsController : ControllerBase
{
 ...
}
  • Using ApiConventionMethod. This attributes accepts both the type and the convention method.
// PUT: api/Pets/5
[ApiConventionMethod(typeof(DefaultApiConventions), nameof(DefaultApiConventions.Put))]
[HttpPut("{id}")]
public async Task<ActionResult<Pet>> PutPet(long id, Pet pet)
{
 ...
}

Like many other features in MVC, more specific attributes will supersede less specific ones. An API metadata attribute such as ProducesResponseType or Produces applied to an action will stop applying any convention atributes. The ApiConventionMethod will supersede a ApiConventionType attribute applied to the method’s controller or the assembly; and an ApiConventionType attribute applied to a controller will supersede ones applied to the assembly.

Authoring conventions

A convention is a static type with methods. These methods are annotated with ProducesResponseType or ProducesDefaultResponseType attributes.

public static class MyAppConventions
{
 [ProducesResponseType(200)]
 [ProducesResponseType(404)]
 public static void Find(int id)
 {

 }
}

Applying this convention to an assembly would result in the convention method applying to any action with the name Find and having exactly one parameter named id, as long as they do not have other more specific metadata attributes.

In addition to ProducesResponseType and ProducesDefaultResponseType, two additional attributes – ApiConventionNameMatch and ApiConventionTypeMatch – can be applied to the convention method that determines the methods they apply to.

[ProducesResponseType(200)]
[ProducesResponseType(404)]
[ApiConventionNameMatch(ApiConventionNameMatchBehavior.Prefix)]
public static void Find(
 [ApiConventionNameMatch(ApiConventionNameMatchBehavior.Suffix)]
 int id)
{ }

The ApiConventionNameMatchBehavior.Prefix applied to the method, indicates that the convention can match any action as long as it starts with the prefix “Find”. This will include methods such as Find, FindPet or FindById. The ApiConventionNameMatchBehavior.Suffix applied to the parameter, indicates that the convention can match methods with exactly one parameter that terminate in the suffix id. This will include parameters such as id, or petId. ApiConventionTypeMatch can be similarly applied to types to constrain the type of the parameter. A params[] arguments can be used to indicate remaining parameters that do not need not be explicitly matched.

An easy way to get started authoring a custom convention is to start by copying the body of DefaultApiConventions and modifying it. Here’s a link to the source of the type: https://raw.githubusercontent.com/aspnet/Mvc/release/2.2/src/Microsoft.AspNetCore.Mvc.Core/DefaultApiConventions.cs

Feedback

This is one on our earliest forays in trying to use tooling to enhance runtime experiences. We’re interested in any thoughts you have about this as well as your experiences using this in your applications. The best place to provide feedback is by opening issues at https://github.com/aspnet/Mvc.

Additional help

Posted on Leave a comment

LibMan CLI Released

The Command Line Interface (CLI) is now available for Microsoft Library Manager (LibMan) and can be downloaded via NuGet. Look for Microsoft.Web.LibraryManager.Cli
The LibMan CLI is cross-platform, so you’ll be able to use it anywhere that .NET Core is supported (Windows, Mac, Linux).

Install the LibMan CLI

To install LibMan, type:

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

Once the LibMan CLI is installed, you can start using LibMan from the root of your web project (or any folder).

Using LibMan from the Command Line

When using LibMan CLI, begin commands with “libman” then follow with the action you wish to invoke.
For example, to install all files from the latest version of jquery, type:

> libman install jquery

Follow the prompts to select the provider and destination. Type the values you want, or press [Enter] to accept the defaults.

The install operation creates a libman.json file in the current directory if one does not already exist, then adds the new library configuration. It then downloads the files and places them in the destination folder. See the example below.

LibMan CLI example

To learn more about the LibMan CLI, refer to the LibMan CLI documentation on the Library Manager Wiki.

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

Posted on Leave a comment

Improvements in Visual Studio 2017 15.8 for web developers

This week we released Visual Studio 2017 version 15.8. Our 15.8 update brings the following improvements for web developers:

  • Custom docker image tags during Publish
  • Zip push deployment for Azure Functions
  • Managing user secrets in ASP.NET Framework projects (targeting .NET 4.7.1 or higher)
  • Enabling Application Insights as part of publishing to Azure App Service
  • Optimizing build performance for solutions containing ASP.NET Framework projects
  • Author and source information for ASP.NET Core templates

Custom docker image tags during Publish

You can now customize the “Image tag” for Docker containers when publishing them to a container registry. The value can either be automatically generated by Visual Studio every time you publish (the previous behavior), or it be manually changed if you need a consistent tag (e.g. “latest”):

Screenshot of new property called "Image Tag" in Publish

Zip push deployment & run from zip for Azure Functions

Visual Studio now provides the option to deploy and run Azure Functions projects as zip files:

Screenshot of publish and run from zip option in Publish

Run-From-Zip is a runtime feature that allows ‘mounting’ a zip file and running directly from it. Your App runs directly over the ‘mounted’ zip file, which completely takes over your wwwrootfolder (which becomes read-only).  Using run from Zip offers the following benefits:

  • Atomicity: when your application is deployed as as single unit, and updated as a single unit meaning publishing an update will never leave your app in a partially updated state
  • Faster deployment of large applications
  • Improved cold start performance

Managing user secrets in ASP.NET Framework projects (targeting .NET 4.7.1 or higher)

A feature that ASP.NET Framework projects were missing compared to ASP.NET Core was support for storing application secrets (e.g. connection strings, API keys, etc.) in a file outside of source control unique to each user. Now, with .NET Framework 4.7.1 and Visual Studio 15.8 it’s as simple as right clicking on the project in Solution Explorer and selecting “Manage User Secrets”:

Screenshot of the new "Manage user secrets" menu item when right clicking in Solution Explorer

Visual Studio will take care of the rest including downloading the necessary NuGet packages, updating the web.config file, creating the secrets file on disk and finally opening it for you to edit:

Screenshot of an example user secrets file

Note: Only available for projects targeting .NET Framework 4.7.1 or higher, if you can’t see the menu item make sure you have the 4.7.1 targeting pack installed and that the project is actually targeting 4.7.1, you can change it from project properties:

Screenshot of the run time drop-down available in project properties

Enabling Application Insights as part of publishing to Azure App Service

When publishing to Azure App Service, Visual Studio asks you to either create a new App Service or re-use an existing one. If you choose to create a new App Service to host your application, Visual Studio now offers you the ability to also provision and configure Application Insights:

Screenshot of new drop-down related to Application Insights when creating a new App Service

All you need to do is pick the region you would like Application Insights to be provisioned in and Visual Studio will make sure it’s configured to pick up telemetry events and metrics from the new App Service. If you wish to add custom events and metrics follow this guide. Of course, you can always set the field to “None” and Visual Studio will not provision nor configure Application Insights on your behalf.

Optimizing build performance for solutions containing ASP.NET Framework projects

We added a new menu item under Build | ASP.NET Compilation | Optimize Build Performance for Solution:

Screenshot of new menu item Build | ASP.NET Compilation | Optimize Build Performance for Solution

This new menu item is applicable to solutions containing ASP.NET Framework projects only and is not applicable to ASP.NET Core projects. Its purpose is to update specific ASP.NET related NuGet packages referenced by the codebase.

When an ASP.NET Framework codebase is using out-of-date packages, the inner loop performance of Visual Studio is impacted. The motivation behind updating these packages is to restore optimal inner loop performance for a given solution.  You will only have to do this once per solution and you will not have to deal with this problem in the future since the new package is designed in a way that even when it gets out of date it doesn’t affect the inner loop performance in Visual Studio.

Author and source information for ASP.NET Core templates

The dialog for new ASP.NET Core projects now shows you the author and source for the selected template:

Screenshot of author and source information available in the New Project Dialog

  • If the template is coming from a .NET Core SDK installed on the machine, the dialog will now display the version of the SDK as the source
  • If the template is coming from a VSIX (i.e. Visual Studio extension) installed on the machine, the dialog will now display the name of the VSIX as the source

Conclusion

If you’re interested in the many other great things that Visual Studio 2017 15.8 brings, check out our Visual Studio 15.8 post on the Visual Studio blog.

We hope that you’ll give 15.8 a try and let us know how it works for you. If you run into any issues please report them using Visual Studio, or let us know what you think below, or via Twitter.

Posted on Leave a comment

Rust for Game Development

C++ has had a long run as the primary programming language for games, after taking the crown from C and ASM well over a decade back.  In recent years more and more developers are moving towards more productivity oriented languages such as C#.  What about developers that want to have the fine level of control of memory and low level access C++ provides, but want to get away from the complexity and cruft C++ has accumulated over the last 30+ years?  That is the niche the Rust programming language hopes to fill.  Rust is a systems programming language originally sponsored by Mozilla for use on the Firefox browser.  Game developers have long been interested in Rust, but last week one rather large game developer became the first to adopt the Rust programming language.

Last week, Ready at Dawn CTO Andrea Pessino released the following tweet:

image

Ready at Dawn is a well established game studio known for games such as The Order: 1886, Daxter and various God of War titles.  This tweet launched a far bit of interest in Rust, so I decided to start doing some research into the Rust echo system, a look at game engines and libraries available then promptly stopped…

Because this site, AreWeGameYet already did an excellent job of exactly what I was setting out to accomplish!  So there… if you are interested in checking out Rust for game development, be sure to start there.  Additionally if you are interested in learning a bit more about the state of Rust game development, as well as a quick tutorial on getting a Rust development environment up and running on Windows using Visual Studio Code using the Piston game engine, be sure to check out this video!

[embedded content]

Programming