LoginSignup
65
7

JavaエンジニアがASP.NET Coreを触ってみた

Last updated at Posted at 2023-12-17

はじめに

このテーマで投稿しようと思ったきっかけ

単純に仕事で.NETのスキルが必要になったからである。
筆者はエンジニア歴のうち半分以上はJava案件(10年くらい?)に関わってきた。
Javaと.NETはほぼほぼ似ている(≒?)と言われますが、コーディング部分において実際にどのくらいJava(主にSpringBoot)の経験が活かせ、何が違うのかが気になったので、実際に.NETを触ってみようと思った。
もし、同様のことを気になったエンジニアがいたら参考になれば幸いである。

軽く.NETとは

.NETは説明不要なほど人気な言語なのでざっと要約すると以下のような特徴がある。

  • Webアプリケーションの開発が容易
  • 複数のプログラミング言語に対応(C#, VB.NETなど)
  • 開発コストを抑えられる
  • クロスプラットフォームに対応(Windows, Mac, Linux)

最後のクロスプラットフォームに対応は筆者にとって驚きだった。
2000年代はWindowsしか使えませんでした。ところが2016年ごろから.NET Coreがリリースされてから急激に進化した模様。(全然追ってなかった・・・)
開発手法も以下のように定義されてる。

  • 昔ながらのMVCモデル
  • 今やASP.NETの基本Razorページ
  • 新時代の開発手法Blazor

軽く環境構築から

まずはスペック

というわけで軽く環境構築してみようと思います。ちなみに今回は以下のような環境で整えてみようと思う。

  • OS: MacOS Ventura(13)
  • Visual Studio Code
  • .NET Core6.0(当時のLTS)

ちなみにMacにもVisual Studioがあるが2024年夏にサポート終了するようなので今回はVisual Studio Codeで整えてみる。

インストールや諸々

  • .NET 6.0のダウンロード

    インストールしたらまずターミナルでdotnetコマンドを通す。

    ln -s /usr/local/share/dotnet/dotnet /usr/local/bin/
    

    dotnet コマンドを用いてインストール状態を確認

    $ dotnet --version
    > 6.0.417
    $ dotnet --list-sdks
    > 6.0.417
    $ dotnet --list-runtimes
    > Microsoft.AspNetCore.App 6.0.25
    > Microsoft.NETCore.App 6.0.25
    

  • VSCodeのインストール
    公式サイトからインストールして展開するだけ。
    VSCodeをインストールしたらC# のプラグインをVSCodeのマーケットプレイスからインストールしてください。
    image.png
    必須ではありませんがコマンドパレット(command+shit+p)で以下のプラグインを入れておくと便利です。

    • デバッグ

      • Download .Net Core Debugger
    • code コマンド

      • Install 'code' command in PATH

Razorアプリを作ってみる

記事のテーマの意図、検証したいこと

ここで記事のテーマになるんですが、Javaに慣れすぎたエンジニアが.NETが必要になったらどれだけ違和感なく溶け込むことができるのか?全く新しく覚える必要がある要素は何か?をRazorアプリを作りながら整理したいと思います。

Razorページプロジェクトを作成

VisualStudioCodeのターミナルdotnetコマンドを使ってRazorページプロジェクトを作成します。
作成したプロジェクトをcode コマンドを使って開きます。

dotnet new webapp -o FirstRazorApp
code FirstRazorApp

VisualStudioCodeが起動し、プロジェクトを開く。
image.png

VisualStudioCodeのターミナルを開き、dotnet runを実行。
image.png

http://localhost:5075 を実行しすると画面が開けることが確認できる。
image.png

プロジェクト構成

 
構成 説明
Pagesフォルダ ページ関連のファイルを配置。
Sharedフォルダ 画面レイアウトやエラーメッセージ画面など共通画面レイアウトを配置
Propertiesフォルダ ランチャの設定など
wwwrootフォルダ ページが参照するリソースを配置
Program.cs プロジェクトを起動するときの最初に実行するプログラム
SpringBoot でいうSpringBootApplication.javaような
拡張子 説明
.cshtml テンプレートファイル
.cshtml.cs Modelクラス

Razorページの利用

入力フォームRazorページを新規作成し、画面を表示するまで実装してみる。
dotnet new page -n {名前} -o {場所} -p:n {名前空間} を使ってpageを生成する。

dotnet new page -n InputForm -o Pages -p:n FirstRazorApp

image.png

ここから簡単な入力フォームを書いていく。まずはモデルクラス。

InputForm.cshtml.cs
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace MyApp.Namespace
{
    public enum Genders
    {
        male,
        female
    }

    public enum PlatformItems
    {
        Windows,
        macOS,
        Linux,
        ChromeOS,
        Android,
        iOS
    }

    public class InputFormModel : PageModel
    {
        [BindProperty(SupportsGet = true)]      // クエリパラメータとバインド
        public int Id {get; set;}

        public string? Message {get; set;}      // 型の後に?をつけるとNull許容型で宣言
        [DataType(DataType.Text)]
        public string? Name {get; set;}
        [DataType(DataType.EmailAddress)]
        public string? Mail {get; set;}
        [DataType(DataType.PhoneNumber)]
        public string? TelNumber {get; set;}
        public bool CheckBox {get; set;}
        public Genders Gender {get; set;}
        public PlatformItems Platform {get; set;}

        public void OnGet()
        {
            Message = "何か入力してみて!";
        }

        // Post処理時、同名の変数にフィールドの入力値をそれぞれバインドされる。
        public void OnPost(int id, string name, string mail, string telNumber, bool checkbox, 
            string gender, PlatformItems platform)
        {
            Message = string.Format("[Id: {0}, Name: {1}, Mail: {2}, Tel: {3}, CheckBox: {4}, Gender: {5}, Platform: {6}]", 
                id, name, mail, telNumber, checkbox, gender, platform);
        }
    }
}

コードを書いてみたけど以下の2点におっ?と反応。

  • public string? Message {get; set;} の型の後ろに?にあるのは?
  • 変数名の命名

型の後ろに?を付けるのはNull許容型の宣言を指す。.NETでは変数宣時にNull許容を定義するのでコンパイル時にヌルポが発生する可能性のある変数に対して警告が発生し検出しやすくなった。
Javaではそのような仕組みはなくNullPointerException が発生した際の犯人探しに結構苦労したことは良い思い出だが、Javaと親和性の高いKotolinでは.NETと同様にヌルポ思想は実現している。
変数名のjavaでは頭文字が小文字から始まるに対して.NETでは頭文字が大文字から始まっている。
他にもimport句がusingであったり、JavaではDIをアノテーションで定義するの対して、.NETでは[]で定義するなど若干違ってたりするが、コーディングに関して大きく違和感を感じることもなかった。

では、続いてテンプレートファイル。

InputForm.cshtml
@page "{id?}"
@model MyApp.Namespace.InputFormModel
@{

}

<div>
    <h1 class="dispaly-4">Welcome</h1>
    <p class="h4">@Model.Message</p>
    @using (Html.BeginForm())
    {
        <div class="form-group">
            @Html.DisplayName("Id")
            @Html.LabelFor(model => model.Id)
        </div>
        <div class="form-group">
            @Html.DisplayName("Name")
            @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control"} })
        </div>
        <div class="form-group">
            @Html.DisplayName("Mail")
            @Html.TextBoxFor(model => model.Mail, @Model.Mail, new { @class = "form-control" })
        </div>
        <div class="form-group">
            @Html.DisplayName("TelNumber")
            @Html.TextBoxFor(model=>model.TelNumber, new { @class = "form-control" })
        </div>
        <div class="form-group">
            <label class="form-label h5">
                @Html.CheckBoxFor(model => model.CheckBox, new { @class = "form-check-input"})
                @Html.DisplayName("CheckBox1")
            </label>
        </div>
        <div class="form-group">
            <label class="form-label h5">
                @Html.RadioButtonFor(model => model.Gender, MyApp.Namespace.Genders.male,  
                    new { @class = "form-check-input"})
                @Html.DisplayName("male")
            </label>
        </div>
        <div class="form-group">
            <label class="form-label h5">
                @Html.RadioButtonFor(model => model.Gender, MyApp.Namespace.Genders.female,  
                    new { @class = "form-check-input"})
                @Html.DisplayName("female")
            </label>
        </div>
        <div class="form-group">
            <label class="form-label h5">
                @Html.DisplayName("Platform")
                @Html.DropDownListFor(model => model.Platform, 
                    new SelectList(Enum.GetValues(typeof(MyApp.Namespace.PlatformItems))), 
                    new { @class = "form-control"})
            </label>
        </div>
        <input type="submit" class="btn btn-primary" value="送信">
    }
</div>

テンプレートファイルはモデルクラスとテンプレートファイルとバインドが可能であったりとSpringBootのテンプレートエンジンであるThymeleafほぼ似通ってるのであまり違和感は感じることもなかった。
ちなみにコンパイルすると以下のような画面に仕上がる。
image.png

入力して「送信」すると。。。
image.png

入力した内容を表示するまでができた。
今回はここまでで。。。

あとがき

Javaエンジニアが実際に.NETで開発環境構築+簡単なWebアプリを実装するまで学習してみたところの感想

  • ヌルポ防止策に.NETでは変数宣言時にNull許容を定義するんで活用方法についてもう少し深掘りが必要。
  • 変数名の命名が異なるので.NETのお作法を覚える必要があるのと使い分けられる慣れが必要。
  • Razorアプリ≒SpringBoot?でほぼほぼSpringBootじゃん。

SpringBootの開発経験があればそんなに遜色なく.NETでも通じそうな印象。
尚、今回はBlazorアプリやNuGetやスキャフォールディングなどDB系は触れなかったが、今後の学習のテーマに。。。
ここまでの学習時間は6時間程度。

ここまで読んでいただいてありがとうございました。以上。

参考文献

65
7
2

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
65
7