C#とJavaScriptの連携

### はじめに
JavaScriptの現場経験が初めてだったのですが、サーバサイド側（C#）との連携が特に分かりませんでした。
現場でやった内容を思い出しながらまとめてみます。
メモ程度のコードなのでご注意ください。
ちなみにフレームワークはASP.NET MVCです。

### ①Ajax
はじめの頃はサーバとの連携はAjaxしか知りませんでした。
例えばサーバ処理後、画面をそのまま戻したい時とか、ポップアップを出すなど別のjsの処理をしたい時などに、他にいい方法が分からずAjaxを使っていました。
```Index.cshtml
@using (Html.BeginForm("アクション名", "コントローラ名", FormMethod.Post, new { id = "form" }))
{
    <button type="button" id="xxxx">XXXX</button>
}

```
```Index.js
// functionで書くことも可能
$(document).on('click', 'xxxx', function() {
    var obj = document.forms['form'];
    $.ajax({
        method: "POST",
        url: "https://example.com", // 後述のグローバル変数にすることも可能
        data: $(obj).serialize(),
        dataType: "json"
    }).done(function (data, textStatus, jqXHR) {
        console.log(data);

        // エラーメッセージを作成したり画面レイアウトを作成したり
    });
}   
```

#### Ajax処理後の値に書き換える
例えばページング処理をAjaxで作成したのですが、一覧をAjax処理後の値に書き換えるいい方法が分からずhtmlを手書きをしていました。
今回気になってChatGPTに聞いたところ、以下のサンプルコードを教えてもらいました。
```Sample.cshtml
@model IEnumerable<MyViewModel>

<table>
    <thead>
        <tr>
            <th>項目1</th>
            <th>項目2</th>
            <th>項目3</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>@item.Item1</td>
                <td>@item.Item2</td>
                <td>@item.Item3</td>
            </tr>
        }
    </tbody>
</table>
```
```Sample.js
$(function() {
    $.ajax({
        url: '/MyController/MyAction',
        type: 'GET',
        dataType: 'json',
        success: function(data) {
            // 取得したjsonの値を使ってtableを書き換える
            var tbody = $('table tbody');
            tbody.empty(); // tbody内の要素をすべて削除する
            $.each(data, function(i, item) {
                var tr = $('<tr></tr>');
                tr.append($('<td></td>').text(item.Item1));
                tr.append($('<td></td>').text(item.Item2));
                tr.append($('<td></td>').text(item.Item3));
                tbody.append(tr);
            });
        },
        error: function() {
            alert('エラーが発生しました');
        }
    });
});
```

#### 余談
以下のようなコードは想定通り動作せず、結果としてAjaxを使っていました。

例１：submitの後、jsの処理をしたい
```Sample.js
$('#form').submit(function() {
    // submit後を想定したがalertが先に出る
    alert('完了しました。');
});
```

他にも、Controllerで処理後、ViewModelにフラグを設定して完了ポップアップを出すようにしていました。
しかし、画面描画より先にポップアップが出てしまい、setTimeoutを設定するしか分かりませんでした。それでも、その時によってポップアップが先に出てしまい不完全でした。
```Sample.cshtml
@{
    if (Model.UpdatedFlg)
    {
        <script>
            window.onload = function () {
                setTimeout(() => {
                    alert('完了しました。');
                }, 1000);
            }
        </script>
    }
}
```

例２：条件によってsubmitを無効化する
```Sample2.js
// 共通クライアントエラーを発火するためsubmitさせる
$('#form').submit(function() {
    if (エラーがなかったら) {
        return true; // submitする
    } else {
        return false; // submitしない
    }
});
```
submitを無効化するのはonsubmitに書かないとできませんでした。
そのため、サーバへ飛ばすのはsubmitではなくAjaxにしていました。
```Sample2.cshtml
@using (Html.BeginForm("Create", "Word", FormMethod.Post, new { id = "form", onsubmit="return false"}))
{
    @Html.TextBoxFor(model => model.Word, new { name="newWord"})
    <button type="submit">追加</button>
}
```

### ②hiddenに値を設定してsubmitする
jsで取得・処理した値をサーバに飛ばしたい時に使用していました。
```Index.cshtml
@using (Html.BeginForm("アクション名", "コントローラ名", FormMethod.Post, new { id = "form" }))
{
    @Html.AntiForgeryToken()
    <input type="hidden" name="xxxx" id="xxxx">
    <button type="button" onclick="Xxxx()">XXXX</button>
}

```
```Index.js
function Xxxx() {
    $('#xxxx').val('hoge');
    $('#form').subit();
}
```

### ③グローバル変数
URLやViewModelの値、セッションの値、定数などC#の値をjsで使いたい時に使用していました。
```Index.cshtml
<script type="text/javascript">
    var searchUrl = '@Url.Action("Search", "User")';
    var userName = '@Html.Raw(Json.Encode(Model.UserName))';
</script>
```

### 最後に
JavaScriptの経験が浅く、まだ基本的な知識も足りていないと思います。
ネットで情報を得るのに難航していたのですが、ChatGPTを使うことで具体的な質問をできたり、サンプルソースも提示してくれるので取っ掛かりがつかみやすいと思いました。
今後学習にも活用したいと思います。