Відобразити подання з іншого контролера в 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
У ситуації, яку ви описали вище, так, вам слід скористатися папкою Спільний доступ.
Джонатан Фріланд

69
Так, це теж можливо. Якщо ви повернете View ("~ / Views / Wherever / SomeDir / MyView.aspx"), ви можете повернути будь-який перегляд, який ви хочете. Це не порушує жодне конкретне правило, однак, ASP.Net MVC стосується "конвенції про конфігурацію". Іншими словами, рамка побудована для автоматичного функціонування з використанням певних умов, і ви повинні використовувати її там, де це можливо.
утроба

1
Дякую за пояснення. Я не знав, що Погляди можна назвати так. Спільний каталог, звичайно, працює чудово :)
dtc

1
Я не був у контролері, тому довелося використовувати, new ViewResult { ViewName = "~/Views/Error/Unauthorised.cshtml" };і це спрацювало
Нахт,

162

Ви можете використовувати:

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

Він був протестований у ASP.NET MVC 3, але також повинен працювати в ASP.NET MVC 2.


3
Працює в MVC 2 і виявилося найчистішим рішенням незвичної ситуації, з якою я маю справу.
Тод Меньєр

3
Resharper повідомить про це посилання як про помилку, але воно все ще працює.
CodeMonkeyKing

1
@CodeMonkeyKing - Resharper 7 (у VS2012) правильно ідентифікує шлях, відформатований як "~/Views/Category/NotFound.cshtml".
Річард Єв

Варто зауважити: це рішення працює з режимами відображення, наприклад, якщо у вас був перегляд "/Category/NotFound.Mobile.cshtml".
BenWillkommen

55

Так можливо. Повернути такий RedirectToAction()метод:

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

1
Я вважаю, що це має йти як RedirectToAction ("ActionOrView", "Controller", null), інакше другим параметром є routeValues
Zoran P.

Але в цьому випадку вам потрібно насправді записати дію в контролер, на відміну від рішення View.
tobbenb3

@ tobbenb3 Це набагато краще рішення на відміну від жорсткого кодування результату. У будь-якому випадку ви не повинні проходити в рядку шляху.
perustaja

34

Ви пробували RedirectToAction?


1
Я б сказав, що це MVC для тих, хто не хоче представлення даних, якими він поділився, пам'ятайте, що для всіх інших рішень (таких як використання прямих шляхів) хто-небудь, хто намагається перефактурувати погляди, не повинен мати на увазі що він також використовується в іншому контролері, що призводить до непередбачуваної поведінки
yoel halb

4
як щодо без перенаправлення?
Luckyy

спосіб кращого рішення, ніж переміщення перегляду на спільні папки
juFo

Це рішення вимагає дії на контролері, View (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
ignacio chiazzo

5
Ви не повертаєте перегляд, ви закликаєте дію.
0014 р.

Перш за все мені було корисно.
anil shrestha

5

Ви також можете зателефонувати до будь-якого контролера з JavaScript / jQuery . Скажімо, у вас є контролер, який повертає 404 або інший користувальницький контроль / сторінку. Потім, під час дії, з коду клієнта, ви можете зателефонувати на якусь адресу, яка запустить ваш контролер і поверне результат у форматі HTML , ваш клієнтський код може взяти цей повернутий результат і помістити його там, де ви хочете, на вашій сторінці ...


Я не знаю, що. Це звучить як щось таке, що я можу використати в майбутньому. Так, mvc скелі :)
dtc

1

За допомогою цього коду ви можете отримати будь-який контролер:

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

Переклад: За допомогою цього коду ви можете отримати будь-який контролер: [код], З повагою,
Роберт Колумбія

3
Хоча цей код може відповісти на питання, надаючи додатковий контекст щодо того, як та / або чому він вирішує проблему, покращить довгострокове значення відповіді.
Nic3500
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.