LoginSignup
0
0

MVCをWeb作成から理解する。

Posted at

処理フロー

  1. ログイン画面を初期表示
  2. ログイン画面からサインアップ画面に移動
  3. アカウント登録を行い、サインイン画面に移動
  4. 作成したアカウントでサインイン

開発環境

IDE Visual Studio
フレームワーク .Net Core
バックエンド C#
フロントエンド Html Css JavaScript
DB My Sql
DB操作 Linq
Webサーバ Apache Tompat

クライアントとApacheの間にTomcatを挟むことでアクセス数が多くなった場合も対応できるようになるため。

SDK 

.NET SDK をダウンロードする(.NET Coreを扱うために必要)
https://dotnet.microsoft.com/ja-jp/download/visual-studio-sdks

Entity Framework Core

.NET Coreの中のMVCの構造を再現するためのMVCフレームワーク

NuGet
image.png

ファイル構成

ファイル構成を開く

プロジェクト名
├Migrations
├Model
│├ Book.cs
│└ User.cs
├Pages
│└Shared
│ ├ Index.cshtml ー (View)
│ │└ Index.cshtml.cs ー (Service)
│ ├ LoginPage.cshtml
│ │ └ LoginPage.cshtml.cs
│ ├ Mypage.cshtml
│ │└ Mypage.cshtml.cs
│ ├ privacy.cshtml
│ │ └ privacy.cshtml.cs
│ └ SignUp.cshtml
│ └ SignUp.cshtml.cs
├ViewModel
│├LoginPageVModel.cs
│├MypageVModel.cs
│└SignUpVModel.cs
├appsettings.json
├MyContext.cs
└Program.cs

ファイル構成詳細

image.png
image.png

DBとMVCの関係性

全体のデータ流れ図

image.png

部分的に切り分けて理解していく

ModelーDBのテーブルにあたる役割

サンプルコード

Modelの記述方法(book.cs User.cs)

User.cs
using Microsoft.AspNetCore.Identity;
using System.ComponentModel.DataAnnotations;

namespace MvcEx0421.Model
{
    public class User : IdentityUser
    {
    }
}

IdentityUser(.NET Coreの機能)

IdentityUserを継承することで、ユーザ管理に必要な基本情報をModelに作成できる。
UserModelに基本情報以外のプロパティを定義することができる。

Book.cs
using System.ComponentModel.DataAnnotations;

namespace MvcEx0421.Model
{
    public class Book : User
    {
        [Required]//アノテーション
        [Key]
        [Display(Name = "書籍番号")]
        public int Id { get; set; }

        [Display(Name = "書籍名")]
        public string Name { get; set; }

        //コンストラクタの定義は必ず行う(変数には空を定義)
        public Book()
        {
            Id = 0;
            Name = "";
        }

        //Idが1の時佐藤さんが確定で入る場合はメソッドを定義しておくといい
        public Book(int satouNum = 1)
        {
            Id = BookId;
            Name = "漫画";
        }
    }
}


アノテーション(属性)ー[Key][Display(Name = "書籍番号")]

Modelで定義したプロパティに対し、制限を付けることができる.NET Coreの機能

アノテーション一覧
https://qiita.com/mrpero/items/607c31895d77815a77cb

マイグレーションファイルとは

DBの構成を定義し、DBの生成を一括して行うSQL群をまとめたファイル

マイグレーションファイルを自動生成する手順

  1. 必要なパッケージをインストールする

    • Sqliteを扱うため
      image.png
    • コマンドベースでDBをMigrationしたり、DBFileからDbContextクラスをスキャフォールディングすることが出来ます
      image.png
      スキャフォールディングとは
      データモデルとなる型を元に、いわゆるCRUD(Create/Read/Upadate/Delete)と呼ばれる追加、読込、変更、削除を行う画面とそのコードを自動で生成する機能のことです
  2. MyDbContext.csには下記を定義する

    • DBの接続
    • テーブル
    • テーブル間のリレーション
      • MyDbContextの役割
        • 定義したModelを、MyDbContextで各Modelの関係性と存在を定義すること
        • DBへの接続情報と接続処理を行うこと
  3. マイグレーションファイルの作成

    • パッケージマネージャコンソールにて下記のコマンドを実行
      • EntityFrameworkCore\Add-Migration InitialCreate
      • Add-Migration InitialCreate
  4. マイグレーションファイルの実行

    • パッケージマネージャコンソールにて下記のコマンドを実行
      • EntityFrameworkCore\Update-Database
      • Add-Migration InitialCreate
サンプルコード(MyDbContext.cs)
MyDbContext.cs
using Microsoft.EntityFrameworkCore;
using MvcEx0421.Model;

namespace MvcEx0421
{
    public class MyDbContext : DbContext
    {
        public DbSet<Book> Books { get; set; }
        public DbSet<User> Users { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            var str = $"Server=IPアドレス;" +
             $"Database=original;" +
             $"Uid=root;" +
             $"Pwd=Password";
            optionsBuilder.UseMySql(str
                , ServerVersion.AutoDetect(str)
            );
        }
    }
}

Serviceーバックエンド処理を担う役割

  • DBからModelに値を入れる
  • 対象のViewに遷移する(Get Post)
サンプルコード
Index.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace MvcEx0421.Pages
{
    public class IndexModel : PageModel
    {
        private readonly ILogger<IndexModel> _logger;
        
        public IndexModel(ILogger<IndexModel> logger)
        {
            _logger = logger;
        }

        public IActionResult OnGet()
        {
            return new RedirectResult("/LoginPage");
        }
        //public IActionResult OnGet()
        //{
        //    return new RedirectToPageResult("LoginPage");
        //}
    }
}
MyPage.cs
using System.Linq;
using Microsoft.EntityFrameworkCore;
//using System.Web.Mvc;
using Microsoft.AspNetCore.Mvc;
using MvcEx0421.Pages.Shared;
using MvcEx0421.Model;
using MvcEx0421.ViewModel;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace MvcEx0421.Pages
{
    public class MyPage
    {
        private readonly ILogger<MyPage> _logger;

        public MyPage(ILogger<MyPage> logger)
        {
            _logger = logger;
        }

        [HttpGet]
        public IActionResult Index()
        {
            return new ViewResult();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public void OnGet(MyDbContext DbContext, int Id){}
        
        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult SignUp(string Id, string Name)
        {
            ///対象のテーブルのコンストラクタの定義
            MyPageVModel vmMyPage = new MyPageVModel();
            ///行の値を定義
            vmMyPage.Id = Id;
            vmMyPage.Name = Name;

            return new ViewResult();
        }
    }
}

LoginPage.cs
//using System.Web.Mvc;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using System.Linq;
using MvcEx0421.Model;
using System.Data;

namespace MvcEx0421.Pages
{
    public class LoginPage
    {
        private readonly ILogger<LoginPage> _logger;
        public LoginPage(ILogger<LoginPage> logger)
        {
            _logger = logger;
        }

        public void OnGet()
        {
            
        }

        public IActionResult OnPostLogIn(String Id, String Name)
        {
            ///DBにアクセスするためのコンストラクタの定義
            var _DbContext = new MyDbContext();

            var userExistence = _DbContext.Users.Any(x => x.Id == Id);
            var user = _DbContext.Users.Where(x => x.Id == Id);

            if (userExistence == true)
            {
                return new RedirectToActionResult("Mypage", "MyPage", user);
            }
            else
            {
                return new ViewResult();
            }
        }
    }
}

SignUp.cs
using System.Linq;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using MvcEx0421.Pages.Shared;
using MvcEx0421.Model;
using Microsoft.AspNetCore.Mvc;

namespace MvcEx0421.Pages
{
    public class SignUp
    {
        private readonly ILogger<SignUp> _logger;

        public SignUp(ILogger<SignUp> logger)
        {
            _logger = logger;
        }

        public void Index()
        {
        }

        public IActionResult OnPostMemberCreate(string Id, string Name)
        {
            ///DBにアクセスするためのコンストラクタの定義
            MyDbContext cx = new MyDbContext();
            ///対象のテーブルのコンストラクタの定義
            User user = new User();
            ///行の値を定義
            user.Id = Id;
            user.UserName = Name;

            ///Model OR ViewModelに値を挿入
            cx.Add(user);

            ///セーブする。
            cx.SaveChanges();

            if (user.UserName == "")
            {
                return new ViewResult();
            }
            else
            {
                return new RedirectResult("/LoginPage");
            }
        }
    }
}

ViewModelー対象のView専用に作成するModel

サンプルコード
MypageVModel.cs
using Microsoft.AspNetCore.Mvc.RazorPages;
using MvcEx0421.Model;

namespace MvcEx0421.ViewModel
{
    public class MyPageVModel : PageModel
    {
        public string UserId { get; set; }
        public string UserName { get; set; }
        public string BookId { get; set; }
        public string BookName { get; set; }

        public MyPageVModel()
        {
            User user = new User();
            UserId = user.Id;
            UserName = user.UserName;

            Book book = new Book();
            BookId = book.Id;
            BookName = book.Name;
        }
    }
}

ViewーWeb画面

サンプルコード
SignUp.cshtml
@page
@model ViewModel.SignUpVModel
<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
</head>
<body>
    <div>
        <form method="POST" >
            <table border="1">
                <tr>
                    <th>Id</th>
                    <!-- name属性「name="name_box"」を設定する事で、遷移先で受け取り可能になる -->
                    <td><input type="text" id="id" name="id" /></td>
                </tr>
                <tr>
                    <th>name</th>
                    <td><input type="text" id="name" name="name" /></td>
                </tr>
            </table>
            <!-- 送信ボタンのtypesubmitを指定する -->
            <input type="submit" asp-page-handler="MemberCreate" value="登録" >
        </form>
    </div>
</body>
</html>

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