2014-01-24 3 views
3

Наша иерархия решение выглядит следующим образом:ASP.NET MVC пользовательский вид маршрутизации

Controller \ Категория \ Просмотр

Ex: Контроллеры \ DataAnalysis \ DataRetrieve

Теперь я хотел бы, чтобы на карте маршрутизации, так что, когда пользователь просто набирает имя представления в URL-адресе, он автоматически сопоставляет URL-адрес соответствующему контроллеру

IE: localhost: 1234 \ DataAnalysis \ DataRetrieve

Если сопоставить

Вид \ DataAnalysis \ DataRetrieve \ Index.cshtml

Аналогично, любые запросы URL, включая действия, должны получить соответствующий вид

IE: локальный: 1234 \ DataAnalysis \ DataRetrieve \ TestAction

Если сопоставить

Вид \ DataAnalysis \ DataRetrieve \ TestAction.cshtml

В настоящее время мы используем по умолчанию маршрутизации

public static void RegisterRoutes(RouteCollection routes) 
    { 
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

     routes.MapRoute(
      name: "Default", 
      url: "{controller}/{action}/{id}", 
      defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional } 
     ); 
    } 

Что означает, если я типа показано выше URL, он игнорирует категорию и не возвращает вид.

Есть ли способ настроить маршрутизацию, чтобы получить поведение выше?

--edit

Чтобы прояснить мой вопрос на основе комментариев, вот скриншот моего решения исследователь

enter image description here

Теперь, если я позвоню LOCALHOST: 12346/DataAnalysis/DataRetrieve, это должно отведите меня к индексу. Маршрутизация это не проблема, так как я могу сделать что-то вроде этого:

 routes.MapRoute(
      name: "ExampleRouting", 
      url: "{category}/{controller}/{action}" 
     ); 

Но вот проблема. Я хотел бы также организовать свою файловую структуру, как это:

enter image description here

По умолчанию, когда я пытаюсь получить индекс dataretrieve, он выглядит в соображениях \ DataRetrieve \ Индекс не Views \ DataAnalysis \ DataRetrieve \ Индекс.

Как я могу изменить это поведение?

Edit2 ------------------------

На основании ответа, я добавил пользовательский вид двигателя, зарегистрировал его в Application_Start, обновила мою маршрутизацию. Все еще имеет идентичную проблему.

Глобальный.asax

public class MvcApplication : System.Web.HttpApplication 
{ 
    protected void Application_Start() 
    { 
     AreaRegistration.RegisterAllAreas(); 

     WebApiConfig.Register(GlobalConfiguration.Configuration); 
     FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
     RouteConfig.RegisterRoutes(RouteTable.Routes); 
     ViewEngines.Engines.Add(new SPCViewEngine()); 

     BundleConfig.RegisterBundles(BundleTable.Bundles); 
     AuthConfig.RegisterAuth(); 
    } 
} 

RouteConfig.cs

public static void RegisterRoutes(RouteCollection routes) 
    { 
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 


     routes.MapRoute(
      name: "Default", 
      url: "{controller}/{category}/{action}/{id}", 
      defaults: new { controller = "Login", action = "Index", category = "Login", id = UrlParameter.Optional } 
     ); 
    } 

SPCViewEngine (пользовательский вид двигателя)

public class SPCViewEngine : RazorViewEngine 
{ 
    public SPCViewEngine() 
     : base() 
    { 
     ViewLocationFormats = new[] { 
      "~/Views/{1}/%1/{0}.cshtml", 
      "~/Views/{1}/%1/{0}.vbhtml", 
      "~/Views/Shared/{0}.cshtml", 
      "~/Views/Shared/{0}.vbhtml" 
     }; 

     PartialViewLocationFormats = new[] { 
      "~/Views/%1/{1}/{0}.cshtml", 
      "~/Views/%1/{1}/{0}.vbhtml", 
      "~/Views/Shared/{0}.cshtml", 
      "~/Views/Shared/{0}.vbhtml" 
     }; 
    } 

    protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath) 
    { 
     var categoryName = controllerContext.RouteData.Values["category"].ToString(); 
     return base.CreatePartialView(controllerContext, partialPath.Replace("%1", categoryName)); 
    } 

    protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath) 
    { 
     var categoryName = controllerContext.RouteData.Values["category"].ToString(); 
     return base.CreateView(controllerContext, viewPath.Replace("%1", categoryName), masterPath); 
    } 

    protected override bool FileExists(ControllerContext controllerContext, string virtualPath) 
    { 
     var categoryName = controllerContext.RouteData.Values["category"].ToString(); 
     return base.FileExists(controllerContext, virtualPath.Replace("%1", categoryName)); 
    } 
} 
+0

Так DataAnalysis ваш контроллер, или в том, что название вашего проекта, и DataRetrieve это ваш контроллер? – krillgar

+0

Я смущен, или, может быть, ты. Маршрутизация не имеет ничего общего с представлениями. Маршрутизация маршрутов только для действий контроллера. –

+1

Я бы предложил организовать ваше приложение, используя области. См. Http://msdn.microsoft.com/en-us/library/ee671793(v=vs.100).aspx для этого. – Onots

ответ

12

Если я правильно понял ваш вопрос, вы можете создать свой собственный вид двигателя разрешающего вид расположения на время выполнения и подключение к вашему приложению.

Создайте свой собственный механизм просмотра.

public class MyViewEngine : RazorViewEngine 
{ 
    public MyViewEngine() 
     : base() 
    { 
     ViewLocationFormats = new[] { 
     "~/Views/{1}/%1/{0}.cshtml", 
     "~/Views/{1}/%1/{0}.vbhtml", 
     "~/Views/Shared/{0}.cshtml", 
     "~/Views/Shared/{0}.vbhtml" 
    }; 

    PartialViewLocationFormats = new[] { 
     "~/Views/%1/{1}/{0}.cshtml", 
     "~/Views/%1/{1}/{0}.vbhtml", 
     "~/Views/Shared/{0}.cshtml", 
     "~/Views/Shared/{0}.vbhtml" 
    }; 
    } 

    protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath) 
    { 
     var catagoryName = controllerContext.RouteData.Values["category"].ToString(); 
     return base.CreatePartialView(controllerContext, partialPath.Replace("%1", catagoryName)); 
    } 

    protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath) 
    { 
     var catagoryName = controllerContext.RouteData.Values["category"].ToString(); 
     return base.CreateView(controllerContext, viewPath.Replace("%1", catagoryName),masterPath); 
    } 

    protected override bool FileExists(ControllerContext controllerContext, string virtualPath) 
    { 
     var catagoryName = controllerContext.RouteData.Values["category"].ToString(); 
     return base.FileExists(controllerContext, virtualPath.Replace("%1", catagoryName)); 
    } 

} 

и зарегистрировать его здесь

protected void Application_Start() 
{ 
    AreaRegistration.RegisterAllAreas(); 

    RegisterGlobalFilters(GlobalFilters.Filters); 
    RegisterRoutes(RouteTable.Routes); 


    //Register your View Engine Here. 
    ViewEngines.Engines.Add(new MyViewEngine()); 
} 

Обновить маршрут конфигурации, по умолчанию должен быть

 routes.MapRoute(
      name: "Default", 
      url: "{controller}/{category}/{action}/{id}", 
      defaults: new { controller = "Home", action = "Index", category = "DefaultCategoryName", id = UrlParameter.Optional } 
     ); 
+0

Ваш ответ кажется правильным способом сделать это, но по какой-то причине он все еще не работает. Запрос localhost/DataAnalysis/DataRetrieve приводит к 404, и ни один из методов переопределения в настраиваемом режиме просмотра не запускается, когда я накладываю на них точки отладки. Однако, когда я пытаюсь localhost: 12346/DataRetrieve/TestAction без категории впереди, он работает. Изменить: Ничего, последняя часть тоже не работает. – l46kok

+0

Вы зарегистрировали механизм просмотра в начале приложения и обновили конфигурацию маршрута? Я попробовал это в своем локальном хосте, это работает для меня, и точка отладки должна ударяться по каждому запросу. – ssilas777

+0

Да. Я временно отредактирую свой вопрос с обновленным контентом. – l46kok

Смежные вопросы