【发布时间】:2014-02-14 20:41:03
【问题描述】:
我们的解决方案层次结构如下:
控制器\类别\视图
例如: 控制器\数据分析\数据检索
现在我想映射路由,这样当用户在 url 中键入视图的名称时,它会自动将 url 映射到相应的控制器
IE: localhost:1234\DataAnalysis\DataRetrieve
应该映射到
查看\DataAnalysis\DataRetrieve\Index.cshtml
同样地,任何包含操作的 url 请求都应该检索相应的视图
IE: localhost: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,它会忽略类别并且无法返回视图。
有没有办法自定义路由以获得上述行为?
--编辑
为了根据 cmets 澄清我的问题,这是我的解决方案资源管理器的屏幕截图
现在,如果我调用 localhost:12346/DataAnalysis/DataRetrieve,这应该会将我带到索引。路由这不是问题,因为我可以这样做:
routes.MapRoute(
name: "ExampleRouting",
url: "{category}/{controller}/{action}"
);
但这就是问题所在。我还想像这样组织我的文件结构:
默认情况下,当我尝试检索 dataretrieve 的索引时,它会查看 Views\DataRetrieve\Index 而不是 Views\DataAnalysis\DataRetrieve\Index。
如何改变这种行为?
编辑2------------
根据答案,我添加了一个自定义视图引擎,在 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));
}
}
【问题讨论】:
-
那么 DataAnalysis 是你的 Controller,还是你项目的名字,DataRetrieve 是你的 Controller?
-
我很困惑,或者你可能是。路由与视图无关。仅路由到控制器操作的路由。
-
我建议使用区域来组织您的应用程序。请参阅msdn.microsoft.com/en-us/library/ee671793(v=vs.100).aspx。
-
@Onots 几乎所有页面都将使用相同的共享布局文件,坦率地说,我们认为在区域下重新配置它们的共享布局设置(包括所有子渲染操作属性)会非常忙碌,除非我们是错误的,有一个简单的方法可以解决这个问题。
-
@l46kok 我希望您可以使用 Area _viewStart 来引用相同的(共享)根布局设置。不过,还不必亲自处理这个问题。这就是我评论而不是回答的原因:D
标签: c# .net asp.net-mvc-4 url razor