了解しました。
前回のサンプルをさらに改良し、堅牢性・保守性・実用性 を高めた形で再生成します。
今回は以下の点を改善しています。
- 非同期処理のキャンセル対応(
CancellationToken) - 入力値の追加バリデーション
- 更新日時の記録例
- SweetAlert2 の UI 改善
- Ajax 側での詳細エラーハンドリング
1. Controller 側(更新アクション)
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Threading;
using System.Threading.Tasks;
using YourAppNamespace.Data; // DbContext の名前空間
using YourAppNamespace.Models; // Payment モデルの名前空間
public class PaymentsController : Controller
{
private readonly ApplicationDbContext _context;
public PaymentsController(ApplicationDbContext context)
{
_context = context;
}
/// <summary>
/// Ajax から呼び出される Payment 更新アクション
/// </summary>
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> UpdatePayment(
[FromBody] PaymentUpdateDto dto,
CancellationToken cancellationToken)
{
if (dto == null || dto.PaymentId <= 0)
{
return BadRequest(new { message = "不正なデータです。" });
}
if (dto.Amount < 0)
{
return BadRequest(new { message = "金額は0以上で入力してください。" });
}
var payment = await _context.Payments
.FirstOrDefaultAsync(p => p.PaymentId == dto.PaymentId, cancellationToken);
if (payment == null)
{
return NotFound(new { message = "指定された支払いデータが見つかりません。" });
}
// 値の更新
payment.IncomeCategoryId = dto.IncomeCategoryId;
payment.Amount = dto.Amount;
payment.UpdatedAt = DateTime.UtcNow; // 更新日時を記録する例
try
{
await _context.SaveChangesAsync(cancellationToken);
return Ok(new { message = "更新が完了しました。" });
}
catch (DbUpdateException ex)
{
return StatusCode(500, new { message = "データベース更新に失敗しました。", error = ex.Message });
}
}
}
/// <summary>
/// Ajax で受け取る更新用 DTO
/// </summary>
public class PaymentUpdateDto
{
public int PaymentId { get; set; }
public int IncomeCategoryId { get; set; }
public decimal Amount { get; set; }
}
2. View 側 JavaScript(SweetAlert2 + Ajax 呼び出し)
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script>
// SweetAlert2 の confirm 後に Ajax 更新
}).then((result) => {
if (result.isConfirmed && paymentId && paymentId > 0) {
const data = {
paymentId: paymentId,
incomeCategoryId: result.value.incomeCategoryId,
amount: result.value.amount
};
$.ajax({
url: '/Payments/UpdatePayment',
type: 'POST',
contentType: 'application/json',
headers: {
'RequestVerificationToken': $('input[name="__RequestVerificationToken"]').val()
},
data: JSON.stringify(data),
success: function (response) {
Swal.fire({
icon: 'success',
title: '更新成功',
text: response.message,
confirmButtonText: 'OK'
}).then(() => {
location.reload();
});
},
error: function (xhr) {
let msg = '不明なエラーが発生しました。';
if (xhr.responseJSON?.message) {
msg = xhr.responseJSON.message;
}
Swal.fire({
icon: 'error',
title: '更新失敗',
text: msg,
confirmButtonText: '閉じる'
});
}
});
}
});
</script>
3. 改良点まとめ
- CancellationToken を導入し、リクエスト中断に対応。
- 金額の負数入力をサーバー側で拒否。
- 更新日時 (
UpdatedAt) を記録する例を追加。 - SweetAlert2 の UI を改善し、ユーザーにわかりやすいメッセージ表示。
- Ajax 側で詳細なエラーメッセージを取得して表示。
この形にすれば、セキュリティ・保守性・ユーザー体験 のバランスが取れた実装になります。
もしご希望であれば、このコードを Index.cshtml に完全統合した動作サンプル として提供できます。
そうすれば、すぐに動作確認可能です。
この統合版を作成しますか?
Powered by Froala Editor