0
0

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 1 year has passed since last update.

タスク管理ツールをReact + ASP.Coreで作る 03サンプルAPIのデータをクライアントサイドで表示する

Last updated at Posted at 2022-10-24

前回の続きです

前回までで、webapiと、クライアントサイドの双方のひな型を作りました。
今のところどちらもテンプレートから生成したままで、プロジェクトが生成されて開発環境が立ち上がることの確認までが出来た状態です。

ここから、サーバーサイドのwebapiのデータをクライアントで表示する機能を作っていこうと思います。

index

今回やること

  • サーバーサイド
    • 別ドメインからのアクセスを許容する
  • クライアントサイド
    • webapiからデータを取得して表示するコンポーネントを作る
    • メイン画面から作ったコンポーネントを呼び出す

サーバーサイドの更新(Startup.csを変更して別ドメインからのアクセスを許容)

ASP.NET Coreは、初期状態だと別ドメインからのアクセスを制限する設定がされています。
元々はCSRF等の攻撃に対策するための機能ですが、今回のアプリではサーバーサイドとクライアントサイドでドメインが異なるので、初期設定のままだとクライアントからのアクセスも制限されてしまいます。
そのため、以下の様にStartup.csを変更して、別ドメインからのアクセスを許容する設定を行います。

Startup.cs
Startup.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;

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

        public IConfiguration Configuration { get; }

+       readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

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

            services.AddControllers();
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "server_app", Version = "v1" });
            });


+            services.AddCors(o => o.AddPolicy(MyAllowSpecificOrigins, builder =>
+            {
+                builder.AllowAnyOrigin()    // Allow CORS Recest from all Origin
+                       .AllowAnyMethod()    // Allow All Http method
+                       .AllowAnyHeader();   // Allow All request header
+            }));

        }

        // 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();
                app.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "server_app v1"));
            }

            app.UseHttpsRedirection();

            app.UseRouting();

+            app.UseCors(MyAllowSpecificOrigins);   // Add For CORS
+
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

クライアントサイドの更新(WEB APIからデータを取得する機能と、それをメイン画面に表示する)

クライアントサイドに、サーバーサイドのAPI「WeatherForecast」からデータを取得し、テーブルに表示するコンポーネント「WeatherForecast.tsx」を作り、またApp.tsxでそれを呼び出します。

WeatherForecast.tsx
WeatherForecast.tsx
import { useEffect, useState } from 'react';

interface Forecast {
  date: Date;
  temperatureC: number;
  temperatureF: number;
  summary: string;
}

export const WeatherForecast = () => {
    
    
    const [loading, setLoading] = useState(true);
    const [forecasts, setForecast] = useState<Forecast[]>();
  
    useEffect(() => {
        populateWeatherData();
    }, []);
  
    const populateWeatherData = async () => {
        const response = await fetch('https://localhost:5001/weatherforecast');
        const data = await response.json();
        setForecast(data);
        setLoading(false);
    };
    
    if(loading) return <div>loading....</div>

    return (
        <div>
            <h1 id="tabelLabel">Weather forecast</h1>
            <p>This component demonstrates fetching data from the server.</p>
            <table className="table table-striped" aria-labelledby="tabelLabel">
                <thead>
                <tr>
                    <th>Date</th>
                    <th>Temp. (C)</th>
                    <th>Temp. (F)</th>
                    <th>Summary</th>
                </tr>
                </thead>
                <tbody>
                {forecasts && forecasts.map((forecast) => (
                    <tr key={forecast.date.toString()}>
                    <td>{forecast.date.toString()}</td>
                    <td>{forecast.temperatureC}</td>
                    <td>{forecast.temperatureF}</td>
                    <td>{forecast.summary}</td>
                    </tr>
                ))}
                </tbody>
            </table>
        </div>
    )
}
App.tsx
App.tsx
import React from 'react';
import logo from './logo.svg';
import './App.css';
import { FetchData } from './WeatherForecast';

function App() {
  return (
-    <div className="App">
-      <header className="App-header">
-        <img src={logo} className="App-logo" alt="logo" />
-        <p>
-          Edit <code>src/App.tsx</code> and save to reload.
-        </p>
-        <a
-          className="App-link"
-          href="https://reactjs.org"
-          target="_blank"
-          rel="noopener noreferrer"
-        >
-          Learn React
-        </a>
-      </header>
-    </div>
+    <div>
+      <WeatherForecast />
+    </div>
  );
}

export default App;

実行結果

image.png

今回は以上です
続きは次回です

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?