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


Posted on Leave a comment

Blazor 0.5.0 experimental release now available

Blazor 0.5.0 is now available! This release explores scenarios where Blazor is run in a separate process from the rendering process. Specifically, Blazor 0.5.0 enables the option to run Blazor on the server and then handle all UI interactions over a SignalR connection. This release also adds some very early support for debugging your Blazor .NET code in the browser!

New features in this release:

  • Server-side Blazor
  • Startup model aligned with ASP.NET Core
  • JavaScript interop improvements
    • Removed requirement to preregister JavaScript methods
    • Invoke .NET instance method from JavaScript
    • Pass .NET objects to JavaScript by reference
  • Add Blazor to any HTML file using a normal script tag
  • Render raw HTML
  • New component parameter snippet
  • Early support for in-browser debugging

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

Get Blazor 0.5.0

To get setup with Blazor 0.5.0:

  1. Install the .NET Core 2.1 SDK (2.1.300 or later).
  2. Install Visual Studio 2017 (15.7 or later) with the ASP.NET and web development workload selected.
  3. Install the latest Blazor Language Services extension from the Visual Studio Marketplace.
  4. Install 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.5.0

To upgrade an existing Blazor project from 0.4.0 to 0.5.0:

  • Install all of the required bits listed above.
  • Update your Blazor package and .NET CLI tool references to 0.5.0. Your 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.5.0" />
 <PackageReference Include="Microsoft.AspNetCore.Blazor.Build" Version="0.5.0" />
 <DotNetCliToolReference Include="Microsoft.AspNetCore.Blazor.Cli" Version="0.5.0" />
    </ItemGroup>
    
    </Project>
    
  • Update index.html to replace the blazor-boot script tag with a normal script tag that references _framework/blazor.webassembly.js..

    index.html

    <!DOCTYPE html>
    <html>
    <head>
 <meta charset="utf-8" />
 <meta name="viewport" content="width=device-width">
 <title>BlazorApp1</title>
 <base href="/" />
 <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
 <link href="css/site.css" rel="stylesheet" />
    </head>
    <body>
 <app>Loading...</app> 
 <script src="_framework/blazor.webassembly.js"></script>
    </body>
    </html>
    
  • Add a Startup class to your project and update Program.cs to setup the Blazor host.

    Program.cs

    @using using Microsoft.AspNetCore.Blazor.Hosting;
    
    public class Program
    {
 public static void Main(string[] args)
 {
 CreateHostBuilder(args).Build().Run();
 }
    
 public static IWebAssemblyHostBuilder CreateHostBuilder(string[] args) =>
 BlazorWebAssemblyHost.CreateDefaultBuilder()
 .UseBlazorStartup<Startup>();
    }
    

    Startup.cs

    using Microsoft.AspNetCore.Blazor.Builder;
    using Microsoft.Extensions.DependencyInjection;
    
    public class Startup
    {
 public void ConfigureServices(IServiceCollection services)
 {
 }
    
 public void Configure(IBlazorApplicationBuilder app)
 {
 app.AddComponent<App>("app");
 }
    }
    
  • Update to the new JavaScript interop model. The changes to the JavaScript interop model are covered in the “JavaScript interop changes” section below.

What is server-side Blazor?

Blazor is principally a client-side web framework intended to run in a browser where the component logic and DOM interactions all happen in the same process.

Blazor client-side

However, Blazor was built to be flexible enough to handle scenarios where the Blazor app runs apart from the rendering process. For example, you might run Blazor in a Web Worker thread so that it runs separately from the UI thread. Events would get pushed from the UI thread to the Blazor worker thread, and Blazor would push UI updates to the UI thread as needed. This scenario isn’t supported yet, but it’s something Blazor was designed to handle.

Blazor web worker

Another potential use case for running Blazor in a separate process is writing desktop applications with Electron. The Blazor component logic could run in a normal .NET Core process, while the UI updates are handled in the Electron rendering process.

Blazor Electron

We have a working prototype that you can try out of using Blazor with Electron in this way.

Blazor 0.5.0 takes the out-of-process model for Blazor and streeeetches it over a network connection so that you can run Blazor on the server. With Blazor 0.5.0 you can run your Blazor components server-side on .NET Core while UI updates, event handling, and JavaScript interop calls are handled over a SignalR connection.

Blazor server-side

There are a number of benefits to running Blazor on the server in this way:

  • You can still write your entire app with .NET and C# using the Blazor component model.
  • Your app still has a rich interactive feel and avoids unnecessary page refreshes.
  • Your app download size is significantly smaller and the initial app load time is much faster.
  • Your Blazor component logic can take full advantage of server capabilities including using any .NET Core compatible APIs.
  • Because you’re running on .NET Core on the server existing .NET tooling, like debugging, just works.
  • Works with thin clients (ex browsers that don’t support WebAssembly, resource constrained devices, etc.).

Of course there are some downsides too:

  • Latency: every user interaction now involves a network hop.
  • No offline support: if the client connection goes down the app stops working.
  • Scalability: the server must manage multiple client connections and handle client state.

While our primary goal for Blazor remains to provide a rich client-side web development experience, enough developers expressed interest in the server-side model that we decided to experiment with it. And because server-side Blazor uses the exact same component model as running Blazor on the client, it is well aligned with our client-side efforts.

Get started with server-side Blazor

To create your first server-side Blazor app use the new server-side Blazor project template.

dotnet new blazorserverside -o BlazorApp1

Build and run the app from the BlazorApp1.Server directory to see it in action:

cd BlazorApp1.Server
dotnet run

You can also create a server-side Blazor app from Visual Studio.

Blazor server-side template

When you run the Blazor server-side app it looks like a normal Blazor app, but the download size is significantly smaller (under 100KB), because there is no need to download a .NET runtime, the app assembly, or any of its dependencies.

Blazor server-side running app

Blazor server-side download size

You’re also free to run the app under the debugger (F5) as all the .NET logic is running on .NET Core on the server.

The template creates a solution with two projects: an ASP.NET Core host project, and a project for your server-side Blazor app. In a future release we hope to merge these two projects into one, but for now the separation is necessary due to the differences in the Blazor compilation model.

The server-side Blazor app contains all of your component logic, but instead of running client-side in the browser the logic is run server-side in the ASP.NET Core host application. The Blazor app uses a different bootstrapping script (blazor.server.js instead of blazor.webassembly.js), which establishes a SignalR connection with the server and handles applying UI updates and forwarding events. Otherwise the Blazor programming model is the same.

The ASP.NET Core app hosts the Blazor app and sets up the SignalR endpoint. Because the Blazor app runs on the server, the event handling logic can directly access server resources and services. For example, the FetchData page no longer needs to issue an HTTP request to retrieve the weather forecast data, but can instead use a service configured on the server:

protected override async Task OnParametersSetAsync()
{
 forecasts = await ForecastService.GetForecastAsync(StartDate);
}

The WeatherForecastService in the template generates the forecast data in memory, but it could just as easily pull the data from a database using EF Core, or use other server resources.

Startup model

All Blazor projects in 0.5.0 now use a new startup model that is similar to the startup model in ASP.NET Core. Each Blazor project has a Startup class with a ConfigureServices method for configuring the services for your Blazor app, and a Configure method for configuring the root components of the application.

public class Startup
{
 public void ConfigureServices(IServiceCollection services)
 {
 }

 public void Configure(IBlazorApplicationBuilder app)
 {
 app.AddComponent<App>("app");
 }
}

The app entry point in Program.cs creates a Blazor host that is configured to use the Startup class.

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

 public static IWebAssemblyHostBuilder CreateHostBuilder(string[] args) =>
 BlazorWebAssemblyHost.CreateDefaultBuilder()
 .UseBlazorStartup<Startup>();
}

In server-side Blazor apps the entry point comes from the host ASP.NET Core app, which references the Blazor Startup class to both add the server-side Blazor services and to add the Blazor app to the request handling pipeline:

public class Startup
{
 public void ConfigureServices(IServiceCollection services)
 {
 ...
 services.AddServerSideBlazor<App.Startup>();
 }

 public void Configure(IApplicationBuilder app, IHostingEnvironment env)
 {
 ...
 app.UseServerSideBlazor<App.Startup>();
 }
}

While the server-side Blazor project may also have a Program class, it is not used when running on the server. However it would be used if you switched to client-side (WebAssembly) execution just by changing the <script> tag in index.html to load blazor.webassembly.js instead of blazor.server.js.

The Blazor app and the ASP.NET Core app share the same service provider. Services added in either ConfigureServices methods are visible to both apps. Scoped services are scoped to the client connection.

State management

When running Blazor on the server the UI state is all managed server-side. The initial state is established with the client connects to the server and is maintained in memory as the user interacts with the app. If the client connection is lost then the server-side app state will be lost, unless it is otherwise persisted and restored by the app. For example, you could maintain your app state in an AppState class that you serialize into session state periodically and then initialize the app state from session state when it is available. While this process is currently completely manual in the future we hope to make server-side state management easier and more integrated.

JavaScript interop changes

You can use JavaScript interop libraries when using server-side Blazor. The Blazor runtime handles sending the JavaScript calls to the browser and then sending the results back to the server. To accommodate out-of-process usage of JavaScript interop the JavaScript interop model was significantly revised and expanded upon in this release.

Calling JavaScript from .NET

To call into JavaScript from .NET use the new IJSRuntime abstraction, which is accessible from JSRuntime.Current. The InvokeAsync<T> method on IJSRuntime takes an identifier for the JavaScript function you wish to invoke along with any number of JSON serializable arguments. The function identifier is relative to the global scope (window). For example, if you wish to call window.someScope.someFunction then the identifier would be someScope.someFunction. There is no longer any need to register the function before it can be called. The return type T must also be JSON serializable.

exampleJsInterop.js

window.exampleJsFunctions = {
 showPrompt: function (message) {
 return prompt(message, 'Type anything here');
 }
};

ExampleJsInterop.cs

using Microsoft.JSInterop;

public class ExampleJsInterop
{
 public static Task<string> Prompt(string message)
 {
 // Implemented in exampleJsInterop.js
 return JSRuntime.Current.InvokeAsync<string>(
 "exampleJsFunctions.showPrompt",
 message);
 }
}

The IJSRuntime abstraction is async to allow for out-of-process scenarios. However, if you are running in-process and want to invoke a JavaScript function synchronously you can downcast to IJSInProcessRuntime and call Invoke<T> instead. We recommend that most JavaScript interop libraries should use the async APIs to ensure the libraries can be used in all Blazor scenarios, client-side or server-side.

Calling .NET from JavaScript

To invoke a static .NET method from JavaScript use the DotNet.invokeMethod or DotNet.invokeMethodAsync functions passing in the identifier of the static method you wish to call, the name of the assembly containing the function, and any arguments. Again, the async version is required to support out-of-process scenarios. To be invokable from JavaScript, the .NET method must be public, static, and attributed with [JSInvokable]. By default, the method identifier is the method name, but you can specify a different identifier using the JSInvokableAttribute constructor. Calling open generic methods is not currently supported.

JavaScriptInteroperable.cs

public class JavaScriptInvokable
{
 [JSInvokable]
 public static Task<int[]> ReturnArrayAsync()
 {
 return Task.FromResult(new int[] { 1, 2, 3 });
 }
}

dotnetInterop.js

DotNet.invokeMethodAsync(assemblyName, 'ReturnArrayAsync').then(data => ...)

New in Blazor 0.5.0, you can also call .NET instance methods from JavaScript. To invoke a .NET instance method from JavaScript you first pass the .NET instance to JavaScript by wrapping it in a DotNetObjectRef instance. The .NET instance will then be passed by reference to JavaScript and you can invoke .NET instance methods on the instance using the invokeMethod or invokeMethodAsync functions. The .NET instance can also be passed as an argument when invoking other .NET methods from JavaScript.

ExampleJsInterop.cs

public class ExampleJsInterop
{
 public static Task SayHello(string name)
 {
 return JSRuntime.Current.InvokeAsync<object>(
 "exampleJsFunctions.sayHello", 
 new DotNetObjectRef(new HelloHelper(name)));
 }
}

exampleJsInterop.js

window.exampleJsFunctions = {
 sayHello: function (dotnetHelper) {
 return dotnetHelper.invokeMethodAsync('SayHello')
 .then(r => console.log(r));
 }
};

HelloHelper.cs

public class HelloHelper
{
 public HelloHelper(string name)
 {
 Name = name;
 }

 public string Name { get; set; }

 [JSInvokable]
 public string SayHello() => $"Hello, {Name}!";
}

Output

Hello, Blazor!

Add Blazor to any HTML file

In previous Blazor releases the project build modified index.html to replace the blazor-boot script tag with a real script tag that handled downloading the starting up the runtime. This setup made it difficult to use Blazor in arbitrary HTML files.

In Blazor 0.5.0 this mechanism has been replaced. For client-side projects add a script tag that references the _framework/blazor.webassembly.js script (which is generated as part of the build). For server-side projects you reference _framework/blazor.server.js. You can add this script to any HTML file, including server generated content.

For example, instead of using the static index.html file from the Blazor client project you could add a Razor Page to your ASP.NET Core host project and then add the Blazor script tag there along with any server-side rendering logic.

Render raw HTML

Blazor normally renders strings using DOM text nodes, which means that any markup they may contain will be ignored and treated as literal text. This new feature lets you render special MarkupString values that will be parsed as HTML or SVG and then inserted into the DOM.

WARNING: Rendering raw HTML constructed from any untrusted source is a major security risk!

Use the MarkupString type to add blocks of static HTML content.

@((MarkupString)myMarkup)

@functions {
 string myMarkup = "<p class='markup'>This is a <em>markup string</em>.</p>";
}

Component parameter snippet

Thanks to a community contribution from Benjamin Vertonghen (vertonghenb) we now have a Visual Studio snippet for adding component parameters. Just type para and then hit Tab twice to add a parameter to your component.

Debugging

Blazor 0.5.0 introduces some very basic debugging support in Chrome for client-side Blazor apps running on WebAssembly. While this initial debugging support is very limited and unpolished it does show the basic debugging infrastructure coming together.

To debug your client-side Blazor app in Chrome:

  • Build a Blazor app in Debug configuration (the default for non-published apps)
  • Run the Blazor app in Chrome
  • With the keyboard focus on the app (not in the dev tools, which you should probably close as it’s less confusing that way), press the following Blazor specific hotkey:
    • Shift+Alt+D on Windows/Linux
    • Shift+Cmd+D on macOS

You need to run Chrome with remote debugging enabled to debug your Blazor app. If you don’t, you will get an error page with instructions for running Chrome with the debugging port open so that the Blazor debugging proxy can connect to it. You will need to close all Chrome instances and then restart Chrome as instructed.

Blazor debugging error page

Once you have Chrome running with remote debugging enabled, hitting the debugging hotkey will open a new debugger tab. After a brief moment the Sources tab will show a list of the .NET assemblies in the app. You can expand each assembly and find the .cs/.cshtml source files you want to debug. You can then set breakpoints, switch back to your app’s tab, and cause the breakpoints to be hit. You can then single-step (F10) or resume (F8).

Blazor debugging

How does this work? Blazor provides a debugging proxy that implements the Chrome DevTools Protocol and augments the protocol with .NET specific information. When you hit the debugging hotkey, Blazor points the Chrome DevTools at the proxy, which in turn connects to the browser window you are trying to debug (hence the need for enabling remote debugging).

You might be wondering why we don’t just use browser source maps. Source maps allow the browser to map compiled files back to their original source files. However, Blazor does not map C# directly to JS/WASM (at least not yet). Instead, Blazor does IL interpretation within the browser, so source maps are not relevant.

NOTE: The debugger capabilities are very limited. You can currently only:

  • Single-step through the current method (F10) or resume (F8)
  • In the Locals display, observe the values of any local variables of type int/string/bool
  • See the call stack, including call chains that go from JavaScript into .NET and vice-versa

That’s it! You cannot step into child methods (i.e., F11), observe the values of any locals that aren’t an int/string/bool, observe the values of any class properties or fields, hover over variables to see their values, evaluate expressions in the console, step across async calls, or do basically anything else.

Our friends on the Mono team have done some great work tackling some of the hardest technical problems to enable source viewing, breakpoints, and stepping, but please be patient as completing the long tail of debugger features remains a significant ongoing task.

Community

The Blazor community has produced a number of great Blazor extensions, libraries, sample apps, articles, and videos.
You can find out about these community projects on the Blazor Community page. Recent additions include a Blazor SignalR client, Redux integration, and various community authored samples (Toss, Clock, Chat). If you have a Blazor related project that you’d like to share on the community page let us know by sending us a pull request to the Blazor.Docs repo.

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 please 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 also 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

Exploring Azure App Service – Azure Diagnostics

If you’ve followed our previous posts about using Azure App Service to host web apps in the cloud (1. Introduction to App Service, 2. Hosting web apps that use SQL) you’re already familiar with how easy it is to get an app running in the cloud; but what if the app doesn’t work correctly (it’s crashing, running too slow, etc.)?  In this post we’ll explore how to use Azure’s Application Insights to have always on diagnostics that will help you find and fix these types of issues.

Azure Application Insights provides seamless integration with Azure App Service for monitoring, triaging and diagnosing code-level issues. It can easily be enabled on an existing web app with a single button click. Profiler traces and exception snapshots will be available for identifying the lines of code that caused issues. Let’s take a closer look at this experience.

Enable Application Insights on an existing web app to investigate issues

We recommend you follow along using your own application, but if you don’t have one readily available we will be using the Contoso University sample. The instructions on how to deploy it to App Service are in the readme file.

If you are following along with Contoso University, you will notice the Instructors page throws errors. In addition, the Courses tab loads a bit slower than others.

Let’s turn on Application Insights to investigate. After the app is deployed to App service, Application Insights can be enabled from the App Service portal by clicking the button on the overview blade:

Fill out the Application Insights enablement blade the following way:

  • Create a new resource, with an appropriate name.
  • Leave all default options for Code-level diagnostics on. The added section Code level diagnostics is on by default to enable Profiler and Snapshot Debugger for diagnosing slow app performance and runtime exceptions.
  • Click the ‘OK’ button. Once prompted if to restart the web app, click ‘Continue’ to proceed.

Once Application Insights is enabled, you will be able to see its connection status. You can now navigate to the Application Insights overview blade by clicking on the link next to the green check mark:

Generate traffic for your web app in order to reproduce issues

Let’s generate some traffic to reproduce our two issues: a) Courses page loading slowly, b) Instructors page throwing errors. You are going to use performance test with Azure portal to make requests to the following URLs:

  • http://<your_webapp_name>.azurewebsites.net/Courses
  • http://<your_webapp_name>.azurewebsites.net/Instructors

You are going to be creating two different performance tests, once for each URL. For the Courses page you are going to simulate 250 users over a duration of 5 minutes, since you are experiencing a performance issue. For the Instructors page you can simulate 10 users over 1 minutes since we’d generally expect less instructors than users on the site at any given time.

Profile your app during performance tests to identify performance issues

A performance test will generate traffic, but if you want to understand how you app performs you have to analyze its performance while the test is running using a profiler. Let’s do exactly that, using the Performance | Configure Profiler blade while one of our performance tests is running:

Later on we will walkthrough how to use the profiler to identify the exact lines of code responsible for the slow-down. For now, let’s focus on simply profiling . After clicking on “Profile now”, wait until the performance test finishes and the profiler has completed its analysis. After a new entry in the section “Recent profiling sessions” appears, navigate back to the Overview blade.

Diagnose runtime exceptions

If your web app has any failed requests, you need to root cause and solve the issues to ensure your app works reliably. After running your performance test on the Instructors page you have some example failed requests to take a look at:

Let’s go to Failures blade to investigate what failed.

On the Failures blade, the top failed operation is ‘GET Instructors/Index’ and the top exception is ‘InvalidOperationException’. Click on the ‘COUNT’ column of the exception count to open list of sample exceptions. Click on the suggested exception to open the End-to-End Transaction blade.

In the End-to-End Transaction blade, you can see ‘System.InvalidOperationException’ exceptions thrown from GET Instructors/Index operation. Select the exception row and click on ‘Open debug snapshot’.

If it’s the first time you use Snapshot Debugger, you will prompt to request RBAC access to snapshots to safeguard the potentially sensitive data shown in local variables:

Once you get access, you will see a snapshot view like the following:

From the local variables and call stack, you can see the exception is thrown at InstructorsController.cs line 56 with message ‘Nullable object must have a value’. This provides sufficient information to proceed with debugging the app’s source code.

To get a better experience, download the snapshot and debug it using Visual Studio Enterprise. You will be able to interactively see which line of code caused the exception:

Looking at the code, the exception was thrown because ‘id’ is null and you are missing the appropriate check. When your app is running in the cloud, resources are dynamically provisioned and destroyed and so may not always get the chance to access the state of a failed component before it is reset. The Snapshot Debugger is a powerful tool that can maintain the failed state of the component even after the component’s state has been reset, by capturing local variables and call stack at the time the exception is thrown.

Diagnose bad performance from your web app

The server response time chart on the overview blade provides quick information on how performant your web app is over time. In the Contoso example, we see some spikes on the chart indicating there is a short period of time where users experienced slow responses for the requests they made.

To investigate further, navigate to the Performance blade in App Insights portal:

Zoom into the time range 6pm-10pm in the ‘Operation times: zoom into range’ chart to see spikes on the Request count.

Sort the Operations table by duration and request count to figure out where your web app spent the most time. In our example GET Courses/Index operation has the longest average duration. Let’s click on it to investigate why this operation takes so long.

The right side of the blade provides insights based on the Course/Index operation.

From the chart you can see although most operations only took around 400ms, the worst ones took up to 35 seconds. This means some users are getting really bad experience when hitting this URL and you should address it. Let’s look at Profiler traces to troubleshoot why GET Courses/Index was being so slow.

You should see profiler traces similar to the following:

The code path that’s taking the most time is prefixed with the flame icon. In this particular request, most time was spent on reading the list of courses from the database. Browsing to the code CourseController.cs we can see that when loading the list of courses the AsNoTracking() optimization option is not used. By default, Entity Framework will turn on tracking which caches the results to compare with what’s modified. This could add an approx. ~30% overhead to your app’s performance. For simple read operation like this one, we can optimize the query performance by using the AsNoTracking() option.

Conclusion

We hope that you find it easy to use Application Insights to diagnose performance and errors in your web apps. We believe Azure App Service is a great place to get started hosting and maintaining your web apps. You don’t have to enable App Insights upfront; the option is always there to be turned on when and as needed without re-deployment.

If you have any questions or issues, let us know by leaving comments below.

Catherine Wang Program Manager, VS and .NET

Catherine is on Azure developer experience team and is responsible for Azure diagnostics, security and storage tools.

Posted on Leave a comment

Razor Improvements – Feedback Wanted

In recent releases of Visual Studio 2017, there has been a great focus on improving the experience of working with Razor files (*.cshtml). The improvements were aimed at addressing the most pressing customer-facing issues and included changes from formatting and IntelliSense to general performance and reliability. Now that the fixes and enhancements have been publicly available for a few months, we hope you’ve been having a much-improved experience with the Razor editor.

Please let us know how we’re doing by taking a short, two-minute survey. Also, feel free to leave relevant feedback in the comments section below.

If you haven’t already downloaded the latest version, update your copy of Visual Studio 2017 through the Visual Studio Installer, or follow the links to download the installer from the Visual Studio website.

Razor editor in Visual Studio IDE

We know that despite our improvements, Razor editing isn’t perfect yet, so if you run into issues please file a report using the Visual Studio feedback tool. We review this feedback frequently and will continue to fix issues that are identified.

To launch the feedback tool, choose “Report a Problem…” under the Help->Send Feedback menu. When filing a report, please provide as much of your Razor file as you can share, with a description of what happened versus what you expected. (Sample code and screenshots are very helpful!)

Report a Problem menu item

Thanks for your interest in Web Development in Visual Studio.
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

Workaround for Bower Version Deprecation

As of June 25, the version of Bower shipped with Visual Studio was deprecated, resulting in Bower operations failing when run in Visual Studio. If you use Bower, you will see an error something like:

EINVRES Request to https://bower.herokuapp.com/packages/bootstrap failed with 502

This will be fixed in Visual Studio 15.8. In the meantime, you can work around the issue by using a new version of Bower or by adding some configuration to each Bower project.

The Issue

Some time, ago Bower switched their primary registry feed but continued to support both. On June 25th, they turned off the older feed, which the copy in Visual Studio tries to use by default.

The Fix

There are two options to fix this issue:

  1. Update the configuration for each Bower project to explicitly use the new registry: https://reigstry.bower.io
  2. Manually install a newer version of Bower and configure Visual Studio to use it.

Workaround 1: Define the new registry entry in the project’s Bower config file (.bowerrc)

Add a .bowerrc file to the project (or modify the existing .bowerrc) with the following content:

{
 "registry": "https://registry.bower.io"
}

With the registry property defined in a .bowerrc file in the project root, Bower operations should run successfully on the older versions of Bower that shipped with Visual Studio 2015 and Visual Studio 2017.

Workaround 2: Configure Visual Studio to point to use a newer version of Bower

An alternative solution is to configure Visual Studio use to a newer version of Bower that you have installed as a global tool on your machine. (For instructions on how to install Bower, refer to the guidance on the Bower website.) If you have installed Bower via npm, then the path to the bower tools will be contained in the system $(PATH) variable. It might look something like this: C:\Users\[username]\AppData\Roaming\npm. If you make this path available to Visual Studio via the External Web Tools options page, then Visual Studio will be able to find and use the newer version.

To configure Visual Studio to use the globally installed Bower tools:

  1. Inside Visual Studio, open Tools->Options.
  2. Navigate to the External Web Tools options page (under Projects and Solutions->Web Package Management).
  3. Select the “$(PATH)” item in the Locations of external tools list box.
  4. Repeatedly press the up-arrow button in the top right corner of the Options dialog until the $(PATH) item is at the top of the list.
  5. Press OK to confirm the change.

Configure External Web Tools Path
Ordered this way, when Visual Studio is searching for Bower tools, it will search your system path first and should find and use the version you installed, rather than the older version that ships with Visual Studio in the $(VSINSTALLDIR)\Web\External directory.

Note: This change affects path resolution for all external tools. So, if you have Grunt, Gulp, npm or any other external tools on the system path, those tools will be used in preference to any other versions that shipped with VS. If you only want to change the path for Bower, leave the system path where it is and add a new entry at the top of the list that points to the instance of Bower installed locally. It might look something like this: C:\Users\[username]\AppData\Roaming\npm\node_modules\bower\bin

We trust this will solve any issues related to the recent outage of the older bower registry. If you have any questions or comments, please leave them below.

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

New Cocos Creator Tutorial Series

A brand new tutorial series just went live on devga.me (to join the existing Armory 3D series), the Cocos Creator Crash Course.

Cocos Creator Crash Course - Devga.me Tutorial Series

The series currently consists of the following tutorial parts:

Cocos Creator Tutorial Series homepage

There are a few more tutorial chapters in active development.  The existing content should already be enough to get you up and running using the Cocos Creator game engine!  There will also be at least one video tutorial covering basically everything covered by the text series.

GameDev News, Programming , , ,

Posted on Leave a comment

Changes to script debugging in Visual Studio 15.7

We’re always looking for ways to make developing with Visual Studio faster.  One of the tasks developers do many times a day is launching debugging sessions.  We identified that script debugging added about 1.5s per F5, but only about 15.5% of people actively debugged script using Visual Studio.

Based on the above, in Visual Studio 15.7 we made the decision to turn off script debugging by default to improve the overall experience for most users. If you want to turn the capability back on, you can do it from Tools | Options | Debugging | and check “Enable JavaScript debugging for ASP.NET (Chrome, Edge, and IE):

We also added the following dialog when you attempt to set a breakpoint with script debugging disabled:

When script debugging is ON, Visual Studio automatically stops debugging when the browser window is closed. It will also close the browser window if you stop debugging in Visual Studio. We added the same capability to Visual Studio when script debugging is OFF under Tools | Options | Project and Solutions | Web Projects:

With this option enabled:

  • Visual Studio will open a new browser window when debugging starts
  • Visual Studio will stop debugging when the browser window is closed

The following matrix shows you all the available options and the expected behavior for each combination:

Enable JavaScript debugging for ASP.NET (Chrome, Edge and IE) Stop debugger when browser window is closed What happens when you start debugging What happens when you stop debugging What happens when you close the browser window
TRUE TRUE New browser window always pops up New browser window always goes away, with all open tabs Debugging stops
TRUE FALSE New browser window always pops up New browser window always goes away, with all open tabs Debugging stops
FALSE TRUE New browser window always pops up New browser window always goes away, with all open tabs Debugging stops
FALSE FALSE Opens new tab if browser window already exists Browser tab/window stays open Debugging continues

If you want Visual Studio to return to its default pre-15.7 behavior, all you have to do is enable script debugging in Tools | Options | Debugging | and check “Enable JavaScript debugging for ASP.NET (Chrome, Edge, and IE). If you notice any unexpected behavior with these options please use report a problem in Visual Studio to let us know. If you have any feedback or suggestions regarding this change please let us know on uservoice or simply post a reply to this post.

Posted on Leave a comment

Armory Game Engine Tutorial Series

If you’ve recently been to the GameFromScratch tutorial series page recently you may have noticed the addition of a new Armory game engine tutorial series.  It’s not actually hosted on GameFromScratch, instead it’s on our newly launched sister site (watch out, the paints still wet!) DevGa.me.  Don’t worry though, nothings changed, it’s just a newer, cleaner, ArmoryDevGame900x600mobile friendly home for tutorial series, I’ll explain more about this later.  For now, just be aware there is a new text and video based tutorial series on the Armory game engine under development!

Armory (or Armory3D) is a newly free open source cross platform game engine that runs inside and tightly integrates with the Blender application.  If you are interested in learning more about Armory and why I’m so excited about it, be sure to check out Introduction to Armory video.  The series is still quite young but already there is a fair bit to get you started.  Right now the series consists of:

The entire series homepage is available here.

Additionally the video series has begun, lagging slightly behind the text series.  So far videos consist of:

There is a (very small for now…) playlist available here.

DevGa.me is not a blog format and does not have any news, it’s just home to tutorials.  I will however announce new tutorials here on GameFromScratch, so stay tuned!  If you want to discuss the new series, there is a conversation over on the Armory discussion forums or leave a comment below or on YouTube.

Programming, Art ,

Posted on Leave a comment

Blazor 0.4.0 experimental release now available

Blazor 0.4.0 is now available! This release includes important bug fixes and several new feature enhancements.

New features in Blazor 0.4.0 (details below):

  • Add event payloads for common event types
  • Use camelCase for JSON handling
  • Automatic import of core Blazor namespaces in Razor
  • Send and receive binary HTTP content using HttpClient
  • Templates run on IIS Express by default with autobuild enabled
  • Bind to numeric types
  • JavaScript interop improvements

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

Get Blazor 0.4.0

To get setup with Blazor 0.4.0:

  1. Install the .NET Core 2.1 SDK (2.1.300 or later).
  2. Install Visual Studio 2017 (15.7) with the ASP.NET and web development workload selected.
    • Note: The Blazor tooling isn’t currently compatible with the VS2017 preview channel (15.8). This will be addressed in a future Blazor release.
  3. Install the latest Blazor Language Services extension from the Visual Studio Marketplace.

To install 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.4.0

To upgrade an existing Blazor project from 0.3.0 to 0.4.0:

  • Install all of the required bits listed above.
  • Update your Blazor package and .NET CLI tool references to 0.4.0.

Your 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.4.0" /> <PackageReference Include="Microsoft.AspNetCore.Blazor.Build" Version="0.4.0" /> <DotNetCliToolReference Include="Microsoft.AspNetCore.Blazor.Cli" Version="0.4.0" /> </ItemGroup> </Project>

Event payloads for common event types

This release adds payloads for the following event types:

Event arguments Events
UIMouseEventArgs onmouseover, onmouseout, onmousemove, onmousedown, onmouseup, oncontextmenu
UIDragEventArgs ondrag, ondragend, ondragenter, ondragleave, ondragover, ondragstart, ondrop
UIPointerEventArgs gotpointercapture, lostpointercapture, pointercancel, pointerdown, pointerenter, pointerleave, pointermove, pointerout, pointerover, pointerup
UITouchEventArgs ontouchcancel, ontouchend, ontouchmove, ontouchstart, ontouchenter, ontouchleave
UIWheelEventArgs onwheel, onmousewheel
UIKeyboardEventArgs onkeydown, onkeyup
UIKeyboardEventArgs onkeydown, onkeyup, onkeypress
UIProgressEventArgs onloadstart, ontimeout, onabort, onload, onloadend, onprogress, onerror

Thank you to Gutemberg Ribeiro (galvesribeiro) for this contribution! If you haven’t checked out Gutemberg’s handy collection of Blazor extensions they are definitely worth a look.

Use camelCase for JSON handling

The Blazor JSON helpers and utilities now use camelCase by default. .NET objects serialized to JSON are serialized using camelCase for the member names. On deserialization a case-insensitive match is used. The casing of dictionary keys is preserved.

Automatic import of core for Blazor namespaces in Razor

Blazor now automatically imports the Microsoft.AspNetCore.Blazor and Microsoft.AspNetCore.Blazor.Components namespaces in Razor files, so you don’t need to add @using statements for them. One less thing for you to do!

Send and receive binary HTTP content using HttpClient

You can now use HttpClient to send and receive binary data from a Blazor app (previously you could only handle text content). Thank you Robin Sue (Suchiman) for this contribution!

Bind to numeric types

Binding now works with numeric types: long, float, double, decimal. Thanks again to Robin Sue (Suchiman) for this contribution!

Templates run on IIS Express by default with autobuild enabled

The Blazor project templates are now setup to run on IIS Express by default, while still preserving autobuild support.

JavaScript interop improvements

Call async JavaScript functions from .NET

With Blazor 0.4.0 you can now call and await registered JavaScript async functions like you would an async .NET method using the new RegisteredFunction.InvokeAsync method. For example, you can register an async JavaScript function so it can be invoked from your Blazor app like this:

Blazor.registerFunction('BlazorLib1.DelayedText', function (text) { // Wait 1 sec and then return the specified text return new Promise((resolve, reject) => { setTimeout(() => { resolve(text); }, 1000); });
});

You then invoke this async JavaScript function using InvokeAsync like this:

public static class ExampleJSInterop
{ public static Task<string> DelayedText(string text) { return RegisteredFunction.InvokeAsync<string>("BlazorLib1.DelayedText", text); }
}

Now you can await the async JavaScript function like you would any normal C# async method:

var text = await ExampleJSInterop.DelayedText("See ya in 1 sec!");

Call .NET methods from JavaScript

Blazor 0.4.0 makes it easy to call sync and async .NET methods from JavaScript. For example, you might call back into .NET when a JavaScript callback is triggered. While calling into .NET from JavaScript was possible with earlier Blazor releases the pattern was low-level and difficult to use. Blazor 0.4.0 provides simpler pattern with the new Blazor.invokeDotNetMethod and Blazor.invokeDotNetMethodAsync functions.

To invoke a .NET method from JavaScript the target .NET method must meet the following criteria:

  • Static
  • Non-generic
  • No overloads
  • Concrete JSON serializable parameter types

For example, let’s say you wanted to invoke the following .NET method when a timeout is triggered:

namespace Alerts
{ public class Timeout { public static void TimeoutCallback() { Console.WriteLine('Timeout triggered!'); } }
}

You can call this .NET method from JavaScript using Blazor.invokeDotNetMethod like this:

Blazor.invokeDotNetMethod({ type: { assembly: 'MyTimeoutAssembly', name: 'Alerts.Timeout' }, method: { name: 'TimeoutCallback' }
})

When invoking an async .NET method from JavaScript if the .NET method returns a task, then the JavaScript invokeDotNetMethodAsync function will return a Promise that completes with the task result (so JavaScript/TypeScript can also use await on it).

Summary

We hope you enjoy this latest preview of Blazor. Your feedback is especially important to us during this experimental phase for Blazor. If you run into issues or have questions while trying out Blazor please 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 also let us know what you think by taking our in-product survey. Just 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

Use Dependency Injection In WebForms Application

Dependency Injection design pattern is widely used in modern applications.  It decouples objects to the extent that no client code needs to be changed simply because an object it depends changes to a different one.  It brings you a lot of benefits, like reduced dependency, more reusable code, more testable code, etc.  in the past, it was very difficult to use Dependency Injection in WebForms application before.  Starting from .NET 4.7.2, it is now easy for developers to use Dependency Injection in WebForms applications.  With the UnityAdapter, you can add it to your existing WebForms application in 4 simple steps.

How to enable Dependency Injection in your existing WebForms application

Suppose you have a movie website which lists most popular movies in history.  You use repository pattern to separate the logic that retrieves the data and maps it to the business entity.  Currently you are creating business logic object and repository object in default.aspx page.  The code looks like bellow.

Now simply follow 4 steps below, you will be able to adopt Dependency Injection to decouple the MovieManager from default.aspx page. The sample web application is on this Github repo.  And you can use tag to retrieve the code change in each step.

1. Retarget the project to .NET Framework 4.7.2. (Git Tag: step-1)

Open project property and change the targetFramework of the project to .NET Framework 4.7.2. You would also need to change targetFramework in httpRuntime section in web.config file as illustrated below.

2. Install AspNet.WebFormsDependencyInjection.Unity NuGet package. (Git Tag: step-2)

3. Register types in Global.asax. (Git Tag: step-3)

4. Refactor Default.aspx.cs. (Git Tag: step-4)

Areas that Dependency Injection can be used

There are many areas you can use Dependency Injection in WebForms applications now. Here is a complete list.

  • Pages and controls
    • WebForms page
    • User control
    • Custom control
  • IHttpHandler and IHttpHandlerFactory
  • IHttpModule
  • Providers
    • BuildProvider
    • ResourceProviderFactory
    • Health monitoring provider
    • Any ProviderBase based provider created by System.Web.Configuration.ProvidersHelper.InstantiateProvider. e.g. custom sessionstate provider

Summary

Using Microsoft.AspNet.WebFormsDependencyInjection.Unity NuGet package on .net framework 4.7.2, Dependency Injection can be easily added into your existing WebForms application. Please give it a try and let us know your feedback.