Edit.cshtml.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. using SharedKernel.Attributes;
  2. using SharedKernel.Extensions;
  3. using MediatR;
  4. using Microsoft.AspNetCore.Mvc;
  5. using Microsoft.AspNetCore.Mvc.RazorPages;
  6. using Microsoft.AspNetCore.Mvc.Rendering;
  7. using System.ComponentModel.DataAnnotations;
  8. namespace Admin.Pages.Crypto.List
  9. {
  10. public class EditModel(IMediator mediator) : PageModel
  11. {
  12. public int CoinID { get; private set; }
  13. public string? CurrentLogoImage { get; private set; }
  14. public IReadOnlyList<string> Markets { get; private set; } = [];
  15. public List<SelectListItem> Categories { get; set; } = [];
  16. [BindProperty]
  17. public InputModel Input { get; set; } = new();
  18. public sealed class InputModel
  19. {
  20. [Required(ErrorMessage = "심볼은 필수입니다.")]
  21. [StringLength(30, ErrorMessage = "심볼은 {1}자 이하로 입력하세요.")]
  22. public string Symbol { get; set; } = null!;
  23. [Required(ErrorMessage = "한글명은 필수입니다.")]
  24. [StringLength(200, ErrorMessage = "한글명은 {1}자 이하로 입력하세요.")]
  25. public string KorName { get; set; } = null!;
  26. [Required(ErrorMessage = "영문명은 필수입니다.")]
  27. [StringLength(200, ErrorMessage = "영문명은 {1}자 이하로 입력하세요.")]
  28. public string EngName { get; set; } = null!;
  29. [AllowedExtensions("jpg,jpeg,png,gif,webp,svg", ErrorMessage = "이미지 확장자는 jpg, jpeg, png, gif, webp, svg 이어야 합니다.")]
  30. public IFormFile? LogoImageFile { get; set; }
  31. public bool DeleteLogoImage { get; set; } = false;
  32. [StringLength(5000)]
  33. public string? Description { get; set; }
  34. [StringLength(100)]
  35. public string? ContractAddress { get; set; }
  36. [StringLength(500)]
  37. [DataType(DataType.Url)]
  38. public string? WebsiteUrl { get; set; }
  39. [StringLength(500)]
  40. [DataType(DataType.Url)]
  41. public string? WhitepaperUrl { get; set; }
  42. [StringLength(500)]
  43. [DataType(DataType.Url)]
  44. public string? TwitterUrl { get; set; }
  45. [StringLength(500)]
  46. [DataType(DataType.Url)]
  47. public string? TelegramUrl { get; set; }
  48. public bool IsActive { get; set; } = false;
  49. public bool IsWarning { get; set; } = false;
  50. public bool IsNew { get; set; } = false;
  51. public bool IsDelisted { get; set; } = false;
  52. public int[] CategoryIDs { get; set; } = [];
  53. }
  54. public async Task<IActionResult> OnGetAsync(int id, CancellationToken ct)
  55. {
  56. try
  57. {
  58. var coin = await mediator.Send(new GetCoin.Query(id), ct);
  59. CoinID = coin.ID;
  60. CurrentLogoImage = coin.LogoImage;
  61. Markets = coin.Markets;
  62. var categories = await mediator.Send(new GetCryptoCategories.Query(), ct);
  63. Categories = [..categories.List.Select(c => new SelectListItem(c.Name, c.ID.ToString()))];
  64. Input = new InputModel
  65. {
  66. Symbol = coin.Symbol,
  67. KorName = coin.KorName,
  68. EngName = coin.EngName,
  69. Description = coin.Description,
  70. ContractAddress = coin.ContractAddress,
  71. WebsiteUrl = coin.WebsiteUrl,
  72. WhitepaperUrl = coin.WhitepaperUrl,
  73. TwitterUrl = coin.TwitterUrl,
  74. TelegramUrl = coin.TelegramUrl,
  75. IsActive = coin.IsActive,
  76. IsWarning = coin.IsWarning,
  77. IsNew = coin.IsNew,
  78. IsDelisted = coin.IsDelisted,
  79. CategoryIDs = [..coin.CategoryIDs]
  80. };
  81. return Page();
  82. }
  83. catch (KeyNotFoundException)
  84. {
  85. return NotFound();
  86. }
  87. }
  88. public async Task<IActionResult> OnPostAsync(int id, CancellationToken ct)
  89. {
  90. try
  91. {
  92. if (!ModelState.IsValid)
  93. {
  94. throw new Exception(ModelState.GetErrorMessages());
  95. }
  96. await mediator.Send(new UpdateCoin.Command(
  97. id,
  98. Input.Symbol,
  99. Input.KorName,
  100. Input.EngName,
  101. Input.LogoImageFile,
  102. Input.DeleteLogoImage,
  103. Input.Description,
  104. Input.ContractAddress,
  105. Input.WebsiteUrl,
  106. Input.WhitepaperUrl,
  107. Input.TwitterUrl,
  108. Input.TelegramUrl,
  109. Input.IsActive,
  110. Input.IsWarning,
  111. Input.IsNew,
  112. Input.IsDelisted,
  113. Input.CategoryIDs
  114. ), ct);
  115. TempData["SuccessMessage"] = $"{Input.Symbol} 코인이 수정되었습니다.";
  116. return RedirectToPage("/Crypto/List/Edit", new { id });
  117. }
  118. catch (Exception e)
  119. {
  120. TempData["ErrorMessages"] = e.Message;
  121. return RedirectToPage("/Crypto/List/Edit", new { id });
  122. }
  123. }
  124. }
  125. }