【ASP.NET(C#)10】React.js+SQLServerを使ってMVCの環境構築。Next.jsでも挑戦(.NET 6)

※本ページはサイドバーまたは本文内にアフィリエイト広告を利用しています

今回は前回Udemyの動画でReact及びNext.jsを使った環境構築のやり方を学んだので
ASP.NETでReactのNext.jsを使った初期画面の構築を行いたいと思います。

Udemy動画でReactを学んだ動画は以下を参照

上記を学んでいれば環境構築は問題ありませんが、もしやっていない場合、Node.jsを事前にインストールしておいてください。(npmコマンドなどを使います)
インストールされているか確かめるのはVS上のターミナルかPowerShellでnodeと入力すればOKです。

ここではNode.jsの説明は割愛致します。

環境構築

プロジェクトでReact.jsでのASP.NET Core

最初の新規プロジェクトでReact.jsでのASP.NET Coreを選択

参考サイトを参考に環境を構築

以下の参考サイトを利用すると環境構築できます。ただ、少し違う所があるので後述にあげておきます。

Visual Studio 2019で 最新の React(Next.js) + TypeScript + ASP.NET Core を簡単に構築

  • 今回はNode.jsを使った環境構築をしているため、yarn でなく npmを使っている
  • 3.のTypeScriptを入れるかどうかを十字キーの左右で入れ替える
  • 6.Startup クラスは.NET6ではProgram.csに統合されているため対応方法が違う
  • 7はnpmを使用する場合は対応不要。Package.jsonによって npm devはnext devなど、Next.jsを使ったものに書き替わるため。
  • 8.の起動するの所はVisual Stdioの実行ボタンでOK
  • 3.のTypeScriptは指定しなくてもOK

Startup クラスは.NET6ではProgram.csに統合されているため対応方法が違う

こちらに関しては下記記事を参照してください。.NET 6 ではCore 3.1 と違って、StartUp.csが存在しません。

まず、事前にNugetパッケージマネージャーで下記をいれてください。

・Numind.AspNetCore.SpaServices.Extensions(Microsoft.AspNetCore.SpaProxyも自動でインストールされる)

そしてProgram.csに上記を足します。

省略
・
・
・

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

app.UseSpa(spa =>
{
    spa.UseProxyToSpaDevelopmentServer("http://localhost:3000");
});

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

app.MapFallbackToFile("index.html"); ;

app.Run();

ただ、これだけだとダメで.csprojのSpaProxyServerUrlとSpaProxyLaunchCommandも変更します。(npm startだとビルドしてないと立ち上がらないため)

プロジェクト名.csproj

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
    <TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
    <TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
    <IsPackable>false</IsPackable>
    <SpaRoot>ClientApp\</SpaRoot>
    <DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules\**</DefaultItemExcludes>
    <SpaProxyServerUrl>http://localhost:3000</SpaProxyServerUrl>
    <SpaProxyLaunchCommand>npm run dev</SpaProxyLaunchCommand>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

起動

上記が終わったら VSのデバッグ開始ボタンを押して下記のようなスタート画面が表示されたらそのURLにアクセスすれば初期画面が立ち上がります。

React.jsでMVCを実現(Next.js未使用)

React(npx create-react-app xxxx で作り直した時は後述の通りReactプロジェクト初期状態のファイルの一部が必要)の場合は既存のControllerに入っているweatherforecastを参照できたのでMVCの形式でも問題なさそうです。

ただ、その後画面への表示を試みたのですが、
ncaught (in promise) SyntaxError: Unexpected token ‘<‘, “<!DOCTYPE “… is not valid JSON
のエラーに悩まされ、解決できず断念・・・。他サイトを見たのですが問題解決に至らず。といった感じです。

↑上記エラーですが、Reactプロジェクト初期状態で存在していたsetupProxy.jsを入れたら解決できました。それ以外ではpackage.json(http-proxy-middlewareを入れる)/aspnetcore-react.js/aspnetcore-https.jsもReactプロジェクト初期状態のソースから移動

const { createProxyMiddleware } = require('http-proxy-middleware');
const { env } = require('process');

const target = env.ASPNETCORE_HTTPS_PORT ? `https://localhost:${env.ASPNETCORE_HTTPS_PORT}` :
    env.ASPNETCORE_URLS ? env.ASPNETCORE_URLS.split(';')[0] : 'http://localhost:11038';

const context =  [
  "/weatherforecast",
  "/home", ← この後の説明で必要なので追加
];

module.exports = function(app) {
  const appProxy = createProxyMiddleware(context, {
    target: target,
    secure: false,
    headers: {
      Connection: 'Keep-Alive'
    }
  });

  app.use(appProxy);
};

SQLServerの使用

今回のサーバーサイドは過去記事に習って作成しておりますので省略します。今回は↓の記事のサーバサイド側から今回用に変えた箇所を表示します。

HomeController.cs(HttpGetの所だけ下記のように変更)

        // GET: Article
        [HttpGet]
        public  IEnumerable<TestDb> Get()
        {
            return _context.TestDb.ToArray();
        }

以降はReact側を変更

以降はReactプロジェクト初期状態のソースのようにfetchを使えばアクセスすることができます。今回はReactの記法に乗っ取り、一回だけ自動で呼ばれるように作成したuseEffectを使って情報を取得し、useStateに格納したものをコンポーネントであるBodyに対してpropsを渡して表示させました。

フォルダ構成

ClientApp/src/App.js

import './App.css';
import { useState, useEffect } from 'react';
import Body from "./Components/body";

function App() {
    const [ articles, setArticles] = useState([]);

    useEffect(() => {
        const getArticles = async () => {
            const result = await fetch('home').then(res => res.json());

            setArticles( result );
        };
        getArticles();
    }, []);

    return (
        <>
            <Body articles={articles} />
        </>
    );
}

export default App;

ClientApp/Components/body.js

import React from 'react';

const Body = ({ articles }) => {

    if (!articles) {
        return <div>データがありません</div>
    }

    return (
        <div className="App">
            <table className='table table-striped' aria-labelledby="tabelLabel">
                <thead>
                    <tr>
                        <th>ID</th>
                        <th>Descrition</th>
                        <th>UpdateTime</th>
                    </tr>
                </thead>
                <tbody>
                    {articles.map((article) => (
                        <tr key={article.id}>
                            <td>{article.id}</td>
                            <td>{article.test}</td>
                            <td>{article.update_Time}</td>
                        </tr>
                        ))}
                </tbody>
            </table>
        </div>
    );
};

export default Body;

実行結果

今回はReact.jsを使ってSQLServerの内容を表示することができました。

Next.jsだとMVCの型にはできなさそう

ただ、Next.jsを使った場合はReactの時に参照できていたControllerが参照できなかったです。

Next.jsのAPIから自サーバにアクセスしてもDBの値が取得できないのでMVCの型が破綻してしまってました。Next.jsには別途:next.config.js/jsconfig.jsonというファイルがあるのでpackage.jsonではなく、上記をいじるのかもしれませんが今の所原因が不明です。

先ほど、React側で行った、Fetchに変更しての取得も試みましたがやはりうまくいきませんでした。(404が返っている

色々調べましたがやはりNext.jsの記述は少なく、MVCの型での表示は失敗しました。

もしASP.NETでNEXT.jsを使いたいなら、フロント側とバックエンド側で使用サーバを分けるしかなさそうです。React.jsならMVCの型でも問題なく動作させることができます。

気に入ったらシェアお願いします!

【イナコーシステムからのお知らせ】

読者様への返礼特典付き投げ銭サービス

金額に応じて特典の実用性がUP!

  • ○あなたの名前を半永久的に残せる!
  • ○あなたのブログ/動画チャンネル紹介記事を執筆・サイドバーのリンクエリアに掲載!
  • ○あなたの悩み(エンジニア、ブログなど)を通話付きでアドバイス/サポート。回数制限なし!