6
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ASP.NET MVC を ASP.NET Core MVC にしてみる

Last updated at Posted at 2020-12-01

ふと気になったので ASP.NET MVC を ASP.NET Core MVC にしてみようと思います。とりあえずいきなり巨大なものをコンバートすると心が折れるので ASP.NET MVC のプロジェクトを新規作成したものを、ASP.NET Core MVC に変換するということをやってみようと思います。

とりあえずどれくらい大変なのかを体験するために ASP.NET MVC から ASP.NET Core MVC への移行ドキュメントなどはチェックせずにやってみます。

新規作成したプロジェクトはこんな感じです。packages.config などがあるのがドキっとしますね!

image.png

とりあえず、後から参照が無い系エラーになったとき用に packages.config を消すのは最後にしようと思います。

まずは、プロジェクトファイルを以下の内容に書き換えます。一度プロジェクトをアンロードしてから読み込みましょう。

WebApplication4.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

</Project>

再オープンしてリビルドをしてみると以下のように 22 個のコンパイルエラーが出ました。

error CS0579: 'System.Reflection.AssemblyCompanyAttribute' 属性が重複しています
error CS0579: 'System.Reflection.AssemblyConfigurationAttribute' 属性が重複しています
error CS0579: 'System.Reflection.AssemblyFileVersionAttribute' 属性が重複しています
error CS0579: 'System.Reflection.AssemblyProductAttribute' 属性が重複しています
error CS0579: 'System.Reflection.AssemblyTitleAttribute' 属性が重複しています
error CS0579: 'System.Reflection.AssemblyVersionAttribute' 属性が重複しています
error CS0234: 型または名前空間の名前 'Optimization' が名前空間 'System.Web' に存在しません (アセンブリ参照があることを確認してください)
error CS0234: 型または名前空間の名前 'Mvc' が名前空間 'System.Web' に存在しません (アセンブリ参照があることを確認してください)
error CS0234: 型または名前空間の名前 'Mvc' が名前空間 'System.Web' に存在しません (アセンブリ参照があることを確認してください)
error CS0234: 型または名前空間の名前 'Routing' が名前空間 'System.Web' に存在しません (アセンブリ参照があることを確認してください)
error CS0234: 型または名前空間の名前 'Mvc' が名前空間 'System.Web' に存在しません (アセンブリ参照があることを確認してください)
error CS0234: 型または名前空間の名前 'Mvc' が名前空間 'System.Web' に存在しません (アセンブリ参照があることを確認してください)
error CS0234: 型または名前空間の名前 'Optimization' が名前空間 'System.Web' に存在しません (アセンブリ参照があることを確認してください)
error CS0234: 型または名前空間の名前 'Routing' が名前空間 'System.Web' に存在しません (アセンブリ参照があることを確認してください)
error CS0234: 型または名前空間の名前 'HttpApplication' が名前空間 'System.Web' に存在しません (アセンブリ参照があることを確認してください)
error CS0246: 型または名前空間の名前 'Controller' が見つかりませんでした (using ディレクティブまたはアセンブリ参照が指定されていることを確認してください)
error CS0246: 型または名前空間の名前 'GlobalFilterCollection' が見つかりませんでした (using ディレクティブまたはアセンブリ参照が指定されていることを確認してください)
error CS0246: 型または名前空間の名前 'ActionResult' が見つかりませんでした (using ディレクティブまたはアセンブリ参照が指定されていることを確認してください)
error CS0246: 型または名前空間の名前 'BundleCollection' が見つかりませんでした (using ディレクティブまたはアセンブリ参照が指定されていることを確認してください)
error CS0246: 型または名前空間の名前 'RouteCollection' が見つかりませんでした (using ディレクティブまたはアセンブリ参照が指定されていることを確認してください)
error CS0246: 型または名前空間の名前 'ActionResult' が見つかりませんでした (using ディレクティブまたはアセンブリ参照が指定されていることを確認してください)
error CS0246: 型または名前空間の名前 'ActionResult' が見つかりませんでした (using ディレクティブまたはアセンブリ参照が指定されていることを確認してください)

AssemblyCompanyAttribute などの最初の 6 個のエラーは WPF のプロジェクトを変換したときに見たことがあるエラーですね。AssemblyInfo.cs が自動生成されるようになったため、.NET Framework のプロジェクトにある AssemblyInfo.cs と内容が重複してしまうために起きるエラーですね。

これはプロジェクトファイルに GenerateAssemblyInfo タグを追加して false を設定しましょう。以下のようになります。

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

	<PropertyGroup>
		<TargetFramework>netcoreapp3.1</TargetFramework>
		<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
	</PropertyGroup>

</Project>

不要な using などがあったりする部分もあるので、一旦プロジェクトに対してコードのクリーンナップを実行して綺麗にします。

HomeController クラスには using Microsoft.AspNetCore.Mvc; を追加します。

HomeController.cs
using Microsoft.AspNetCore.Mvc;

namespace WebApplication4.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";

            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }
    }
}

残りのエラーが 4 つになりました。

image.png

どれもアプリの構成系のファイルで起きています。というか Global.asax.cs ってありましたね。懐かしい…

BundleConfig.cs ではスクリプトのバンドルを作ってますが、この機能は ASP.NET Core MVC では見た記憶が無いので無いのでしょう。普通にスクリプトをそのまま参照します。

FilterConfig.cs では HandleErrorAttribute をフィルターに追加しています。RouteConfig.cs はルートの構成ですね。ここらへんは ASP.NET Core MVC では Startup.cs で書くので Startup.cs と エントリーポイントの Program.cs を追加して App_Start フォルダーと Global.asax は消してしまいます。

追加したファイルは以下の 2 つです。手っ取り早く ASP.NET Core MVC のプロジェクトを新規作成して、そこからコピペしてきました。

Program.cs
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

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

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}
Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace WebApplication4
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

この状態でビルドするとエラーが以下の内容に変化しました!何かのエラーを解決する調査をしているときもそうですけど、エラー内容が変わると進捗を感じますね!

image.png

これはスクリプトバンドルが無くなったせいですね。なので、Conetnt フォルダーの中身を wwwroot/css に移動させて Scripts フォルダーを wwwroot/js フォルダーに移動させて、fonts フォルダーを wwwroot/fonts に移動させて favicon.icowwwroot フォルダーに移動させます。

以下のようになりました。

image.png

そしてエラーの出ている _Layout.cshtml を以下の内容から

_Layout.cshtml
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - マイ ASP.NET アプリケーション</title>

    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
</head>
<body>
    <div class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                @Html.ActionLink("アプリケーション名", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li>@Html.ActionLink("ホーム", "Index", "Home")</li>
                    <li>@Html.ActionLink("詳細", "About", "Home")</li>
                    <li>@Html.ActionLink("問い合わせ", "Contact", "Home")</li>
                </ul>
            </div>
        </div>
    </div>
    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; @DateTime.Now.Year - マイ ASP.NET アプリケーション</p>
        </footer>
    </div>

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    @RenderSection("scripts", required: false)
</body>
</html>

直接ファイルを参照するように変更します。

_Layout.cshtml
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - マイ ASP.NET アプリケーション</title>

    <link rel="stylesheet" href="~/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/bootstrap-theme.min.css" />
    <link rel="stylesheet" href="~/css/Site.css" />
</head>
<body>
    <div class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                @Html.ActionLink("アプリケーション名", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li>@Html.ActionLink("ホーム", "Index", "Home")</li>
                    <li>@Html.ActionLink("詳細", "About", "Home")</li>
                    <li>@Html.ActionLink("問い合わせ", "Contact", "Home")</li>
                </ul>
            </div>
        </div>
    </div>
    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; @DateTime.Now.Year - マイ ASP.NET アプリケーション</p>
        </footer>
    </div>

    <script src="~/js/jquery-3.4.1.min.js"></script>
    <script src="~/js/jquery.validate.min.js"></script>
    <script src="~/js/jquery.validate.unobtrusive.min.js"></script>
    <script src="~/js/bootstrap.min.js"></script>
    <script src="~/js/modernizr-2.8.3.js"></script>
    @RenderSection("scripts", required: false)
</body>
</html>

この時点でビルドするとエラーが消えます。とりあえずデバッグ実行してみましょう。

あっ、動いた…

image.png

詳細ページや問い合わせページも動きました。

image.png

もうちょっと詰まるかと思ったら思ったよりあっさりいってびっくりしました。

ASP.NET から ASP.NET Core への移行ドキュメントを見てもアプローチは異なりますが、やっていることは大体同じでした。.NET Framework でなくなった機能を踏んでいない限りは割と機械的に移植できそうですね。

ASP.NET MVC から ASP.NET Core MVC への移行

6
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?