แสดงมุมมองจากคอนโทรลเลอร์อื่นใน ASP.NET MVC


248

เป็นไปได้หรือไม่ที่จะแสดงมุมมองจากคอนโทรลเลอร์อื่น?

พูดเช่นฉันมีCategoriesControllerและCategory/NotFound.aspxมุมมอง ในขณะที่CategoriesControllerฉันสามารถกลับมาView("NotFound")อย่างง่ายดาย

ตอนนี้บอกว่าฉันมีProductsControllerและการกระทำและดูเพื่อเพิ่มผลิตภัณฑ์ อย่างไรก็ตามการกระทำนี้ต้องการให้เรามีหมวดหมู่เพื่อเพิ่มผลิตภัณฑ์ ตัวอย่างเช่นProducts/Add/?catid=10.

ถ้าฉันไม่สามารถค้นหาหมวดหมู่ตามcatidฉันต้องการแสดงNotFoundมุมมองจากตัวควบคุมหมวดหมู่แทนที่จะสร้างCategoryNotFoundมุมมองภายใต้ตัวควบคุมผลิตภัณฑ์

เป็นไปได้หรือฉันกำลังสร้างสิ่งต่าง ๆ ในทางที่ผิด? มีวิธีที่ดีในการทำเช่นนี้?

คำตอบ:


283

ใช่. โดยค่าเริ่มต้นการตรวจสอบ ASP.NET MVC แรกในแต่หลังจากนั้นถ้ามันไม่ได้หาดูก็จะตรวจสอบใน\Views\[Controller_Dir]\\Views\Shared

ไดเรกทอรีที่ใช้ร่วมกันนั้นมีไว้เพื่อแบ่งปันมุมมองข้ามคอนโทรลเลอร์หลายตัวโดยเฉพาะ เพียงเพิ่มมุมมองของคุณไปยังไดเรกทอรีย่อยที่ใช้ร่วมกันและคุณพร้อมแล้ว

ถ้าคุณทำ return View("~/Views/Wherever/SomeDir/MyView.aspx")คุณสามารถส่งคืนมุมมองใด ๆ ที่คุณต้องการ


ขอบคุณดูเหมือนว่าโซลูชันที่ฉันควรใช้ ฉันยังสงสัยว่าเป็นไปได้หรือไม่ที่จะแสดงมุมมองจากคอนโทรลเลอร์อื่น ฉันเดาว่านี่เป็นการละเมิดกฎบางอย่างใน MVC หรือไม่
dtc

1
ในสถานการณ์ที่คุณอธิบายข้างต้นใช่คุณควรใช้โฟลเดอร์แชร์
Jonathan Freeland

69
ใช่ว่าเป็นไปได้ หากคุณส่งคืนมุมมอง ("~ / Views / ไม่ว่าที่ไหน / SomeDir / MyView.aspx") คุณสามารถส่งคืนมุมมองใดก็ได้ที่คุณต้องการ สิ่งนี้ไม่ได้ละเมิดกฎเฉพาะใด ๆ ต่อ se อย่างไรก็ตาม ASP.Net MVC เป็นเรื่องเกี่ยวกับ "ระเบียบวาระการประชุมผ่านการกำหนดค่า" กล่าวอีกนัยหนึ่งกรอบถูกสร้างขึ้นเพื่อทำงานโดยอัตโนมัติโดยใช้การประชุมบางอย่างและคุณควรใช้มันเป็นไปได้
womp

1
ขอบคุณสำหรับคำอธิบาย ฉันไม่รู้ว่าสามารถเรียกดูได้อย่างนั้น ไดเรกทอรีที่ใช้ร่วมกันของหลักสูตรการทำงานอย่างสมบูรณ์ :)
dtc

1
ฉันไม่ได้อยู่ในคอนโทรลเลอร์ดังนั้นฉันจึงต้องใช้งานnew ViewResult { ViewName = "~/Views/Error/Unauthorised.cshtml" };และใช้ได้
Nacht

162

คุณสามารถใช้ได้:

return View("../Category/NotFound", model);

มีการทดสอบใน ASP.NET MVC 3 แต่ควรทำงานใน ASP.NET MVC 2 ด้วย


3
ทำงานใน MVC 2 และกลายเป็นทางออกที่สะอาดที่สุดสำหรับสถานการณ์ที่ผิดปกติที่ฉันต้องเผชิญ
Todd Menier

3
Resharper จะรายงานลิงก์นั้นว่าเป็นข้อผิดพลาด แต่ก็ยังใช้งานได้
CodeMonkeyKing

1
@CodeMonkeyKing - Resharper 7 (ใน VS2012) "~/Views/Category/NotFound.cshtml"อย่างถูกต้องระบุเส้นทางที่มีรูปแบบเป็น
Richard Ev

น่าสังเกต: โซลูชันนี้ใช้งานได้กับโหมดการแสดงผลเช่นหากคุณมีมุมมอง "/Category/NotFound.Mobile.cshtml"
BenWillkommen

55

ใช่มันเป็นไปได้ ส่งคืนRedirectToAction()เมธอดแบบนี้:

return RedirectToAction("ActionOrViewName", "ControllerName");

1
ฉันเชื่อว่าสิ่งนี้ควรเป็น RedirectToAction ("ActionOrView", "Controller", null) มิฉะนั้นพารามิเตอร์ที่สองคือเส้นทางค่า
Zoran P.

แต่ในกรณีนี้คุณต้องเขียนแอ็คชั่นในคอนโทรลเลอร์ซึ่งแตกต่างจากโซลูชัน View
tobbenb3

@ tobbenb3 นั่นเป็นทางออกที่ดีกว่ามากเมื่อเทียบกับการเข้ารหัสแบบผลลัพธ์ วิธีใดก็ตามที่คุณไม่ควรผ่านในสตริงพา ธ
perustaja

34

คุณเคยลองRedirectToActionไหม


1
ฉันจะบอกว่านี่คือ MVC สำหรับทุกคนที่ไม่ต้องการมุมมอง int เขาแชร์โฟลเดอร์โปรดทราบว่าสำหรับวิธีการแก้ปัญหาอื่น ๆ (เช่นการใช้เส้นทางตรง) ทุกคนที่พยายามพิจารณาปัจจัยมุมมองใหม่จะไม่คำนึงถึง ว่ามันยังถูกใช้ในตัวควบคุมอื่นทำให้เกิดพฤติกรรมที่คาดเดาไม่ได้
yoel halb

4
แล้วโดยไม่เปลี่ยนเส้นทางล่ะ
Luckyy

ทางแก้ปัญหาได้ดีกว่าการย้ายมุมมองไปยังโฟลเดอร์ที่ใช้ร่วมกัน
juFo

โซลูชันนี้ต้องการการดำเนินการกับคอนโทรลเลอร์มุมมอง (directPath) แสดงผลเอาต์พุตโดยไม่ต้องดำเนินการใด ๆ เมื่อคุณเพิ่มการกระทำคุณต้องคิดที่จะซ่อนมันจากการเข้าถึงโดยตรงผ่าน url มันจะสร้างขั้นตอนในประวัติเบราว์เซอร์ ฯลฯ แต่ใช่มันเป็นวิธีของฉัน
Jan Zahradník

3
RedirectToAction ส่งรหัสตอบสนอง 302 ไปยังเบราว์เซอร์ ไม่เหมาะสมเมื่อคุณพยายามแสดงหน้าเว็บ 404 ที่ไม่พบ นั่นคือวิธีนี้ดูเหมือนจะใช้งานได้ แต่จะทำให้เครื่องมือค้นหาสับสน
NightOwl888

20

ใช่คุณสามารถ. คืนแอคชั่นแบบนี้:

return RedirectToAction("View", "Name of Controller");

ตัวอย่าง:

return RedirectToAction("Details/" + id.ToString(), "FullTimeEmployees");

วิธีการนี้จะเรียกวิธีการ GET

นอกจากนี้คุณสามารถส่งผ่านค่าไปยังการดำเนินการเช่นนี้:

return RedirectToAction("Details/" + id.ToString(), "FullTimeEmployees", new {id = id.ToString(), viewtype = "extended" });

ฉันจะส่งวัตถุด้วยวิธีนี้ได้อย่างไร
Djeroen

ลองดู @Djeroen
Ignacio chiazzo

5
คุณไม่ได้ส่งคืนมุมมองคุณกำลังเรียกการกระทำ
0014

เหนือสิ่งอื่นใดมีประโยชน์สำหรับฉัน
anil shrestha

5

นอกจากนี้คุณยังสามารถเรียกควบคุมใด ๆ จากJavaScript / jQuery สมมติว่าคุณมีคอนโทรลเลอร์ที่ส่งคืน 404 หรือการควบคุมผู้ใช้ / หน้าอื่น ๆ จากนั้นในการดำเนินการบางอย่างจากรหัสลูกค้าของคุณคุณสามารถโทรหาที่อยู่บางส่วนที่จะทำการควบคุมและส่งคืนผลลัพธ์ในรูปแบบHTMLรหัสลูกค้าของคุณสามารถรับผลลัพธ์ที่ส่งคืนและวางไว้ในที่ใดก็ตามที่คุณต้องการ ...


ผมไม่ทราบว่า. ดูเหมือนว่ามันเป็นสิ่งที่ฉันจะใช้ในอนาคต ใช่ mvc rock :)
dtc

1

ด้วยรหัสนี้คุณสามารถรับคอนโทรลเลอร์ได้:

var controller = DependencyResolver.Current.GetService<ControllerB>();
controller.ControllerContext = new ControllerContext(this.Request.RequestContext, 
controller);

การแปล: ด้วยรหัสนี้คุณสามารถรับตัวควบคุมใด ๆ : [code], ความนับถือ,
Robert Columbia

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