Ответ 1
Добавьте поле NameSpace в файл Global.asax для маршрута по умолчанию.
var route = routes.MapRoute(
"Default", // Route name
"{controller}/{action}", // URL with parameters
new { controller = "Home", action = "Index" }, // Parameter defaults,
new[] { "YourNameSpace.Controllers" }
);
Добавить имя в пространстве AreaRegistration
в Area
public class MyArea : AreaRegistration
{
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"test",
"Test/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
new[] { "MyProjectNameSpace.Controllers" }
);
}
}
Объяснение
У меня есть следующая область в моем приложении. Поэтому приведенный ниже выделенный раздел касается Controller. ок.
Рисунок -1
Я набрал Url: http://localhost:2474/ActionFilterAttribute/index
Перед тем, как перейти к пункту назначения. Я покажу вам, как я инициализировал свой тест. Я добавил ссылку RoureDebugger. Вы можете получить Dll из этого места. Затем я добавил строку кода в файл Global.asax в Application_Start
Handler.
RouteDebug.RouteDebugger.RewriteRoutesForTesting(RouteTable.Routes);
Итак, наконец, используя вышеупомянутый Url, я начал отлаживать приложение. Наконец я увидел нижеследующую картинку.
в
Рисунок -2
Вопрос
действие все равно вызывается, хотя вид не найден, поэтому я получаю сообщение об ошибке.
Ответ
Итак, если вы обратите внимание на выделенное выше Route
, ну, это Default Route
. Этот шаблон сопоставляется с Url, как указано выше. Но View не будет найден в этом случае и что причина, по которой вызывается Controller Action Method
.
Прежде чем перейти к следующей части, почему я получил 404. Я покажу вам несколько тестов, которые я сделал в своем примере приложения.
Я создал класс, который получается из ActionFilterAttribute
, как показано ниже. Это содержит только один Override
, который называется OnResultExecuting
. Этот обработчик выполняет перед выполнением View
, соответствующей конкретному Action
Цель создания этого класса - просто проверить, что происходит с RouteData
и DataTokens
.
public class MyActionFilter : ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
var viewResult = filterContext.Result as ViewResult;
if (viewResult != null)
{
var razorEngine = viewResult
.ViewEngineCollection
.OfType<RazorViewEngine>()
.Single();
var viewName = !String.IsNullOrEmpty(viewResult.ViewName) ?
viewResult.ViewName :
filterContext.RouteData.Values["action"].ToString();
var razorview = razorengine
.FindView
(
filtercontext.Controller.ControllerContext,
viewname,
viewResult.MasterName,
false
).View as RazorView;
}
base.OnResultExecuting(filterContext);
}
}
Ok. Вернемся к первоначальному вопросу. Почему я получил 404?
Ваш Controller
будет выбран базовым маршрутом по умолчанию {controller}/{action}
, прежде чем он проверит Area Route
и поэтому будет искать View
в Root/Views
, а не в Area/views
.
Чтобы проверить это, я установил отладчик в Action Method of Controller внутри Area и обнаружил, что нет DataToken
Information, если запрошенный url не имеет Area Name
. более подробно о DataToken
в Debug
режиме
Рисунок -3
Если вы обратите внимание на ControllerContext
, я перечислил DataTokens
, который не отображает ключ/значение. Это потому, что не обнаружено никакого представления относительно этого контроллера в Root Directory
Как вы можете сказать, что расположенный в данный момент каталог - это Root Directory? Доказательство ниже
Рисунок -4
Не существует ни пространства имен, ни какого-либо Района, указанного в значениях RouteData
. не так ли?
Теперь перейдем к RouteData
, который соответствует шаблону, содержащему Area Name
. Итак, на этот раз мой Url: http://localhost:2474/mypractise/ActionFilterAttribute/index
, а ниже RouteData
соответствует URLRoutingModule
Рисунок -5
Обратите внимание на выделенный раздел, на этот раз сопоставленный маршрут принадлежит шаблону AreaName
, а совпадающее значение false для маршрута по умолчанию, которое принадлежит некоторому RouteData
в Root Directory. Правильно?
Мои последние данные для DataTokens
в случае вышеупомянутого запрошенного Url. На этот раз вы можете увидеть детали пространства имен и информацию о регионе.
Рисунок -6
в
Заключение:
Когда Controller
находится внутри Района, а ваш DataTokens
не отображает информацию для Area
, NameSpace
и UseNameSpaceFallback
информации. Это означает, что вы получите 404. Как упоминалось на рисунке 4, ваш запрошенный URL был правильным, поэтому вы получили DataTokens
и как указано на рисунке 3, DataTokens не были показаны, потому что запрошенный Url не содержит Area Name
и несмотря на то, что вы получили RouteData
, как указано на рисунке 2, потому что это шаблон Url по умолчанию. Наконец, попробуйте выполнить третью строку кода в OnResultExecuting
. Он покажет null, потому что View не найден.
Надеюсь, что это объяснение поможет вам.