.NET CLI

Visual Studio Missing Scaffolding for ASP.NET Core

This morning I set out to try the Scaffold Identity option that was added as part of the ASP.NET 2.1 release. The docs for this feature is really good so I didn’t think I would have any issue, but I was wrong.

Sample Application

To start I used the .NET CLI to create a new application using the following command.

dotnet new razor

I then opened the project in Visual Studio. Then following the docs I right-clicked on the project and expanded the Add option, but the New Scaffolded item is missing.

Sample Application 2

Since the project created using the CLI didn’t have the option I thought I would try creating a new project in Visual Studio. From in Visual Studio using File > New > Project.

Under Visual C# > Web select ASP.NET Core Web Application and click OK.

Select Web Application and then click OK.

After the creation process finishes I right-clicked on the project and expanded the Add option and the New Scaffolded item is there.

What’s the difference?

After trying a lot of different things I finally got to the point of looking at the csproj files for both projects. Here is the csproj from the Visual Studio create project.

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.1.2" PrivateAssets="All" />
  </ItemGroup>
</Project>

And the csproj from the CLI created project.

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
  </PropertyGroup>


  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0-preview3-35497" PrivateAssets="All" />
  </ItemGroup>
</Project>

Notice that the CLI created project is targeting .NET Core 2.2 which is in preview at the time of this writing. Not surprisingly Visual Studio has some limits on what can be done using preview bits.

Wrapping Up

I can’t believe that I let having preview bits installed cause me issues again. I’m guessing that most people aren’t installing the previews so hopefully, this isn’t an issue most of you will have to deal with.

If you do want to use the CLI to create an application targeting a specific version of .NET Core it can be done using a global.json file. Check out Controlling .NET Core’s SDK Version for more information.

Visual Studio Missing Scaffolding for ASP.NET Core Read More »

.NET CLI Errors Due to VSTS Package Source

At work, we use Visual Studio Team Services for source control, internal NuGet package management, and continuous integration. It has been a great tool that has really helped streamline our processes.

.NET CLI Issue

The problem with the setup is if the .NET CLI calls anything that uses NuGet (restore, installing new templates) with the VSTS package source enable it results in the following unauthorized error.

C:\Program Files\dotnet\sdk\2.1.103\NuGet.targets(104,5): error : Unable to load the service index for source https://company.pkgs.visualstudio.com/_packaging/feedname/nuget/v3/index.json. [project.csproj]
C:\Program Files\dotnet\sdk\2.1.103\NuGet.targets(104,5): error : Response status code does not indicate success: 401 (Unauthorized). [project.csproj]

I have been working around this by disabling the VSTS package source when working with the .NET CLI. It is a bit of a pain, but it works since I’m not using any of the packages from our private feed.

A Fix

I had the opportunity to talk to one of the VSTS product managers (PM) for the package management area and they are aware that this issue. While not the ultimate fix the PM pointed out that I could use a personal access token to get around the error.

Create a Personal Access Token

Log in to VSTS and hover over your profile picture and select security.

Next, click the add button on the Personal access tokens screen.

The next page you will need to enter a description for the token and select how long the token should be good for. It is also very important to change the Authorized Scopes off of all and only select the ones you want the token to be valid for. In my case, I selected everything package related, but Packaging (read) would be enough if you aren’t going adding packages to the feed.

At the bottom of the above screen click the Create Token button. This will take you back to the token list page with a new item for your new token and this will be your only opportunity to get a copy of the token.

Add NuGet Source with Token

Now that you have a token open up a command prompt and use the following command to add the NuGet source that will use your new personal access token.

nuget.exe sources add -name {your feed name} -source {your feed URL} -username {anything} -password {your token}

Wrapping Up

It turned out to be pretty easy fix this issue. Don’t be like me and just deal with it by disabling the package sources causing the problem. Just make sure that you don’t check-in your NuGet config file that contains your personal access token.

.NET CLI Errors Due to VSTS Package Source Read More »

.Net CLI Custom Tool

Last week’s post was an overview of the .NET CLI. This week I am going to cover creating a new custom tool for the CLI. This post is going to assume you already has the .NET CLI installed. If not check out last week’s post for instructions.

Getting Started

The tools used by the .NET CLI are just console applications so to begin create a new console application using the CLI with the following commands in a new directory.

dotnet new
dotnet restore

Now that you have a new console application open the new folder up with Visual Studio Code (or the editor of your choice). The tool I am creating will count the files in a project. Very contrived I know, but I wanted to keep this simple and not get distracted by the details of what the tool actually does.

Project.json

The following is the project.json from my file counter tool. The big thing to note is “outputName”: “dotnet-fc” in the buildOptions section. In this example dotnet-fc will make the tool callable from the CLI using dotnet fc. The leading dotnet lets the CLI find the tool and the bit after the dash is the verb that is used with the CLI to execute the tool.

{
  "version": "1.0.0-*",
  "description": "Test creation of a .NET CLI Tool",
  "buildOptions": {
    "emitEntryPoint": true,
    "outputName": "dotnet-fc"
  },
  "dependencies": {
    "Microsoft.NETCore.App": {
      "type": "platform",
      "version": "1.0.0-rc2-3002702"
    }
  },
  "frameworks": {
    "netcoreapp1.0": {}
  }
}

Program.cs

The following is the actual code from the tool that counts the number of files. Again I don’t want this to be the focus of the post, but I am including it for completeness.

using System;
using System.IO;
using System.Linq;

namespace ConsoleApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var fileCount = Directory
                                .EnumerateFiles(Directory.GetCurrentDirectory(), 
                                                "*.*", 
                                                SearchOption.AllDirectories).Count();
            Console.WriteLine($"{Directory.GetCurrentDirectory()} continas {fileCount} files");
        }
    }
}

The console write line is using string interpolation if you have not see it before check out this page.

NuGet

Now that the application is complete use the .NET CLI to create a NuGet package out of it. This functionality is built in to the CLI via the pack command.

dotnet pack

Inside your project directory the NuGet package can be found in the bin directory under either Debug or Release depending on what type of build was done. In my case the project is FileCounter so pack produced FileCounter.1.0.0.nupkg in the bin\Debug directory.

The next step is to add a new package source to your NuGet.Config file which can be found (on Windows) in the C:\Users\YourUser\AppData\Roaming\NuGet directory. In the packageSources section add a new key and value for the directory you want to use for the source of the new tool. The following is my complete NuGet.Config with a new source for “local”.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
	<add key="local" value="C:\NuGetLocal" />
  </packageSources>
</configuration>

Using the New Tool

Open the project that you want to use the new tool with using Visual Studio Code (or any text editor). The new tool will need to be added to the tools section of the project.json file. The following is an example of a full project.json as it exits from using dotnet new with an added tools section.

{
  "version": "1.0.0-*",
  "buildOptions": {
    "emitEntryPoint": true
  },
  "dependencies": {
    "Microsoft.NETCore.App": {
      "type": "platform",
      "version": "1.0.0-rc2-3002702"
    }
  },
"tools": {
    "FileCounter": {
       "version": "1.0.0"
    }
},
  "frameworks": {
    "netcoreapp1.0": {
      "imports": "dnxcore50"
    }
  }
}

Now from the CLI do a dotnet restore and the new tool should be ready to use. In the case of this example you can now run dotnet fc and get a count of the files in your project’s directory.

Lessons Learned

This was the first time I had worked with local NuGet packages and I spent a good bit of time learning where to find the NuGet.Config and the local NuGet caches (C:\Users\YourUser\.nuget\packages and C:\Users\YourUser\.nuget\packages\.tools) were located and the proper edits to make.

The other big thing I would do different the next time around would to be to take advantage of the fact that the .NET CLI will find tools that are on the system path. During development it would have been much simpler than having to go clear the local NuGet caches or change the version number of the tool.

Update

Code used in this post can be found in this GitHub repo.

.Net CLI Custom Tool Read More »