Hiển thị khung nhìn từ bộ điều khiển khác trong ASP.NET MVC


248

Có thể hiển thị một khung nhìn từ bộ điều khiển khác?

Nói ví dụ tôi có một CategoriesControllervà một Category/NotFound.aspxquan điểm. Trong khi ở CategoriesController, tôi có thể dễ dàng trở lại View("NotFound").

Bây giờ nói rằng tôi có một ProductsControllervà một hành động và xem để thêm một sản phẩm. Tuy nhiên, hành động này yêu cầu chúng tôi có Danh mục để thêm Sản phẩm vào. Ví dụ , Products/Add/?catid=10.

Nếu tôi không thể tìm thấy Danh mục dựa trên catid, tôi muốn hiển thị NotFoundchế độ xem từ bộ điều khiển Danh mục thay vì tạo CategoryNotFoundchế độ xem trong bộ điều khiển Sản phẩm.

Điều này có thể hay tôi đang cấu trúc mọi thứ theo cách sai? Có một cách tốt để làm điều này?

Câu trả lời:


283

Đúng. Theo mặc định, ASP.NET MVC kiểm tra trước \Views\[Controller_Dir]\, nhưng sau đó, nếu không tìm thấy khung nhìn, nó sẽ kiểm tra \Views\Shared.

Thư mục dùng chung có sẵn để chia sẻ Lượt xem trên nhiều bộ điều khiển. Chỉ cần thêm Chế độ xem của bạn vào thư mục con được chia sẻ và bạn sẽ ổn.

Nếu bạn làm return View("~/Views/Wherever/SomeDir/MyView.aspx")Bạn có thể trả lại bất kỳ Chế độ xem nào bạn muốn.


Cảm ơn, điều này nghe giống như giải pháp tôi nên sử dụng. Tôi vẫn tự hỏi nếu có thể hiển thị View từ một bộ điều khiển khác. Tôi đoán điều này vi phạm một số quy tắc trong MVC?
dtc

1
Trong tình huống bạn mô tả ở trên, có, bạn nên sử dụng thư mục Dùng chung.
Jonathan Freeland

69
Đúng, điều đó cũng có thể. Nếu bạn quay lại Chế độ xem ("~ / Lượt xem / Bất cứ nơi nào / Một sốDir / MyView.aspx") Bạn có thể trả lại bất kỳ Chế độ xem nào bạn muốn. Điều này không vi phạm bất kỳ quy tắc cụ thể nào, tuy nhiên, ASP.Net MVC hoàn toàn là về "quy ước về cấu hình". Nói cách khác, khung được xây dựng để vận hành tự động bằng cách sử dụng các quy ước nhất định và bạn nên sử dụng nó nếu có thể.
vào

1
Cảm ơn đã giải thích. Tôi không biết Lượt xem có thể được gọi như thế. Tất nhiên, thư mục được chia sẻ hoạt động hoàn hảo :)
dtc

1
Tôi không ở trong Bộ điều khiển, vì vậy tôi phải sử dụng new ViewResult { ViewName = "~/Views/Error/Unauthorised.cshtml" };và nó đã hoạt động
Nacht

162

Bạn có thể dùng:

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

Nó đã được thử nghiệm trong ASP.NET MVC 3, nhưng cũng sẽ hoạt động trong ASP.NET MVC 2.


3
Hoạt động trong MVC 2, và hóa ra là giải pháp sạch nhất cho một tình huống bất thường mà tôi đang xử lý.
Todd Menier

3
Resharper sẽ báo cáo liên kết đó là một lỗi nhưng nó vẫn hoạt động.
CodeMonkeyKing

1
@CodeMonkeyKing - Resharper 7 (trong VS2012) xác định chính xác một đường dẫn được định dạng là "~/Views/Category/NotFound.cshtml".
Richard Ev

Đáng chú ý: giải pháp này hoạt động với các chế độ hiển thị, ví dụ: nếu bạn có chế độ xem "/Carget/NotFound.Mobile.cshtml".
BenWillkommen

55

Vâng nó có thể. Trả về một RedirectToAction()phương thức như thế này:

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

1
Tôi tin rằng điều này sẽ diễn ra như RedirectToAction ("ActionOrView", "Trình điều khiển", null) vì nếu không thì thông số thứ hai là routeValues
Zoran P.

Nhưng trong trường hợp này, bạn phải thực sự viết hành động trong bộ điều khiển, không giống như giải pháp View.
tobbenb3

@ tobbenb3 Đó là một giải pháp tốt hơn nhiều so với kết quả mã hóa cứng. Dù bằng cách nào bạn cũng không nên vượt qua trong một chuỗi đường dẫn.
perustaja

34

Bạn đã thử RedirectToActionchưa


1
Tôi sẽ nói rằng đây là MVC cho bất kỳ ai không muốn xem các thư mục chia sẻ của anh ấy, lưu ý rằng đối với tất cả các giải pháp khác (như sử dụng đường dẫn trực tiếp), bất kỳ ai đang cố gắng xác định lại các lượt xem sẽ không phải ghi nhớ rằng nó cũng đang được sử dụng trong một bộ điều khiển khác, dẫn đến hành vi không thể đoán trước
yoel halb

4
Làm thế nào về mà không chuyển hướng?
Luckyy

giải pháp tốt hơn là chuyển chế độ xem sang thư mục dùng chung
juFo

Giải pháp này yêu cầu hành động trên bộ điều khiển, View (directPath) hiển thị đầu ra mà không có bất kỳ hành động nào. Khi bạn thêm một hành động, bạn cần phải suy nghĩ để ẩn nó khỏi truy cập trực tiếp qua url, nó sẽ tạo ra một bước trong lịch sử trình duyệt, v.v. Nhưng vâng, đó là cách của tôi.
Jan Zahradník

3
RedirectToAction gửi mã phản hồi 302 đến trình duyệt. Điều đó không phù hợp khi bạn đang cố hiển thị trang 404 không tìm thấy. Đó là, giải pháp này có vẻ hiệu quả nhưng sẽ gây nhầm lẫn cho các công cụ tìm kiếm.
NightOwl888

20

Vâng, bạn có thể. Trả lại một hành động như thế này:

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

Một ví dụ:

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

Cách tiếp cận này sẽ gọi phương thức GET

Ngoài ra, bạn có thể chuyển các giá trị cho hành động như thế này:

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

Làm thế nào tôi có thể gửi một đối tượng với phương pháp này?
Djeroen

Hãy xem @Djeroen
ignacio chiazzo 16/2/2016

5
Bạn không trả lại một lượt xem, bạn đang gọi một hành động.
0014

Trên hết là hữu ích cho tôi.
anil shrestha

5

Bạn cũng có thể gọi bất kỳ bộ điều khiển nào từ JavaScript / jQuery . Giả sử bạn có bộ điều khiển trả về 404 hoặc một số điều khiển / trang người dùng khác. Sau đó, trên một số hành động, từ mã máy khách của bạn, bạn có thể gọi một số địa chỉ sẽ kích hoạt bộ điều khiển của bạn và trả về kết quả ở định dạng HTML, mã khách hàng của bạn có thể lấy kết quả trả về này và đặt nó ở bất cứ đâu bạn muốn trong trang của mình ...


Tôi không biết điều đó. Nghe có vẻ như đó là thứ tôi có thể sử dụng trong tương lai. Vâng, mvc đá :)
dtc

1

Với mã này, bạn có thể có được bất kỳ bộ điều khiển nào:

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

Dịch: Với mã này, bạn có thể có được bất kỳ bộ điều khiển nào: [code], Trân trọng,
Robert Columbia

3
Mặc dù mã này có thể trả lời câu hỏi, việc cung cấp ngữ cảnh bổ sung về cách thức và / hoặc lý do giải quyết vấn đề sẽ cải thiện giá trị lâu dài của câu trả lời.
Nic3500
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.