.Net Core 3.0 (Blazor) で出来ること（随時更新）

.Net Core 3.0 (Blazor) で出来ること（随時更新） Last Update 2019/3/20


Source Code on Github : [DotNetCore3Sample](https://github.com/Ohurochan/DotNetCore3Sample)

## Goal
Blazorで出来ることを実際に試しつつ把握する。
→プロダクト運用への備え。

## Requirements.
- .Net Core3.0 Preview 3 [公式](https://dotnet.microsoft.com/download/dotnet-core/3.0)
- Visual Studio 2019 Preview (上記リンク参照)
- Blazor 0.9.0 [公式ブログ参照](https://devblogs.microsoft.com/aspnet/blazor-0-9-0-experimental-release-now-available/)※ここに記載の導入手順が完了していること

## Setup Project


### Choose Blazor Project

- Choose "Blazor (ASP.NET Core hosted)"
- Check ".Net Core" and "ASP.NET Core 3.0" are selected.
![image.png](https://qiita-image-store.s3.amazonaws.com/0/381067/4fd0332c-e2e7-b30a-f477-2d0edf7d5ce6.png)

## Example1. Open/Close Bootstrap Modal from C# 

### step1. Input Bootstrap Refs and Custom js method to your [wwwroot]->index.html

- In \<head>~\</head>

```html
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
```

- In \<body>~\</body>

```html
<script src="js/Examples.js"></script>
```

Like this (index.html)

```html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width">
    <title>DotNetCore3Sample</title>
    <base href="/" />
    <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
    <link href="css/site.css" rel="stylesheet" />


    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
</head>

<body>
    <app>Loading...</app>

    <script src="_framework/components.webassembly.js"></script>

    <!-- Load Example Functions -->
    <script src="js/Examples.js"></script>

</body>
</html>

```

### Step2. Create Example.js and Input below code

- Make a Example.js to [Client]Project -> [wwwroot]-> [js] Folder
![image.png](https://qiita-image-store.s3.amazonaws.com/0/381067/fd33191c-a720-2ce1-ca0f-c65cc985d754.png)

- Input below codes to Example.js

```javascript

    <script>
        async function CloseModalById(idname) {
            console.debug("CloseModalById() Called. idname[" + idname + "]");
            $(idname).modal("hide");
        }
        async function ShowModalById(idname) {
            console.debug("CloseModalById() Called. idname[" + idname + "]");
            $(idname).modal("show");
        }
    </script>
```

like this

![image.png](https://qiita-image-store.s3.amazonaws.com/0/381067/a1809606-6e8f-0cfd-c8f4-dfed99a98b00.png)


### Step3. Create Example1 Page and Bootstrap Button & Modal Window

- Make a Example1.cshtml to [Client]Project -> [pages] Folder

![image.png](https://qiita-image-store.s3.amazonaws.com/0/381067/39c47551-1c41-6288-15f0-95a05869ce9d.png)

- Edit NavMenu.cshtml to add Example1 page

-- add below codes to NavMenu.cshtml

```html

<li class="nav-item px-3">
    <NavLink class="nav-link" href="example1">
        <span class="oi oi-list-rich" aria-hidden="true"></span> Example1
    </NavLink>
</li>
```

like this

![image.png](https://qiita-image-store.s3.amazonaws.com/0/381067/62f6f9f8-7d81-054a-1b23-3d9abbf0c1bb.png)


- Input below code to Example1.cshtml

```html

@page "/example1"
@inject IJSRuntime _jsRuntime

@* Example1. Open/Close Bootstrap Modal from C# *@
@functions {
    string example1title = "Example1";
    string example1text = "Example1. Open/Close Bootstrap Modal from C#";
    string modalTextPlaceHolder = "Enter Something";
    string modalText = null;


    protected async Task Submit()
    {
        await Task.Run(() =>
        {
            example1text = string.IsNullOrEmpty(modalText) ? example1text : modalText;
            modalText = null;
        });
    }

    protected async Task CloseExample1()
    {
        await Submit();
        _ = _jsRuntime.InvokeAsync<bool>("CloseModalById", "#BootStrapModal");
    }
}

<div class="container-fluid">
    <div class="col">
        <div class="col-12 ">
            <p>example1text : @example1text</p>
        </div>
        <button class="btn btn-outline-dark" data-toggle="modal" data-target="#BootStrapModal">
            <i class="fa fa-pencil-square-o"></i>
            Example1
        </button>
    </div>
</div>

<div class="modal fade" id="BootStrapModal">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h3 class="modal-title">@example1title</h3>
                <button type="button" class="close" data-dismiss="modal">
                    <span aria-hidden="true">X</span>
                </button>
            </div>
            <div class="modal-body">
                <div class="container-fluid">
                    <div class="row">
                        <input class="col-12 " placeholder="@modalTextPlaceHolder" bind="@modalText" />
                    </div>
                </div>
            </div>
            <div class="modal-footer">
                <div class="container-fluid">
                    <div class="col">
                        <button type="submit" class="btn btn-block btn-success" data-dismiss="modal" onclick="@Submit">
                            Close By Bootstrap
                        </button>
                        <button type="button" class="btn btn-block btn-danger" onclick="@CloseExample1">
                            Close By C#
                        </button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
```

### Step4. Start Test


You can see&learn how to 

- Bootstrap&Blazor to show/close Modal Dialog
    - bind property
- How to invoke js method from C#
    - inject by IJSRuntime
- where you must put the scrpits
    - In the \<body> tag of index.html

#### Demo
You can see how to close Bootstrap Modal from C# !
![testExample1.gif](https://qiita-image-store.s3.amazonaws.com/0/381067/2d522804-05b2-24a3-38ad-f01ac09dd210.gif)

---

## Example2. How to use InputSelect tag and Validation

### Step1. Add Page(View&Model) to [pages] Folder

- Select "Razor Page" to make a page with model file.

![image.png](https://qiita-image-store.s3.amazonaws.com/0/381067/06d31c05-6ba2-4d21-cbef-0d2856c493de.png)

### Step2. Edit View to put UIs.

- Add Navigation to Example2 page.

NavMenu.cshtml

```html

        <li class="nav-item px-3">
            <NavLink class="nav-link" href="example2">
                <span class="oi oi-list-rich" aria-hidden="true"></span> Example2
            </NavLink>
        </li>
```

- Clear&Input below codes to Example2.cshtml

```html
@page "/example2"

@inherits Example2Model

@functions{
    string textName = null;

    protected void AddName2Options()
    {
        AddOptionValue(textName);
    }
}

<div class="container-fluid">
    <div class="col">
        <div class="row">
            <Input bind="@textName" />
            <button class="btn btn-outline-dark" onclick="@AddName2Options">
                <i class="fa fa-pencil-square-o"></i>
                Add
            </button>
        </div>
        <div class="col">
            <EditForm Model="@param" OnInvalidSubmit="@HandleInvalid">
                <div class="col">
                    <DataAnnotationsValidator />
                    <ValidationSummary />
                </div>
                <div class="col-md-4">
                    <p>Selected Name : @param.name </p>
                    <div class="row">
                        <InputSelect bind-Value="@param.name">
                            @foreach (var item in @OptionValues)
                            {
                                <option value=@item.Value>@item.Value</option>
                            }
                        </InputSelect>
                        <button type="submit" class="btn btn-block btn-success">
                            Submit
                        </button>
                    </div>
                </div>
            </EditForm>
        </div>
    </div>
</div>
```

### Step3. Edit Model to validate

- Clear&Input below codes to Example2.cshtml.cs

```csharp

using System;
using Microsoft.AspNetCore.Components;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;

namespace DotNetCore3Sample.Client.Pages
{
    public class Example2Model : ComponentBase
    {
        protected ValidationParams param = new ValidationParams();

        private static readonly Dictionary<int, string> DefaultOptionValues = new Dictionary<int, string>(
            new Dictionary<int, string>()
            {
                {0, "Tarou"},
                {1, "Hanako"},
                {2, "Franky"}
            });


        protected Dictionary<int, string> OptionValues = new Dictionary<int, string>(DefaultOptionValues);


        protected void AddOptionValue(string name)
        {
            if (string.IsNullOrEmpty(name))
                return;

            OptionValues.Add(OptionValues.Count, name);
        }

        protected async Task HandleInvalid()
        {
            Console.WriteLine("OnHandleInvalid()");
            // Initilize OptionValues and param.name
            await Task.Run(() => {
                OptionValues = new Dictionary<int, string>(DefaultOptionValues);
                param.name = null;
            });
        }
    }

    public class ValidationParams
    {
        [Required(ErrorMessage = "You need select a Name.")]
        [StringLength(100, MinimumLength = 4, ErrorMessage = "Name must be in 4-100 length.")]
        public string name { get; set; }
    }
}
```

### Step4. Start Test

You can see&learn how to 

- Model inherits
- use the \<InputSelect> tag
    - \<EditForm>
        - Must be parent of \<InputSelect> tag
        - EventCallback : OnInvalidSubmit (and OnValidSubmit)
    - bind-Value
- bind&validate data
 - System.ComponentModel.DataAnnotations
 - \<DataAnnotationsValidator />
 - \<ValidationSummary />

#### Demo

![testExample2.gif](https://qiita-image-store.s3.amazonaws.com/0/381067/f7562ef6-7abc-0af6-7205-2c8e7045a9ac.gif)


Source Code on Github : [DotNetCore3Sample](https://github.com/Ohurochan/DotNetCore3Sample)

---