ความแตกต่างระหว่าง ViewResult () และ ActionResult ()


295

ความแตกต่างระหว่างViewResult()และActionResult()ใน ASP.NET MVC คืออะไร?

public ViewResult Index()
{
    return View();
}

public ActionResult Index()
{
    return View();
}

12
เป็นคำถามที่ดีมาก ฉันดูวิดีโอและสร้างหน่วยทดสอบผู้สอนก่อนจะเปลี่ยนประเภทการส่งคืนของ Action ที่เขากำลังจะทดสอบจาก ActionResult เป็น ViewResult ไม่มีคำอธิบาย .... ผมก็ชอบ "สิ่งที่เราสามารถเพียงแค่สุ่มเปลี่ยนประเภทไม่มีคำอธิบายใด?"
ดั๊กแชมเบอร์เลน

3
อาจเป็นไปได้ว่าเอกสารนี้มีประโยชน์ :) msdn.microsoft.com/en-us/library/…
3885927

คำตอบ:


372

ActionResult เป็นคลาสนามธรรมที่สามารถมีหลายชนิดย่อย

ActionResult ชนิดย่อย

  • ViewResult - แสดงมุมมองที่ระบุไปยังสตรีมการตอบกลับ

  • PartialViewResult - แสดงมุมมองบางส่วนที่ระบุไปยังสตรีมการตอบกลับ

  • EmptyResult - การตอบสนองที่ว่างเปล่าจะถูกส่งกลับ

  • RedirectResult - ดำเนินการเปลี่ยนเส้นทาง HTTP ไปยัง URL ที่ระบุ

  • RedirectToRouteResult - ดำเนินการเปลี่ยนเส้นทาง HTTP ไปยัง URL ที่กำหนดโดยเอ็นจิ้นการจัดเส้นทางตามข้อมูลเส้นทางที่กำหนด

  • JsonResult - ทำให้เป็นอนุกรมวัตถุ ViewData ที่กำหนดให้เป็นรูปแบบ JSON

  • JavaScriptResult - ส่งคืนโค้ด JavaScript ที่สามารถเรียกใช้งานบนไคลเอนต์ได้

  • ContentResult - เขียนเนื้อหาลงในสตรีมการตอบกลับโดยไม่ต้องมีมุมมอง

  • FileContentResult - ส่งคืนไฟล์ไปยังไคลเอ็นต์

  • FileStreamResult - ส่งคืนไฟล์ไปยังไคลเอ็นต์ซึ่งจัดทำโดยสตรีม

  • FilePathResult - ส่งคืนไฟล์ไปยังไคลเอ็นต์

ทรัพยากร


5
อะไรคือข้อดีของการคืน ViewResult ผ่าน ActionResult - มันมีความหมายมากกว่านี้เล็กน้อยและแสดงให้เห็นถึงเจตนาของคุณ - แต่ในทางปฏิบัติแล้วไม่แตกต่างกัน?
niico

121

ActionResultเป็นคลาสนามธรรม

ViewResultมาจากActionResult ชั้นเรียนมาอื่น ๆ ได้แก่JsonResultและPartialViewResult

คุณประกาศด้วยวิธีนี้เพื่อให้คุณสามารถใช้ประโยชน์จาก polymorphism และคืนค่าชนิดต่าง ๆ ในวิธีเดียวกัน

เช่น:

public ActionResult Foo()
{
   if (someCondition)
     return View(); // returns ViewResult
   else
     return Json(); // returns JsonResult
}

2
หมายความว่าเราควรส่งคืน ActionResult เสมอเพื่อให้เราได้รับประโยชน์จากมัน หรือมีข้อ จำกัด หรือผลข้างเคียงของสิ่งนี้หรือไม่?
Adarsh ​​Kumar

5
@Adarsh ​​- เหมือนกับคลาสนามธรรมใน C # ประกาศด้วยวิธีนี้หากคุณต้องการสรุปแค็ปซูลการนำไปใช้ภายในเมธอดหรือต้องการพิสูจน์ API ของคุณสำหรับการพิมพ์อื่น ถ้าไม่ใช้คอนกรีต ฉันมักใช้คอนกรีต (เช่น ViewResult หรือ JsonResult)
RPM1984

31

ด้วยเหตุผลเดียวกับที่คุณไม่ได้เขียนวิธีการทุก ๆ คลาสเพื่อส่งคืน "วัตถุ" คุณควรเจาะจงให้มากที่สุดเท่าที่จะทำได้ สิ่งนี้มีค่ามากหากคุณวางแผนที่จะเขียนการทดสอบหน่วย ไม่มีประเภทการทดสอบส่งคืนและ / หรือการคัดเลือกผลลัพธ์


การทำความสะอาดโค้ดและการทดสอบหน่วยเป็นประโยชน์ของการใช้ ViewResult ตามประสบการณ์ของฉัน
JoshYates1980

20

ViewResult เป็นคลาสย่อยของ ActionResult กระบวนการดูวิธีการส่งกลับ ViewResult ดังนั้นตัวอย่างโค้ดสองอันนี้ก็ทำแบบเดียวกัน ความแตกต่างเพียงอย่างเดียวคือด้วย ActionResult หนึ่งคอนโทรลเลอร์ของคุณไม่ได้สัญญาว่าจะส่งคืนมุมมอง - คุณสามารถเปลี่ยนเนื้อหาของเมธอดเพื่อส่งคืน RedirectResult หรืออย่างอื่นโดยไม่มีเงื่อนไขโดยไม่ต้องเปลี่ยนนิยามของเมธอด


11

ในขณะที่คำตอบอื่น ๆ ได้บันทึกความแตกต่างอย่างถูกต้องโปรดทราบว่าหากคุณกลับมาเป็น ViewResult เท่านั้นจะเป็นการดีกว่าที่จะคืนค่าชนิดที่เฉพาะเจาะจงมากกว่าประเภท ActionResult พื้นฐาน ข้อยกเว้นที่ชัดเจนสำหรับหลักการนี้คือเมื่อเมธอดของคุณส่งคืนหลายชนิดที่ได้รับจาก ActionResult

สำหรับการอภิปรายอย่างเต็มรูปแบบของเหตุผลที่อยู่เบื้องหลังหลักการนี้โปรดดูการอภิปรายที่เกี่ยวข้องที่นี่: วิธีการ ASP.NET MVC Controller ต้องส่งคืน ActionResult


4

ในตัวควบคุมหนึ่งสามารถใช้ไวยากรณ์ด้านล่าง

public ViewResult EditEmployee() {
    return View();
}

public ActionResult EditEmployee() {
    return View();
}

ในตัวอย่างด้านบนเฉพาะประเภทการคืนเท่านั้นที่จะแตกต่างกันไป หนึ่งส่งคืนViewResultในขณะที่อีกหนึ่งส่งกลับActionResultในขณะที่อีกหนึ่งผลตอบแทน

ActionResult เป็นคลาสนามธรรม สามารถยอมรับได้:

ViewResult, PartialViewResult, EmptyResult, RedirectResult, RedirectToRouteResult, JsonResult, JavaScriptResult, ContentResult, FileContentResult, FileStreamResult, FilePathResult เป็นต้น

ViewResultเป็น subclass ActionResultของ


4
ฉันไม่แน่ใจว่านี่คือสิ่งที่คุณหมายถึง แต่ในกรณีที่ฉันต้องการชี้แจงว่าคุณไม่สามารถมีสองวิธีในเวลาเดียวกันได้เนื่องจากชื่อและพารามิเตอร์ (ไม่) เหมือนกัน ไม่สามารถโหลดวิธีมากเกินไปได้โดยเปลี่ยนประเภทผลลัพธ์เท่านั้น
Andrew

0

ใน Controller ฉันได้ระบุรหัสด้านล่างด้วย ActionResult ซึ่งเป็นคลาสพื้นฐานที่สามารถมี 11 ชนิดย่อยใน MVC เช่น: ViewResult, FileialResult ,ResultResultResult, RedResToRouteR, JsonResult, JavaScriptResult, FileContentResult

    public ActionResult Index()
                {
                    if (HttpContext.Session["LoggedInUser"] == null)
                    {
                        return RedirectToAction("Login", "Home");
                    }

                    else
                    {
                        return View(); // returns ViewResult
                    }

                }
//More Examples

    [HttpPost]
    public ActionResult Index(string Name)
    {
     ViewBag.Message = "Hello";
     return Redirect("Account/Login"); //returns RedirectResult
    }

    [HttpPost]
    public ActionResult Index(string Name)
    {
    return RedirectToRoute("RouteName"); // returns RedirectToRouteResult
    }

ในทำนองเดียวกันเราสามารถกลับ 11 ชนิดย่อยทั้งหมดเหล่านี้โดยใช้ ActionResult () โดยไม่ต้องระบุทุกวิธีการย่อยอย่างชัดเจน ActionResult เป็นสิ่งที่ดีที่สุดถ้าคุณกลับมาใช้มุมมองประเภทอื่น


0

เพื่อช่วยคุณประหยัดเวลานี่คือคำตอบจากลิงก์ในคำตอบก่อนหน้านี้ที่https://forums.asp.net/t/1448398.aspx

ActionResult เป็นคลาสนามธรรมและเป็นคลาสพื้นฐานสำหรับคลาส ViewResult

ในกรอบ MVC จะใช้คลาส ActionResult เพื่ออ้างอิงวัตถุที่วิธีการดำเนินการของคุณส่งคืน และเรียกใช้วิธี ExecuteResult

และ ViewResult เป็นการใช้งานสำหรับคลาสนามธรรมนี้ มันจะพยายามค้นหาหน้ามุมมอง (โดยปกติจะเป็นหน้า aspx) ในบางเส้นทางที่กำหนดไว้ล่วงหน้า (/ views / controllername /, / views / shared /, ฯลฯ ) โดยใช้ชื่อมุมมองที่กำหนด

เป็นวิธีปฏิบัติที่ดีที่จะให้วิธีการของคุณคืนชั้นเรียนที่เฉพาะเจาะจงมากขึ้น ดังนั้นหากคุณแน่ใจว่าวิธีการกระทำของคุณจะกลับมาบางหน้าดูคุณสามารถใช้ ViewResult แต่ถ้าวิธีการกระทำของคุณอาจมีพฤติกรรมที่แตกต่างกันเช่นแสดงภาพหรือเปลี่ยนเส้นทาง คุณสามารถใช้คลาสพื้นฐานเพิ่มเติม ActionResult เป็นชนิดส่งคืนได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.