Migration project.json to csproj format (C#)

ในช่วงการพัฒนาของ .NET Core tooling จนถึงปัจจุบัน มี design/component หลายอย่างที่มีการเปลี่ยนแปลงในลักษณะที่ไม่ compatible กับ version ก่อนหน้า หรือยกเลิกการใช้งาน หนึ่งในนั้นก็คือ project config file ที่เริ่มต้นใช้รูปแบบ json ซึ่งอยู่ใน file ที่ชื่อ project.json แต่ปัจจุบัน เปลี่ยนมาใช้ MSBuild/csproj format

การ migration project.json ไปสู่ .csproj format ทำได้ด้วยกันสองวิธีคือ

  • Visual Studio 2017
  • dotnet migrate command-line tool

ทั้งสองวิธีใช้กลไกการทำงานเดียวกัน ซึ่งผลที่ได้จะเหมือนกัน

Visual Studio 2017

เปิด project โดยเปิด file .xproj ใน Visual Studio 2017 จะปรากฎ One-way upgrade dialog ขึ้นมาให้เลือก OK, Visual Studio จะทำการ migrate โดย file ที่ถูก migrate (project.json, global.json, .xproj) จะถูกย้ายไปสำรองไว้ใน folder Backup

dotnet migrate

ใช้ command-line เข้าไปที่ folder ที่เก็บ project และใช้คำสั่ง dotnet migrate ซึ่งจะทำการ migrate โดย file ที่ถูก migrate (project.json, global.json, .xproj) จะถูกย้ายไปสำรองไว้ใน folder Backup

<Project Sdk="Microsoft.NET.Sdk">
  ... 
</Project>

ข้อแตกต่างระหว่าง project.json กับ csproj format ( อยู่ในรูปแบบ XML-based ซึ่งมี root node ระบุ sdk ที่ใช้คือ Microsoft.NET.Sdk สำหรับ web project sdk ที่ใช้คือ Microsoft.NET.Sdk.Web ) มีดังนี้

Common options

****** JSON format ******
{
  "name": "MyProjectName",
  "version": "1.0.0-alpha-*",

  "authors": [ "name1", "name2" ],
  "company": "PSU",
  "language": "en-US",
  "title": "My library",
  "description": "This is my library.",
  "copyright": "PSU 3000",
  "userSecretsId": "xyz123"
}
****** csproj format ******
<PropertyGroup>
 <AssemblyName>MyProjectName</AssemblyName>
 <PackageId>MyProjectName</PackageId>
 <VersionPrefix>1.0.0</VersionPrefix>
 <VersionSuffix>alpha</VersionSuffix>

 <Authors>name1;name2</Authors>
 <Company>PSU</Company>
 <NeutralLanguage>en-US</NeutralLanguage>
 <AssemblyTitle>My library</AssemblyTitle>
 <Description>This is my library.</Description>
 <Copyright>PSU 3000</Copyright>
 <UserSecretsId>xyz123</UserSecretsId>
</PropertyGroup>

frameworks

****** JSON format ******
{
  "frameworks": {
    "netcoreapp1.0": {},
    "net451": {}
  }
}
****** csproj format ******
<PropertyGroup>
 <TargetFrameworks>netcoreapp1.0;net451</TargetFrameworks>
</PropertyGroup>

dependencies

****** JSON format ******
{
  "dependencies": {
    "NETStandard.Library": "1.6.0",
    "Microsoft.AspNetCore": "1.1.0",

    "MyOtherProject": "1.0.0-*",
    "AnotherProject": {
      "type": "project"
    }
  }
}
****** csproj format ******
<PropertyGroup>
 <NetStandardImplicitPackageVersion>1.6.0</NetStandardImplicitPackageVersion> 
</PropertyGroup>

<ItemGroup>
 <PackageReference Include="Microsoft.AspNetCore" Version="1.1.0" /> 
</ItemGroup>

<ItemGroup>
 <ProjectReference Include="..\MyOtherProject\MyOtherProject.csproj" />
 <ProjectReference Include="..\AnotherProject\AnotherProject.csproj" /> 
</ItemGroup>

tools

****** JSON format ******
{
  "tools": {
    "Microsoft.EntityFrameworkCore.Tools.DotNet": "1.0.0-*"
  }
}
****** csproj format ******
<ItemGroup>
 <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0" /> 
</ItemGroup>

buildOptions

****** JSON format ******
{
  "buildOptions": {
    "emitEntryPoint": true
    "warningsAsErrors": true,
    "nowarn": ["CS0168", "CS0219"],
    "xmlDoc": true,
    "preserveCompilationContext": true,
    "outputName": "Different.AssemblyName",
    "debugType": "portable",
    "allowUnsafe": true,
    "define": ["TEST", "OTHERCONDITION"]
  }
}
****** csproj format ******
<PropertyGroup>
 <OutputType>Exe</OutputType>
 <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
 <NoWarn>$(NoWarn);CS0168;CS0219</NoWarn>
 <GenerateDocumentationFile>true</GenerateDocumentationFile>     
 <PreserveCompilationContext>true</PreserveCompilationContext> 
 <AssemblyName>Different.AssemblyName</AssemblyName>
 <DebugType>portable</DebugType> 
 <AllowUnsafeBlocks>true</AllowUnsafeBlocks> 
 <DefineConstants>$(DefineConstants);TEST;OTHERCONDITION</DefineConstants>
</PropertyGroup>

testRunner

****** JSON format ******
{
  "testRunner": "xunit",
  "dependencies": {
    "dotnet-test-xunit": ""
  }
}
****** csproj format ******
<ItemGroup>
 <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0-*" />
 <PackageReference Include="xunit" Version="2.2.0-*" />
 <PackageReference Include="xunit.runner.visualstudio" Version="2.2.0-*" /> 
</ItemGroup>

อ้างอิง : https://docs.microsoft.com/en-us/dotnet/core/tools/project-json-to-csproj