Asp.net mvc 控制器和视图中的子文件夹
我想在asp.net mvc中为同一对象/模型提供多个控制器和视图,但结果比我预期的要复杂一些 基本上我想做的是这样的: site.com/product -> will show product details to visitors. site.com/admin/product -> will show some extra information together with product details. and some commands like delete, edit etc. site.com/product ->将向参观者展示产品细节。 site.com/admin/product ->将显示一些附加信息以及产品详细信息。 还有一些命令,如删除、编辑等。 目标是分离访问者和管理员的URL 我的第一种方法是在控制器和视图文件夹中创建一个子文件夹,因此事情看起来是这样的: > Controllers > Admin ProductController.cs ProductController.cs > Views > Admin > Product Index.aspx > Product Index.aspx >控制器 >管理员 ProductController.cs ProductController.cs >观点 >管理员 >产品 Index.aspx >产品 Index.aspx 我可以毫无问题地将URL映射到正确的控制器(前提是我指定了它们的名称空间,因为类名是相同的)。 但是,当我从管理员文件夹下的控制器返回视图时,它不会在Views/admin/Product文件夹下显示索引视图,而是在Views/Product文件夹下显示索引视图 我知道我可以说Asp.net mvc 控制器和视图中的子文件夹,asp.net-mvc,model-view-controller,Asp.net Mvc,Model View Controller,我想在asp.net mvc中为同一对象/模型提供多个控制器和视图,但结果比我预期的要复杂一些 基本上我想做的是这样的: site.com/product -> will show product details to visitors. site.com/admin/product -> will show some extra information together with product details. and some commands lik
返回视图(“此处的完整路径”)
来返回我想要的视图。但这显然不是一个好的解决方案,我不想这样做
我的问题是,在URL必须如此的情况下,处理这种情况的最佳方式是什么
- 创建一个自定义控制器类,该类重写view方法(或为此目的需要重写的任何其他方法),并确保返回正确的视图
- 这是一个丑陋的黑客,但会工作
- 创建一个同时考虑文件夹的自定义视图引擎
- 我不知道该怎么做,但据我所知,这也应该能解决问题
- 使用
- 这一个实际上使用了不同的文件夹布局,但在理论上这也应该起作用。但是我仍然不确定这是否是最好的方法,因为在站点的不同部分下有不同的Controller&View文件夹并不是我想要的。
有什么建议吗?为您的MVC项目尝试Phil Haack的/Areas/: 对于普通内容,您将有一个普通的根目录,对于所有管理内容,您将有一个特殊的/Areas/Admin/部分(url将是/Admin/)
(来源:)ASP.Net MVC默认使用平面视图文件夹结构。区域可以在一定程度上帮助你,尽管它们只会给你多一个等级 这会使控制器的深度嵌套层次结构的视图难以管理。这里真正需要的是视图文件夹层次结构与控制器的命名空间层次结构相匹配 好消息是,您可以编写一个定制的ViewEngine来完成这项工作,所需的工作量非常小——有关详细信息,请参阅my 我已经包含了ControllerPathRazorViewEngine类的一个片段来概述它是如何工作的。通过截取FindView/FindPartialView方法并将控制器名称替换为文件夹路径(基于控制器名称空间和名称),我们可以让它从主视图文件夹中的嵌套文件夹加载视图
public class ControllerPathRazorViewEngine : RazorViewEngine
{
//... constructors etc.
public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
return FindUsingControllerPath(controllerContext, () => base.FindView(controllerContext, viewName, masterName, useCache));
}
public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
{
return FindUsingControllerPath(controllerContext, () => base.FindPartialView(controllerContext, partialViewName, useCache));
}
private ViewEngineResult FindUsingControllerPath(ControllerContext controllerContext, Func<ViewEngineResult> func)
{
string controllerName = controllerContext.RouteData.GetRequiredString("controller");
string controllerPath = controllerPathResolver.GetPath(controllerContext.Controller.GetType());
controllerContext.RouteData.Values["controller"] = controllerPath;
var result = func();
controllerContext.RouteData.Values["controller"] = controllerName;
return result;
}
}
公共类控制器PathRazorViewEngine:RazorViewEngine
{
//…施工人员等。
public override ViewEngineResult FindView(ControllerContext ControllerContext、string viewName、string masterName、bool useCache)
{
返回FindSingControllerPath(controllerContext,()=>base.FindView(controllerContext,viewName,masterName,useCache));
}
公共覆盖视图引擎结果FindPartialView(ControllerContext ControllerContext、字符串partialViewName、布尔useCache)
{
返回FindSingControllerPath(controllerContext,()=>base.FindPartialView(controllerContext,partialViewName,useCache));
}
私有视图引擎结果FindUsingControllerPath(ControllerContext ControllerContext,Func Func)
{
string controllerName=controllerContext.RoutedData.GetRequiredString(“控制器”);
字符串controllerPath=controllerPathResolver.GetPath(controllerContext.Controller.GetType());
controllerContext.RoutedData.Values[“controller”]=controllerPath;
var result=func();
controllerContext.RoutedData.Values[“controller”]=controllerName;
返回结果;
}
}