ActionResult
action method는 ActionResult instance를 반환한다.
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
ActionResult는 abstract class이며, 모든 action result의 base class이다.
ExecuteResult라는 abstract method가 있으며, 파생 class에서 구현한다.
ActionResult는 많은 파생 class를 가지고 있으며, 다음 3가지로 유형으로 나눌 수 있다.
content-returning, redirection, status results
예를들면 ContentResult Class는 아래와 같이 ActionResult Class 클래스를 구현한다.
차례로 살펴보자.
Content-Returning Results
ActionResult를 구현하며, browser나 호출한 script로 content를 반환한다.
ViewResult
view를 반환한다.
public ViewResult Index()
{
return View();
}
PartialViewResult
partial view를 반환한다.
public PartialViewResult Partial()
{
return PartialView("CustomPartial");
}
FileResult
파일을 반환한다.
public FileResult ViewFile()
{
return File(Url.Content("~/Files/testfile.txt"), "text/plain");
}
public FileResult FileBytes()
{
// return byte array
byte[] fileBytes =
System.IO.File.ReadAllBytes(Server.MapPath("~/Files/testfile.txt"));
return File(fileBytes, "text/plain");
}
public FileResult DownloadFile()
{
// rename download file
return File(Url.Content("~/Files/testfile.txt"),
"text/plain",
"testFile.txt");
}
파일을 다운로드
<a href="/Account/FileDownload" download>다운로드</a>
public FileResult FileDownload()
{
string str = "<h1>Hello, world</h1>";
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(str);
return File(bytes, "text/html");
}
ContentResult
content, MIME type을 지정하여 원하는 내용을 반환한다.
public ContentResult Content()
{
return Content("<h3>Here's a custom content header</h3>", "text/html");
}
// return type이 string이면, ContentResult instance로 wrap하여 반환한다.
public string Content()
{
return "<h3>Here's a custom content header</h3>";
}
EmptyResult
아무것도 반환하지 않는다.
public EmptyResult Empty()
{
return new EmptyResult();
}
public ActionResult NothingReturned()
{
return null; //Returns an EmptyResult
}
JsonResult
Ajax 호출에서 많이 사용되는 class이다.
public JsonResult Json()
{
return Json(new { Name = "John Smith",
ID = 4,
DateOfBirth = new DateTime(1999, 12, 31) },
JsonRequestBehavior.AllowGet);
}
JavaScriptResult
script를 반환한다.
public JavaScriptResult LoadScript()
{
return JavaScript("alert('Hello! This popup shows that we can return JavaScript from controller actions.')");
}
view에서 다음과 같이 할 수 있다.
<script type="text/javascript" src="@Url.Action("LoadScript")"></script>
MVVM, 그 외 동적 script 사용시에 유용하다.
하지만, Controller가 View 기능에 관여하게 되어 separation of concern을 위반하므로 사용에 주의해야 한다.
Redirection Results
다른 URL이나 action으로 redirecting하는 ActionResult 파생 클래스를 살펴보자.
RedirectResult
외부 site로 redirect 할때 사용한다.
public RedirectResult RedirectToOtherSite()
{
return Redirect("https://www.google.com/");
}
RedirectToRouteResult
same app에서 page redirect 시, 사용한다.
action 에서 another action으로 이동시킨다.
public RedirectToRouteResult RedirectToRoute()
{
// route object를 생성한다.
return RedirectToRoute(new { controller = "Home", action = "Route" });
}
public RedirectToRouteResult RedirectToAction()
{
// controller를 명시하지 않으면, current controller에서 Action action을 찾는다.
// controller, action, route value 등등 명시할 수 있다.
return RedirectToAction("Action");
}
Status Results
browser로 status code를 반환한다.
HttpStatusCodeResult
HTTP status code와, 표시할 custom message를 browser로 반환한다.
public HttpStatusCodeResult UnauthorizedStatusCode()
{
return new HttpStatusCodeResult(HttpStatusCode.Unauthorized, "You are not authorized to access this controller action.");
}
public HttpStatusCodeResult BadGateway()
{
return new HttpStatusCodeResult(HttpStatusCode.BadGateway, "I have no idea what this error means.");
}
HttpStatusCode enum은 모든 HTTP status code를 포함한다.
custom error page가 있을 때, exception 처리하기 좋다.
몇몇 자주 사용되는 status code를 위해 다음 파생 class가 있다.
HttpUnauthorizedResult
HttpUnauthorizedResult는 HttpStatusCode.Unauthorized를 반환하는 것과 동일하지만, 더 가독성이 있다.
public HttpStatusCodeResult UnauthorizedResult()
{
return new HttpUnauthorizedResult("You are not authorized to access this controller action.");
}
HttpNotFoundResult
public HttpNotFoundResult NotFound()
{
return HttpNotFound("We didn't find that action, sorry!");
}
Custom ActionResult
action methods에서 중복되는 코드를 제거하고, test하기 어려운 action을 만드는 dependency를 extract하는데 사용된다.
1) 중복코드를 담당하는 custom action result만들기
object collection에서 csv file을 만드는 action result
public class CsvActionResult : ActionResult
{
public IEnumerable ModelListing { get; set; }
public CsvActionResult(IEnumerable modelListing)
{
ModelListing = modelListing;
}
public override void ExecuteResult(
ControllerContext context)
{
byte[] data = new CsvFileCreator()
.AsBytes(ModelListing);
var fileResult = new FileContentResult(
data, "text/csv")
{
FileDownloadName = "CsvFile.csv";
}
fileResult.ExecuteResult(context);
}
public class CsvFileCreator
{
public byte[] AsBytes(IEnumerable modelList)
{
StringBuilder sb = new StringBuilder();
BuildHeaders(modelList, sb);
BuildRows(modelList, sb);
return sb.AsBytes();
}
private void BuildHeaders(
IEnumerable modelList, StringBuilder sb)
{
foreach (PropertyInfo property in
modelList.GetType().GetElementType().GetProperties())
{
sb.AppendFormat("{0},", property.Name);
}
sb.NewLine();
}
private void BuildRows(
IEnumerable modelList, StringBuilder sb)
{
foreach (object modelItem in modelList)
{
BuildRowData(modelList, modelItem, sb);
sb.NewLine();
}
}
private void BuildRowData(
IEnumerable modelList, object modelItem,
StringBuilder sb)
{
foreach (PropertyInfo info in
modelList.GetType().GetElementType().GetProperties())
{
object value = info.GetValue(modelItem, new object[0]);
sb.AppendFormat("{0},", value);
}
}
}
아래 ExportUsers action은 CSV file생성 로직이 CsvActionResult action result로 이동하여 소스가 간단해졌다.
public ActionResult Export()
{
return View();
}
public ActionResult ExportUsers()
{
IEnumerable<User> model = UserRepository.GetUsers();
return new CsvActionResult(model);
}
로직을 분리하여, 재사용성이 높아졌다.
2) 테스트하기 어려운 의존성 제거
public class LogoutActionResult : ActionResult
{
public RedirectToRouteResult ActionAfterLogout
{
get; set;
}
public LogoutActionResult(RedirectToRouteResult actionAfterLogout)
{
ActionAfterLogout = actionAfterLogout
}
public override void ExecuteResult(ControllerContext context)
{
FormsAuthentication.SignOut();
ActionAfterLogout.ExecuteResult(context);
}
}
public ActionResult Logout()
{
var redirect = RedirectToAction("Index", "Home");
return new LogoutActionResult(redirect);
}
'ASP.NET MVC' 카테고리의 다른 글
ASP.NET MVC] Ajax Request - .load() (0) | 2022.07.12 |
---|---|
ASP.NET MVC] View Model (0) | 2022.07.11 |
ASP.NET MVC] Controller, Actions, IController, ControllerBase (0) | 2022.07.11 |
ASP.NET MVC] Sub Select Option 동적 변경 (0) | 2022.05.27 |
ASP.NET MVC] Response.ContentType을 사용한 엑셀 다운로드 (1) | 2022.05.27 |
댓글