誰かがコメントで指摘したように、MVCで行うのと同じように、Razorページにはコントローラーは必要ありません。また、Razorにはボタンクリックイベントのネイティブ処理がありません。ユーザーがボタンをクリックしたときに(「コードビハインド」で)何かを行うには、少なくとも2つのオプションがあります。
コントローラー関数を定義する方法を示すMVCの例がたくさんあります。しかし、言ったように、私は持っていません。
したがって、私は両方の方法を理解しようとしています。ここで私のテストcshtml:
<form method="post">
<input type="submit" class="btn btn-primary" value="way1">Way 1/>
</form>
<button id="btn" type="button" class="btn btn-primary" value="way2">Way 2</button>
<script>
$(document).ready(function() {
$("#btn").click(function (e) {
e.preventDefault();
$.ajax({
url: "@Url.Action("Way2")",
type: "POST",
data: "foo",
datatype: "text",
success: function (data) {
alert(data);
}
});
return false;
});
});
</script>
そしてここにcshtml.cs:
パブリッククラスTestModel:PageModel {private readonly MyContext _context;
public TestModel(MyContext context)
{
_context = context;
}
public IActionResult OnPost()
{
// here I can put something to execute
// when the submit button is clicked
}
public ActionResult Way2(string data)
{
// this is never triggered
}
「Way1」(送信)を使用すると、ボタンのクリックをキャッチできますが、いくつかの欠点があります。デフォルトでは、投稿のためにページがリロードされます。時々、何も変更する必要はなく、C#関数を呼び出すだけです。しかし、複数のボタンを処理する方法がわかりません。つまり5つのボタンがある場合、それぞれに異なる方法を実行するにはどうすればよいですか?
「Way2」では、csコードの関数に到達できず、Bad Requestエラー(400)が発生するため、何か間違ったことをしました。私は何を取りこぼしたか?
通常のフォーム送信
通常のフォーム送信を行う場合、慣例に従って、On{{HttpVerb}}{{YourHanderName}}
形式に従うハンドラーメソッド名が必要です。
public ActionResult OnPostWay2(string data)
{
// to do : return something
}
form
タグ内に送信ボタンがあり、asp-page-handler
に言及していることを確認してください。その属性の値は、ページモデルクラスのハンドラー名である必要があります(Way2
)
<form method="POST">
<button type="submit" asp-route-data="foo" asp-page-handler="Way2">Way 2</button>
</form>
上記のコードは、url yourBaseUrl/YourPageName?data=foo&handler=Way2
に設定されている formaction
属性 でボタンのマークアップを生成します。ユーザーが送信ボタンをクリックすると、formaction属性値がフォームのデフォルトアクションURLをオーバーライドするため、このURLをフォームにポストします。リクエストを受信すると、razor pagesフレームワークはこのパラメーター(handler
)を使用し、対応するハンドラーメソッドにリクエストを送信します。
Ajax呼び出し
フレームワークは、送信されたリクエストデータの一部としてRequestVerificationToken
を予期しているため、400(Bad Request)応答を取得しています。ページの表示ソースを確認すると、フォーム内に__RequestVerificationToken
という名前の非表示の入力要素が表示されます。フレームワークはこれを使用して、起こり得るCSRF攻撃を防ぎます。リクエストにこの情報がない場合、フレームワークは400の不正なリクエストを返します。
Ajaxコードを機能させるには、これを明示的に送信するだけです。これが実際のサンプルです
$("#btn").click(function(e) {
e.preventDefault();
var t = $("input[name='__RequestVerificationToken']").val();
$.ajax({
url: $(this).attr("formaction"),
headers:
{
"RequestVerificationToken": t
},
type: "POST",
data: { data: 'foo2' },
}).done(function(data) {
console.log(data);
}).fail(function(a, v, e) {
alert(e);
});
});
これでajax呼び出しを行っているので、json応答を返すのが理にかなっています
public ActionResult OnPostWay2(string data)
{
return new JsonResult("Received "+ data + " at "+DateTime.Now);
}
上記の例では、jQueryコードを使用して__RequestVerificationToken
という名前の入力要素を取得し、その値を読み取ります。より堅牢なアプローチは、ビューにIAntiforgery
実装を挿入し、GetAndStoreTokens
メソッドを使用することです。
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions{
public string GetAntiXsrfRequestToken()
{
return Xsrf.GetAndStoreTokens(Model.HttpContext).RequestToken;
}
}
<script>
$(function () {
$("#btn").click(function(e) {
e.preventDefault();
var t = '@GetAntiXsrfRequestToken()';
$.ajax({
url: $(this).attr("formaction"),
headers:
{
"RequestVerificationToken": t
},
type: "POST",
data: { data: 'foo2' },
}).done(function(data) {
console.log(data);
}).fail(function(a, v, e) {
alert(e);
});
});
})
</script>