:::: MENU ::::

Sunday, June 10, 2018

Sometimes you may need to run Visual Studio as Administrator; to do so, you have to right-click on Visual Studio task bar shortcut, right-click again on Visual Studio and select Run as Administrator. Then, you may open the solution you want manually from File -> Open -> Project/Solution or drop your .sln file onto Visual Studio.

To make your life easier, you may perform the following tasks in order to start as Administrator faster.

Open Visual Studio as Administrator

If you want to start Visual Studio as Administrator you can do the following:

  • right-click on your VS task bar shortcut
  • right-click on your VS product and select Properties
  • from Properties window select Advanced…
  • from Advanced Properties check on Run as Administrator option
  • select Ok in Advanced Properties window, Apply and then Ok on VS 2017 Properties

Open every Visual Studio Solution (.sln) as Administrator

Although not the best idea if you open third-party VS solutions, it may come in handy if you need to open the same solutions as Administrator again and again. To do so, right-click on devenv.exe and select Troubleshoot Compatibility.

You may then proceed to the following steps:

  • on the Program Compatibility Troubleshooter window, click on Troubleshoot Program
  • check The program requires additional permissions and click Next
  • on the next window, click on Test the program… and VS will open as administrator
  • click next and then click on Yes, save these settings for this program

Following the above, whenever you open a solution (.sln) it will always open as Adminsitrator. If you want to disable this function, you will need to follow again the steps above without checking though The Program requires additional permissions.


Saturday, June 9, 2018

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 argumentsEvents
UIMouseEventArgsonmouseover, onmouseout, onmousemove, onmousedown, onmouseup, oncontextmenu
UIDragEventArgsondrag, ondragend, ondragenter, ondragleave, ondragover, ondragstart, ondrop
UIPointerEventArgsgotpointercapture, lostpointercapture, pointercancel, pointerdown, pointerenter, pointerleave, pointermove, pointerout, pointerover, pointerup
UITouchEventArgsontouchcancel, ontouchend, ontouchmove, ontouchstart, ontouchenter, ontouchleave
UIWheelEventArgsonwheel, onmousewheel
UIKeyboardEventArgsonkeydown, onkeyup
UIKeyboardEventArgsonkeydown, onkeyup, onkeypress
UIProgressEventArgsonloadstart, 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.invokeDotNetMethodAsyncfunctions.

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 invokeDotNetMethodAsyncfunction 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:

More

Wednesday, June 6, 2018

This post shows how a view with dynamic css styles could be implemented using an MVC view component in ASP.NET Core. The values are changed using a HTML form with ASP.NET Core tag helpers, and passed into the view component which displays the view using css styling. The styles are set at runtime.

Code: https://github.com/damienbod/AspNetCoreMvcDynamicViews

Creating the View Component

The View Component is a nice way of implementing components in ASP.NET Core MVC. The view component is saved in the \Views\Shared\Components\DynamicDisplay folder which fulfils some of the standard paths which are pre-defined by ASP.NET Core. This can be changed, but I always try to use the defaults where possible.

The DynamicDisplay class implements the ViewComponent class, which has a single async method InvokeAsync that returns a Task with the IViewComponentResult type.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using AspNetCoreMvcDynamicViews.Views.Shared.Components.DynamicDisplay;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
 
namespace AspNetCoreMvcDynamicViews.Views.Home.ViewComponents
{
    [ViewComponent(Name = "DynamicDisplay")]
    public class DynamicDisplay : ViewComponent
    {
        public async Task<IViewComponentResult> InvokeAsync(DynamicDisplayModel dynamicDisplayModel)
        {
            return View(await Task.FromResult(dynamicDisplayModel));
        }
    }
}

The view component uses a simple view model with some helper methods to make it easier to use the data in a cshtml view.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
namespace AspNetCoreMvcDynamicViews.Views.Shared.Components.DynamicDisplay
{
    public class DynamicDisplayModel
    {
        public int NoOfHoles { get; set; } = 2;
 
        public int BoxHeight { get; set; } = 100;
 
        public int NoOfBoxes { get; set; } = 2;
 
        public int BoxWidth { get; set; } = 200;
 
        public string GetAsStringWithPx(int value)
        {
            return $"{value}px";
        }
 
        public string GetDisplayHeight()
        {
            return $"{BoxHeight + 50 }px";
        }
 
        public string GetDisplayWidth()
        {
            return $"{BoxWidth * NoOfBoxes}px";
        }
    }
}

The cshtml view uses both css classes and styles to do a dynamic display of the data.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@using AspNetCoreMvcDynamicViews.Views.Shared.Components.DynamicDisplay
@model DynamicDisplayModel
 
<div style="height:@Model.GetDisplayHeight(); width:@Model.GetDisplayWidth()">
    @for (var i = 0; i < Model.NoOfBoxes; i++)
    {
    <div class="box" style="width:@Model.GetAsStringWithPx(Model.BoxWidth);height:@Model.GetAsStringWithPx(Model.BoxHeight);">
        @if (Model.NoOfHoles == 4)
        {
            @await Html.PartialAsync("./FourHolesPartial.cshtml")
        }
        else if (Model.NoOfHoles == 2)
        {
            @await Html.PartialAsync("./TwoHolesPartial.cshtml")
        }
        else if (Model.NoOfHoles == 1)
        {
            <div class="row justify-content-center align-items-center" style="height:100%">
                <span class="dot" style=""></span>
            </div>
        }
    </div>
    }
</div>

Partial views are used inside the view component to display some of the different styles. The partial view is added using the @await Html.PartialAsync call. The box with the four holes is implemented in a partial view.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div class="row" style="height:50%">
    <div class="col-6">
        <span class="dot" style="float:left;"></span>
    </div>
    <div class="col-6">
        <span class="dot" style="float:right;"></span>
    </div>
</div>
 
<div class="row align-items-end" style="height:50%">
    <div class="col-6">
        <span class="dot" style="float:left;"></span>
    </div>
    <div class="col-6">
        <span class="dot" style="float:right;"></span>
    </div>
</div>

And CSS classes are used to display the data.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.dot {
    height: 25px;
    width: 25px;
    background-color: #bbb;
    border-radius: 50%;
    display: inline-block;
}
 
.box {
    float: left;
    height: 100px;
    border: 1px solid gray;
    padding: 5px;
    margin: 5px;
    margin-left: 0;
    margin-right: -1px;
}

Using the View Component

The view component is then used in a cshtml view. This view implements the form which sends the data to the server. The view component is added using the Component.InvokeAsync method which takes only a model as a parameter and then name of the view component.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
@using AspNetCoreMvcDynamicViews.Views.Shared.Components.DynamicDisplay
@model MyDisplayModel
@{
    ViewData["Title"] = "Home Page";
}
 
<div style="padding:20px;"></div>
 
<form asp-controller="Home" asp-action="Index" method="post">
    <div class="col-md-12">
 
        @*<div class="form-group row">
            <label  class="col-sm-3 col-form-label font-weight-bold">Circles</label>
            <div class="col-sm-9">
                <select class="form-control" asp-for="mmm" asp-items="mmmItmes"></select>
            </div>
        </div>*@
 
        <div class="form-group row">
            <label class="col-sm-5 col-form-label font-weight-bold">No of Holes</label>
            <select class="col-sm-5 form-control" asp-for="DynamicDisplayData.NoOfHoles">
                <option value="0" selected>No Holes</option>
                <option value="1">1 Hole</option>
                <option value="2">2 Holes</option>
                <option value="4">4 Holes</option>
            </select>
        </div>
 
        <div class="form-group row">
            <label class="col-sm-5 col-form-label font-weight-bold">Height in mm</label>
            <input class="col-sm-5 form-control" asp-for="DynamicDisplayData.BoxHeight" type="number" min="65" max="400" />
        </div>
 
        <div class="form-group row">
            <label class="col-sm-5 col-form-label font-weight-bold">No. of Boxes</label>
            <input class="col-sm-5 form-control" asp-for="DynamicDisplayData.NoOfBoxes" type="number" min="1" max="7" />
        </div>
 
        <div class="form-group row">
            <label class="col-sm-5 col-form-label font-weight-bold">Box Width</label>
            <input class="col-sm-5 form-control" asp-for="DynamicDisplayData.BoxWidth" type="number" min="65" max="400" />
        </div>
 
        <div class="form-group row">
            <button class="btn btn-primary col-sm-10" type="submit">Update</button>
        </div>
 
    </div>
 
    @await Component.InvokeAsync("DynamicDisplay", Model.DynamicDisplayData)
 
</form>

The MVC Controller implements two methods, one for the GET, and one for the POST. The form uses the POST to send the data to the server, so this could be saved if required.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class HomeController : Controller
{
    [HttpGet]
    public IActionResult Index()
    {
        var model = new MyDisplayModel
        {
            DynamicDisplayData = new DynamicDisplayModel()
        };
        return View(model);
    }
 
    [HttpPost]
    public IActionResult Index(MyDisplayModel myDisplayModel)
    {
        // save data to db...
        return View("Index", myDisplayModel);
    }

Running the demo

When the application is started, the form is displayed, and the default values are displayed.

And when the update button is clicked, the values are visualized inside the view component.

Links:

https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components?view=aspnetcore-2.1

https://docs.microsoft.com/en-us/aspnet/core/mvc/views/partial?view=aspnetcore-2.1

https://docs.microsoft.com/en-us/aspnet/core/mvc/views/razor?view=aspnetcore-2.1

More