Created
May 18, 2017 12:32
-
-
Save amoretspero/7f86972ed09bd4f59d3a01e6fa1aab73 to your computer and use it in GitHub Desktop.
Sample code for server-side C#, ASP.NET Core.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Threading.Tasks; | |
using System.Diagnostics; | |
using Microsoft.AspNetCore.Mvc; | |
using Microsoft.EntityFrameworkCore; | |
using csatdb.Models; | |
using csatdb.Models.ExamSearchViewModels; | |
using csatdb.Data; | |
using csatdb.Helpers; | |
using ImageMagick; | |
using System.ComponentModel.DataAnnotations; | |
using Microsoft.AspNetCore.Http; | |
using Microsoft.AspNetCore.Hosting; | |
using Microsoft.WindowsAzure; | |
using Microsoft.WindowsAzure.Storage; | |
using Microsoft.Extensions.Configuration; | |
using Microsoft.WindowsAzure.Storage.Blob; | |
using System.Diagnostics; | |
using Microsoft.AspNetCore.Authorization; | |
namespace csatdb.Controllers | |
{ | |
public class ExamSearchController : Controller | |
{ | |
private readonly ApplicationDbContext _context; | |
private readonly IHostingEnvironment _hostingEnv; | |
private readonly Dictionary<string, ExamType> _examInfoMap; | |
private readonly IConfigurationRoot _configuration; | |
private readonly string _cloudStoragePrefix = "https://campusbox.blob.core.windows.net/testcloud"; | |
private readonly ExamSearchHelpers _examSearchHelper; | |
public ExamSearchController (IHostingEnvironment hostingEnv, ApplicationDbContext context) | |
{ | |
_hostingEnv = hostingEnv; | |
_context = context; | |
IConfigurationBuilder configurationBuilder = new ConfigurationBuilder().SetBasePath(_hostingEnv.ContentRootPath).AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); | |
configurationBuilder.AddEnvironmentVariables(); | |
_configuration = configurationBuilder.Build(); | |
_examInfoMap = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, ExamType>>(System.IO.File.ReadAllText(_hostingEnv.ContentRootPath + "/Data/ExamInformation/exam-information.json")); | |
Console.OutputEncoding = System.Text.Encoding.UTF8; | |
_examSearchHelper = new ExamSearchHelpers(_hostingEnv, _context); | |
} | |
public IActionResult Index() | |
{ | |
List<ExamPaper> examPapers = _context.ExamPapers.ToList(); | |
List<ExamSearchIndexExamElement> examInformations = examPapers | |
.Select(ep => new ExamSearchIndexExamElement { Type = ep.Type, Year = ep.Year, SchoolYear = ep.SchoolYear, Month = ep.Month, ExamDisplayName = _examSearchHelper.GetDisplayNameForExam(ep) }) | |
.Distinct(new ExamSearchIndexExamElementComparer()) | |
.OrderByDescending(elem => elem.Type) | |
.ThenByDescending(elem => elem.Year) | |
.ThenByDescending(elem => elem.SchoolYear) | |
.ThenByDescending(elem => elem.Month) | |
.ToList(); | |
return View(new ExamSearchIndexViewModel | |
{ | |
Exams = examInformations | |
}); | |
} | |
public IActionResult Detail() | |
{ | |
string examCode = (string)RouteData.Values["examcode"]; | |
if (_examSearchHelper.IsExamCodeValid(examCode)) | |
{ | |
string[] parsedExamCode = examCode.Split(new string[] { "-" }, StringSplitOptions.None); | |
string type = parsedExamCode[0]; | |
string schoolYear = parsedExamCode[1]; | |
int year = Convert.ToInt32(parsedExamCode[2]); | |
int month = 0; | |
if (type == "csat") { month = Convert.ToInt32(parsedExamCode[3]); } | |
string subject = parsedExamCode[4]; | |
string problemType = ""; | |
if (parsedExamCode.Length > 5) { problemType = parsedExamCode[5]; } | |
string convertedType = _examSearchHelper.TypeConverter(type); | |
string convertedSchoolYear = _examSearchHelper.SchoolYearConverter(schoolYear); | |
string convertedMonth = ""; | |
if (type == "csat") { convertedMonth = month.ToString() + "월"; } else { convertedMonth = "공통"; } | |
string convertedSubject = _examSearchHelper.SubjectConverter(year, subject); | |
string convertedProblemType = null; | |
string solutionFileLink = null; | |
if (problemType != "") | |
{ | |
convertedProblemType = _examSearchHelper.ProblemTypeConverter(convertedType, convertedSchoolYear, year, convertedMonth, convertedSubject, problemType); | |
} | |
ExamPaper examPaper = null; | |
try | |
{ | |
examPaper = _context.ExamPapers.Include(ep => ep.ExamLevelCutline).Single(ep => ep.Type == convertedType && ep.SchoolYear == convertedSchoolYear && ep.Year == year && ep.Month == month && ep.Subject == convertedSubject && ep.ProblemType == convertedProblemType); | |
} | |
catch (System.Exception e) | |
{ | |
return NotFound(); | |
} | |
if (examPaper.IsSolutionFileExists) | |
{ | |
solutionFileLink = _examSearchHelper.GenerateCloudStorageFullPath(_examSearchHelper.GenerateFileNameByExamPaper(examPaper, false)); | |
} | |
ExamSearchDetailElement targetElement = new ExamSearchDetailElement() | |
{ | |
ExamPaper = examPaper, | |
ExamCode = examCode, | |
DisplayName = _examSearchHelper.GetDisplayNameForExamPaper(examPaper), | |
ExamPaperFileLink = _examSearchHelper.GenerateCloudStorageFullPath(_examSearchHelper.GenerateFileNameByExamPaper(examPaper, true)), | |
SolutionFileLink = solutionFileLink, | |
TimeLimit = _examSearchHelper.GetTimeLimit(examPaper.Type, examPaper.Subject), | |
ProblemCount = _examSearchHelper.GetProblemCount(examPaper.Type, examPaper.Subject), | |
ExamPreparer = _examSearchHelper.GetExamPreparer(examPaper), | |
Difficulty = _examSearchHelper.GetDifficulty(examPaper), | |
IsComparisonChartDataReady = _examSearchHelper.IsComparisonChartDataReady(examPaper) | |
}; | |
List<ExamSearchDetailElement> relatedElements = new List<ExamSearchDetailElement>(); | |
relatedElements.AddRange(_context.ExamPapers | |
.Include(ep => ep.ExamLevelCutline) | |
.Where(ep => ep.Type == examPaper.Type && ep.Year == examPaper.Year && ep.Month == examPaper.Month && ep.SchoolYear == examPaper.SchoolYear) | |
.Select(ep => new ExamSearchDetailElement | |
{ | |
ExamPaper = ep, | |
ExamCode = _examSearchHelper.GenerateExamCodeByExamPaper(ep), | |
DisplayName = _examSearchHelper.GetDisplayNameForExamPaper(ep), | |
TimeLimit = _examSearchHelper.GetTimeLimit(ep.Type, ep.Subject), | |
ProblemCount = _examSearchHelper.GetProblemCount(ep.Type, ep.Subject), | |
Difficulty = _examSearchHelper.GetDifficulty(ep), | |
ExamPreparer = _examSearchHelper.GetExamPreparer(ep) | |
})); | |
ExamSearchDetailViewModel result = new ExamSearchDetailViewModel() | |
{ | |
TargetElement = targetElement, | |
RelatedElements = relatedElements | |
}; | |
ViewData["examcode"] = examCode; | |
return View("Detail", result); | |
} | |
else | |
{ | |
return View("NotFount"); | |
} | |
} | |
[HttpGet] | |
[Authorize] | |
public IActionResult Create() | |
{ | |
return View(new ExamSearchCreateViewModel()); | |
} | |
[HttpPost] | |
[Authorize] | |
public async Task<IActionResult> Create(ExamSearchCreateViewModel model) | |
{ | |
if (!ModelState.IsValid) | |
{ | |
ModelState.AddModelError(string.Empty, "잘못 입력된 내용이 있습니다. 내용을 다시 확인하세요."); | |
ViewData["ErrorMessage"] = "잘못 입력된 내용이 있습니다. 내용을 다시 확인하세요."; | |
return View(model); | |
} | |
else | |
{ | |
KeyValuePair<bool, string> examExistence = _examSearchHelper.IsExamSearchCreateViewModelValid(model); | |
if (!examExistence.Key) | |
{ | |
ModelState.AddModelError(string.Empty, examExistence.Value); | |
ViewData["ErrorMessage"] = "등록할 수 없는 시험지 정보입니다. 관리자에게 문의해주세요."; | |
return View(model); | |
} | |
else | |
{ | |
string examPaperFileName = new System.Text.StringBuilder().Append(model.ExamPaperFile.FileName.Skip(model.ExamPaperFile.FileName.LastIndexOf("\\")+1).ToArray()).ToString(); | |
KeyValuePair<bool, string> examPaperFileValid = _examSearchHelper.IsExamFileNameValid(new System.Text.StringBuilder().Append(examPaperFileName.Take(examPaperFileName.LastIndexOf('.')).ToArray()).ToString()); | |
if (!examPaperFileValid.Key) | |
{ | |
ModelState.AddModelError(string.Empty, examPaperFileValid.Value); | |
ViewData["ErrorMessage"] = "시험지 파일 이름이 정확하지 않습니다. 양식에 맞는 이름인지 확인해주세요."; | |
return View(model); | |
} | |
else | |
{ | |
string solutionFileName = ""; | |
if (model.SolutionFile != null) | |
{ | |
solutionFileName = new System.Text.StringBuilder().Append(model.SolutionFile.FileName.Skip(model.SolutionFile.FileName.LastIndexOf("\\")+1).ToArray()).ToString(); | |
KeyValuePair<bool, string> solutionFileValid = _examSearchHelper.IsSolutionFileNameValid(new System.Text.StringBuilder().Append(solutionFileName.Take(solutionFileName.LastIndexOf('.')).ToArray()).ToString()); | |
if (!solutionFileValid.Key) | |
{ | |
ModelState.AddModelError(string.Empty, solutionFileValid.Value); | |
ViewData["ErrorMessage"] = "해설 파일 이름이 정확하지 않습니다. 양식에 맞는 이름인지 확인해주세요."; | |
return View(model); | |
} | |
} | |
bool isSolutionFileExists = false; | |
if (model.SolutionFile != null) | |
{ | |
isSolutionFileExists = true; | |
} | |
// Check if exam already exists. | |
// This should check if there is exam with | |
// 'same year', 'same month', 'same school year', 'same subject', 'same problem type' already exists. | |
KeyValuePair<bool, string> noDuplicationCheck = _examSearchHelper.CheckExamNoDuplication(model); | |
if (!noDuplicationCheck.Key) | |
{ | |
ModelState.AddModelError(string.Empty, noDuplicationCheck.Value); | |
ViewData["ErrorMessage"] = "이미 등록된 시험지 정보입니다. 목록을 확인해주세요."; | |
return View(model); | |
} | |
// Generate cloud storage account. | |
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(_configuration.GetConnectionString("AzureStorageConnection")); | |
// Get blob client. | |
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); | |
// Get access to container for 'testcloud' service. | |
CloudBlobContainer container = blobClient.GetContainerReference("testcloud"); | |
// Write thumbnail image. | |
// By default, try ImageMagick NuGet library. | |
// When it fails, try command line method. | |
// When it fails also, return error. | |
// Thumbnail images will be stored at cloud storage, under path "/images/examsearch-thumbnails". | |
bool isProblemTypeExists = _examSearchHelper.IsProblemTypeExists(new System.Text.StringBuilder().Append(examPaperFileName.Take(examPaperFileName.LastIndexOf('.')).ToArray()).ToString()); | |
try | |
{ | |
// Primary attempt. | |
MagickNET.SetTempDirectory(System.IO.Path.Combine(_hostingEnv.ContentRootPath, "ImageMagick", "ImageMagickTemp")); | |
MagickNET.SetGhostscriptDirectory(System.IO.Path.Combine(_hostingEnv.ContentRootPath, "ImageMagick")); | |
MagickReadSettings settings = new MagickReadSettings(); | |
settings.Density = new Density(300, 300); | |
MagickImageCollection images = new MagickImageCollection(); | |
images.Read(model.ExamPaperFile.OpenReadStream()); | |
MagickImage thumbnail = images[0]; | |
thumbnail.Format = MagickFormat.Png; | |
thumbnail.Write(System.IO.Path.Combine(new string[] { _hostingEnv.WebRootPath, "images", "examsearch-thumbnails", _examSearchHelper.GenerateThumbnailImageName(examPaperFileName, isProblemTypeExists) })); | |
thumbnail.Dispose(); | |
images.Dispose(); | |
CloudBlockBlob thumbnailBlob = container.GetBlockBlobReference(System.IO.Path.Combine(new string[] { "images", "examsearch-thumbnails", _examSearchHelper.GenerateThumbnailImageName(examPaperFileName, isProblemTypeExists) })); | |
await thumbnailBlob.UploadFromFileAsync(System.IO.Path.Combine(new string[] { _hostingEnv.WebRootPath, "images", "examsearch-thumbnails", _examSearchHelper.GenerateThumbnailImageName(examPaperFileName, isProblemTypeExists) })); | |
System.IO.File.Delete(System.IO.Path.Combine(new string[] { _hostingEnv.WebRootPath, "images", "examsearch-thumbnails", _examSearchHelper.GenerateThumbnailImageName(examPaperFileName, isProblemTypeExists) })); | |
} | |
catch (System.Exception e) | |
{ | |
try | |
{ | |
// Second attempt. | |
// Command line imagemagick tools should be available. | |
// Save uploaded pdf file to imagemagick temp folder. | |
model.ExamPaperFile.CopyTo(new System.IO.FileStream(System.IO.Path.Combine(new string[] { _hostingEnv.ContentRootPath, "ImageMagick", "ImageMagickTemp", model.ExamPaperFile.FileName }), System.IO.FileMode.Create)); | |
// Delete thumbnail file if exists. | |
System.IO.File.Delete(System.IO.Path.Combine(new string[] { _hostingEnv.WebRootPath, "images", "examsearch-thumbnails", _examSearchHelper.GenerateThumbnailImageName(examPaperFileName, isProblemTypeExists) })); | |
// Generates thumbnail image name | |
string thumbnailImageName = _examSearchHelper.GenerateThumbnailImageName(examPaperFileName, isProblemTypeExists); | |
// Generate temporary thumbnail image name, without filetype extension. | |
string tempThumbnailImageName = _examSearchHelper.GenerateTemporaryThumbnailImageName(examPaperFileName, isProblemTypeExists); | |
// Ready for converting pdf to image. | |
// File type will be PNG, and all page will be extracted. | |
ProcessStartInfo psi = new ProcessStartInfo(); | |
psi.FileName = "/usr/bin/convert"; | |
psi.Arguments = " " + System.IO.Path.Combine(new string[] { _hostingEnv.ContentRootPath, "ImageMagick", "ImageMagickTemp", model.ExamPaperFile.FileName }) + " -density 300 -quality 100 " + System.IO.Path.Combine(new string[] { _hostingEnv.ContentRootPath, "ImageMagick", "ImageMagickTemp", tempThumbnailImageName + ".jpg" }); | |
Console.WriteLine("Command to be executed: \n{0}{1}", psi.FileName, psi.Arguments); | |
psi.UseShellExecute = false; | |
psi.RedirectStandardOutput = true; | |
Process proc = new Process | |
{ | |
StartInfo = psi | |
}; | |
proc.Start(); | |
proc.WaitForExit(); | |
// Ready for converting first page to jpg. | |
ProcessStartInfo psiPNGConvert = new ProcessStartInfo(); | |
psiPNGConvert.FileName = "/usr/bin/convert"; | |
psiPNGConvert.Arguments = " " + System.IO.Path.Combine(new string[] { _hostingEnv.ContentRootPath, "ImageMagick", "ImageMagickTemp", tempThumbnailImageName + "-0.jpg" }) + " " + System.IO.Path.Combine(new string[] { _hostingEnv.WebRootPath, "images", "examsearch-thumbnails", _examSearchHelper.GenerateThumbnailImageName(examPaperFileName, isProblemTypeExists) }); | |
Console.WriteLine("Command to be executed: \n{0} {1}", psiPNGConvert.FileName, psiPNGConvert.Arguments); | |
psiPNGConvert.UseShellExecute = false; | |
psiPNGConvert.RedirectStandardOutput = true; | |
Process procPNGConvert = new Process | |
{ | |
StartInfo = psiPNGConvert | |
}; | |
procPNGConvert.Start(); | |
procPNGConvert.WaitForExit(); | |
// Delete temporary pdf file. | |
System.IO.File.Delete(System.IO.Path.Combine(new string[] { _hostingEnv.ContentRootPath, "ImageMagick", "ImageMagickTemp", model.ExamPaperFile.FileName })); | |
// Delete contents in temporary folder. | |
System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(System.IO.Path.Combine(new string[] { _hostingEnv.ContentRootPath, "ImageMagick", "ImageMagickTemp" })); | |
foreach (System.IO.FileInfo file in di.GetFiles()) | |
{ | |
if (file.Name != "ImageMagickTemp.txt") | |
{ | |
file.Delete(); | |
} | |
} | |
foreach (System.IO.DirectoryInfo dir in di.GetDirectories()) | |
{ | |
dir.Delete(true); | |
} | |
// Upload to cloud storage. | |
CloudBlockBlob thumbnailBlob = container.GetBlockBlobReference(System.IO.Path.Combine(new string[] { "images", "examsearch-thumbnails", _examSearchHelper.GenerateThumbnailImageName(examPaperFileName, isProblemTypeExists) })); | |
await thumbnailBlob.UploadFromFileAsync(System.IO.Path.Combine(new string[] { _hostingEnv.WebRootPath, "images", "examsearch-thumbnails", _examSearchHelper.GenerateThumbnailImageName(examPaperFileName, isProblemTypeExists) })); | |
System.IO.File.Delete(System.IO.Path.Combine(new string[] { _hostingEnv.WebRootPath, "images", "examsearch-thumbnails", _examSearchHelper.GenerateThumbnailImageName(examPaperFileName, isProblemTypeExists) })); | |
} | |
catch (System.Exception e1) | |
{ | |
ModelState.AddModelError(string.Empty, "썸네일 이미지 생성에 실패했습니다. 관리자에게 연락해주세요."); | |
ViewData["ErrorMessage"] = "썸네일 이미지 생성에 실패했습니다. 관리자에게 연락해주세요."; | |
return View(model); | |
} | |
} | |
// Upload file. | |
// Full path to cloud storage file. | |
string cloudStorageFullPath = _examSearchHelper.GenerateCloudStorageFullPath(examPaperFileName); | |
CloudBlockBlob blob = container.GetBlockBlobReference(cloudStorageFullPath); | |
// Check if file already exists. | |
bool isBlobExists = await blob.ExistsAsync(); | |
if (isBlobExists) | |
{ | |
ModelState.AddModelError(string.Empty, "이미 업로드된 파일입니다. 시험지 목록을 참고해주세요."); | |
ViewData["ErrorMessage"] = "이미 업로드된 파일입니다. 시험지 목록을 참고해주세요."; | |
return View(model); | |
} | |
blob.Properties.ContentType = model.ExamPaperFile.ContentType; | |
await blob.UploadFromStreamAsync(model.ExamPaperFile.OpenReadStream()); | |
CloudBlockBlob solutionBlob = null; | |
if (model.SolutionFile != null) | |
{ | |
string cloudStorageSolutionFullPath = _examSearchHelper.GenerateCloudStorageFullPath(solutionFileName); | |
solutionBlob = container.GetBlockBlobReference(cloudStorageSolutionFullPath); | |
bool isSolutionBlobExists = await solutionBlob.ExistsAsync(); | |
if (isSolutionBlobExists) | |
{ | |
ModelState.AddModelError(string.Empty, "이미 업로드된 해설지입니다. 시험지 목록을 참고해주세요."); | |
ViewData["ErrorMessage"] = "이미 업로드된 해설지입니다. 시험지 목록을 참고해주세요."; | |
await blob.DeleteAsync(); | |
return View(model); | |
} | |
solutionBlob.Properties.ContentType = model.SolutionFile.ContentType; | |
await solutionBlob.UploadFromStreamAsync(model.SolutionFile.OpenReadStream()); | |
} | |
// Create view file. | |
if (System.IO.File.Exists(System.IO.Path.Combine(new string[] { _hostingEnv.WebRootPath, "ExamSearch-Partial", _examSearchHelper.GenerateViewFileName(examPaperFileName, isProblemTypeExists) }))) | |
{ | |
ModelState.AddModelError(string.Empty, "이미 페이지가 생성되었습니다. 관리자에게 연락해주세요."); | |
ViewData["ErrorMessage"] = "이미 페이지가 생성되었습니다. 관리자에게 연락해주세요."; | |
await blob.DeleteAsync(); | |
if (model.SolutionFile != null) | |
{ | |
await solutionBlob.DeleteAsync(); | |
} | |
return View(model); | |
} | |
int entityMonth = 0; | |
if (model.Type == "수능기출문제") { entityMonth = model.Date.Month; } | |
// Create database entity. | |
ExamPaper examPaper = new ExamPaper | |
{ | |
Type = model.Type, | |
SchoolYear = model.SchoolYear, | |
Year = model.Date.Year + 1, | |
Month = entityMonth, | |
Date = model.Date, | |
Subject = model.Subject, | |
ProblemType = model.ProblemType, | |
IsExamPaperFileExists = true, | |
IsSolutionFileExists = isSolutionFileExists, | |
ExamPaperDownloadCount = 0, | |
SolutionDownloadCount = 0 | |
}; | |
_context.ExamPapers.Add(examPaper); | |
int examPaperSaveResult = _context.SaveChanges(); | |
if (examPaperSaveResult > 0) | |
{ | |
float? level9Ratio = null; | |
if ( | |
model.Level1Ratio.HasValue && | |
model.Level2Ratio.HasValue && | |
model.Level3Ratio.HasValue && | |
model.Level4Ratio.HasValue && | |
model.Level5Ratio.HasValue && | |
model.Level6Ratio.HasValue && | |
model.Level7Ratio.HasValue && | |
model.Level8Ratio.HasValue) | |
{ | |
level9Ratio = 100.0f - (model.Level1Ratio + model.Level2Ratio + model.Level3Ratio + model.Level4Ratio + model.Level5Ratio + model.Level6Ratio + model.Level7Ratio + model.Level8Ratio); | |
} | |
ExamLevelCutline cutline = new ExamLevelCutline | |
{ | |
MaximumNormalizedScoreRatio = model.MaximumNormalizedScoreRatio, | |
MaximumNormalizedScore = model.MaximumNormalizedScore, | |
MinimumNormalizedScore = model.MinimumNormalizedScore, | |
Level1NormalizedScore = model.Level1NormalizedScore, | |
Level1OriginalScore = model.Level1OriginalScore, | |
Level1Ratio = model.Level1Ratio, | |
Level2NormalizedScore = model.Level2NormalizedScore, | |
Level2OriginalScore = model.Level2OriginalScore, | |
Level2Ratio = model.Level2Ratio, | |
Level3NormalizedScore = model.Level3NormalizedScore, | |
Level3OriginalScore = model.Level3OriginalScore, | |
Level3Ratio = model.Level3Ratio, | |
Level4NormalizedScore = model.Level4NormalizedScore, | |
Level4OriginalScore = model.Level4OriginalScore, | |
Level4Ratio = model.Level4Ratio, | |
Level5NormalizedScore = model.Level5NormalizedScore, | |
Level5OriginalScore = model.Level5OriginalScore, | |
Level5Ratio = model.Level5Ratio, | |
Level6NormalizedScore = model.Level6NormalizedScore, | |
Level6OriginalScore = model.Level6OriginalScore, | |
Level6Ratio = model.Level6Ratio, | |
Level7NormalizedScore = model.Level7NormalizedScore, | |
Level7OriginalScore = model.Level7OriginalScore, | |
Level7Ratio = model.Level7Ratio, | |
Level8NormalizedScore = model.Level8NormalizedScore, | |
Level8OriginalScore = model.Level8OriginalScore, | |
Level8Ratio = model.Level8Ratio, | |
Level9Ratio = level9Ratio, | |
ExamPaperId = examPaper.ExamPaperId | |
}; | |
_context.ExamLevelCutlines.Add(cutline); | |
int cutlineSaveResult = _context.SaveChanges(); | |
if (cutlineSaveResult <= 0) | |
{ | |
ModelState.AddModelError(string.Empty, "데이터베이스 에러입니다. 관리자에게 문의해주세요."); | |
ViewData["ErrorMessage"] = "데이터베이스 에러입니다. 관리자에게 문의해주세요."; | |
return View(model); | |
} | |
else | |
{ | |
ViewData["SuccessMessage"] = "시험지 정보 생성에 성공했습니다! 시험지 이름: " + _examSearchHelper.GetDisplayNameForExamPaper(examPaper); | |
return View("Create"); | |
} | |
} | |
else | |
{ | |
ModelState.AddModelError(string.Empty, "데이터베이스 에러입니다. 관리자에게 문의해주세요."); | |
ViewData["ErrorMessage"] = "데이터베이스 에러입니다. 관리자에게 문의해주세요."; | |
return View(model); | |
} | |
} | |
} | |
} | |
} | |
[HttpGet] | |
[Authorize] | |
public IActionResult Edit() | |
{ | |
// Code omitted | |
} | |
[HttpPost] | |
[Authorize] | |
public async Task<IActionResult> Edit(ExamSearchEditViewModel model) | |
{ | |
// Code omitted. | |
} | |
[HttpPost] | |
[Authorize] | |
public async Task<IActionResult> Delete() | |
{ | |
string examCode = (string)RouteData.Values["examcode"]; | |
// Validate exam code. | |
bool isExamCodeValid = _examSearchHelper.IsExamCodeValid(examCode); | |
if (!isExamCodeValid) | |
{ | |
return Json(new | |
{ | |
Success = false, | |
ErrorMessage = "시험지 코드가 정확하지 않습니다. 다시 확인해주세요." | |
}); | |
} | |
// Get exam paper. | |
ExamPaper targetExamPaper = _examSearchHelper.FindExamPaperByExamCode(examCode); | |
if (targetExamPaper == null) | |
{ | |
return Json(new | |
{ | |
Success = false, | |
ErrorMessage = "없는 시험지입니다. 다시 확인해주세요." | |
}); | |
} | |
else | |
{ | |
// Delete exam level cutline. | |
ExamLevelCutline targetExamLevelCutline = targetExamPaper.ExamLevelCutline; | |
_context.ExamLevelCutlines.Remove(targetExamLevelCutline); | |
int examLevelCutlineDeleteResult = _context.SaveChanges(); | |
if (examLevelCutlineDeleteResult > 0) | |
{ | |
// Delete exam paper. | |
// Generate cloud storage account. | |
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(_configuration.GetConnectionString("AzureStorageConnection")); | |
// Get blob client. | |
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); | |
// Get access to container for 'testcloud' service. | |
CloudBlobContainer container = blobClient.GetContainerReference("testcloud"); | |
// First, delete exam paper thumbnail. | |
string examPaperFileName = _examSearchHelper.GenerateFileNameByExamPaper(targetExamPaper, true); | |
bool isProblemTypeExists = _examSearchHelper.IsProblemTypeExists(new System.Text.StringBuilder().Append(examPaperFileName.Take(examPaperFileName.LastIndexOf('.')).ToArray()).ToString()); | |
CloudBlockBlob thumbnailBlob = container.GetBlockBlobReference(System.IO.Path.Combine(new string[] { "images", "examsearch-thumbnails", _examSearchHelper.GenerateThumbnailImageName(examPaperFileName, isProblemTypeExists) })); | |
await thumbnailBlob.DeleteIfExistsAsync(); | |
// Second, delete cloud stored exam paper. | |
string cloudStorageFullPathExamPaper = _examSearchHelper.GenerateCloudStorageFullPath(examPaperFileName); | |
CloudBlockBlob examPaperBlob = container.GetBlockBlobReference(cloudStorageFullPathExamPaper); | |
await examPaperBlob.DeleteIfExistsAsync(); | |
// Third, delete cloud stored solution file if exists. | |
if (targetExamPaper.IsSolutionFileExists) | |
{ | |
string solutionFileName = _examSearchHelper.GenerateFileNameByExamPaper(targetExamPaper, false); | |
string cloudStorageFullPathSolution = _examSearchHelper.GenerateCloudStorageFullPath(solutionFileName); | |
CloudBlockBlob solutionBlob = container.GetBlockBlobReference(cloudStorageFullPathSolution); | |
await solutionBlob.DeleteIfExistsAsync(); | |
} | |
// Finally, delete exam paper entity. | |
_context.ExamPapers.Remove(targetExamPaper); | |
int examPaperDeleteResult = _context.SaveChanges(); | |
if (examPaperDeleteResult > 0) | |
{ | |
return Json(new | |
{ | |
Success = true | |
}); | |
} | |
else | |
{ | |
return Json(new | |
{ | |
Success = false, | |
ErrorMessage = "데이터베이스 에러입니다. 관리자에게 연락해주세요." | |
}); | |
} | |
} | |
else | |
{ | |
return Json(new | |
{ | |
Success = false, | |
ErrorMessage = "데이터베이스 에러입니다. 관리자에게 연락해주세요." | |
}); | |
} | |
} | |
} | |
[HttpGet] | |
public async Task<IActionResult> SearchResult([FromQuery] ExamSearchSearchResultRequestModel model) | |
{ | |
if (!ModelState.IsValid) | |
{ | |
return View("NotFount"); | |
} | |
else | |
{ | |
List<ExamSearchSearchResultElement> examPapers = _context | |
.ExamPapers | |
.Include(ep => ep.ExamLevelCutline) | |
.Where(ep => ep.Type == model.Type && ep.Year == model.Year && ep.SchoolYear == model.SchoolYear && ep.Month == model.Month) | |
.OrderBy(ep => _examSearchHelper.GetSubjectPriority(ep.Subject)) | |
.ThenBy(ep => _examSearchHelper.GetSafeProblemType(ep)) | |
.Select(ep => new ExamSearchSearchResultElement | |
{ | |
ExamPaper = ep, | |
ExamCode = _examSearchHelper.GenerateExamCodeByExamPaper(ep), | |
DisplayName = _examSearchHelper.GetDisplayNameForExamPaper(ep), | |
ExamPreparer = _examSearchHelper.GetExamPreparer(ep), | |
Difficulty = _examSearchHelper.GetDifficulty(ep), | |
TimeLimit = _examSearchHelper.GetTimeLimit(ep.Type, ep.Subject), | |
ProblemCount = _examSearchHelper.GetProblemCount(ep.Type, ep.Subject) | |
}) | |
.ToList(); | |
return View(new ExamSearchSearchResultViewModel | |
{ | |
ExamPapers = examPapers, | |
Type = model.Type, | |
Year = model.Year, | |
SchoolYear = model.SchoolYear, | |
Month = model.Month, | |
ExamDisplayName = _examSearchHelper.GetDisplayNameForExam(examPapers[0].ExamPaper) | |
}); | |
} | |
} | |
public IActionResult ListYear(int? year) | |
{ | |
// Code omitted. | |
} | |
public IActionResult ListMonth(int? month) | |
{ | |
// Code omitted. | |
} | |
public IActionResult ListSubject(string subject) | |
{ | |
// Code omitted. | |
} | |
public IActionResult ListAll(string type) | |
{ | |
List<ExamPaper> examPapers = _context.ExamPapers | |
.Where(ep => ep.Type == type) | |
.OrderByDescending(ep => ep.SchoolYear) | |
.ThenByDescending(ep => ep.Year) | |
.ThenByDescending(ep => ep.Month) | |
.ThenBy(ep => ep.Subject) | |
.ThenBy(ep => _examSearchHelper.GetSafeProblemType(ep)) | |
.ToList(); | |
List<ExamSearchListAllElement> elements = examPapers.Select(ep => new ExamSearchListAllElement { ExamCode = _examSearchHelper.GenerateExamCodeByExamPaper(ep), DisplayName = _examSearchHelper.GetDisplayNameForExamPaper(ep), ExamPaper = ep }).ToList(); | |
return View(new ExamSearchListAllViewModel | |
{ | |
ExamPaperElements = elements, | |
TotalExamPaperCount = elements.Count, | |
Years = examPapers.Select(ep => ep.Year).Distinct().OrderByDescending(y => y).ToList(), | |
Months = examPapers.Select(ep => ep.Month).Distinct().OrderByDescending(m => m).ToList(), | |
SchoolYears = examPapers.Select(ep => ep.SchoolYear).Distinct().OrderByDescending(sy => sy).ToList(), | |
Subjects = examPapers.Select(ep => ep.Subject).Distinct().OrderBy(s => s).ToList(), | |
Type = type | |
}); | |
} | |
#region helper | |
#endregion | |
} | |
public class ExamSearchSearchResultRequestModel | |
{ | |
[Required] | |
public string Type { get; set; } | |
[Required] | |
public int Year { get; set; } | |
[Required] | |
public string SchoolYear { get; set; } | |
[Required] | |
public int Month { get; set; } | |
} | |
class ExamSearchIndexExamElementComparer : IEqualityComparer<ExamSearchIndexExamElement> | |
{ | |
// Comparer for ExamSearchIndexExamElement object. | |
public bool Equals(ExamSearchIndexExamElement elem1, ExamSearchIndexExamElement elem2) | |
{ | |
if (Object.ReferenceEquals(elem1, elem2)) | |
{ | |
return true; | |
} | |
if (Object.ReferenceEquals(elem1, null) || Object.ReferenceEquals(elem2, null)) | |
{ | |
return false; | |
} | |
return (elem1.Type == elem2.Type && elem1.Year == elem2.Year && elem1.SchoolYear == elem2.SchoolYear && elem1.Month == elem2.Month && elem1.ExamDisplayName == elem2.ExamDisplayName); | |
} | |
public int GetHashCode(ExamSearchIndexExamElement elem) | |
{ | |
if (Object.ReferenceEquals(elem, null)) | |
{ | |
return 0; | |
} | |
int typeHash = elem.Type.GetHashCode(); | |
int yearHash = elem.Year.GetHashCode(); | |
int schoolYearHash = elem.SchoolYear.GetHashCode(); | |
int monthHash = elem.Month.GetHashCode(); | |
int examDisplayNameHash = elem.ExamDisplayName.GetHashCode(); | |
return typeHash ^ yearHash ^ schoolYearHash ^ monthHash ^ examDisplayNameHash; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment