如何在 MVC 中设置默认路由(到某个区域)
Posted
技术标签:
【中文标题】如何在 MVC 中设置默认路由(到某个区域)【英文标题】:How to set a Default Route (To an Area) in MVC 【发布时间】:2011-01-09 13:24:29 【问题描述】:好的,之前有人问过这个问题,但是没有可靠的解决方案。所以为了我自己和其他可能觉得这很有用的人。
在 MVC2 (ASP.NET) 中,我想要它,因此当有人导航到该网站时,会指定一个默认区域。因此,导航到我的网站应该会将您发送到 AreaZ 中的 ControllerX ActionY。
在 Global.asax 中使用以下路由
routes.MapRoute(
"Area",
"",
new area = "AreaZ", controller = "ControllerX ", action = "ActionY "
);
现在这可以正常工作,因为它会尝试提供正确的页面。但是 MVC 继续在站点的根目录中而不是在区域文件夹中查找视图。
有没有办法解决这个问题?
编辑
有一个“解决方案”,在 ControllerX 中,ActionY 返回视图的完整路径。有点破解,但它确实有效。不过我希望有更好的解决方案。
public ActionResult ActionY()
return View("~/Areas/AreaZ/views/ActionY.aspx");
编辑:
当有页面的 html ActionLink 时,这也会成为一个问题。如果未设置区域,则操作链接输出为空白。
所有这些都是设计的还是缺陷?
【问题讨论】:
【参考方案1】:这个我很感兴趣,我终于有机会研究它了。其他人显然不明白这是 finding view 的问题,而不是 routing 本身的问题 - 这可能是因为您的问题标题表明它是关于路由。
在任何情况下,由于这是一个与视图相关的问题,因此获得所需内容的唯一方法是覆盖默认视图引擎。通常,当您这样做时,只是为了切换视图引擎(即切换到 Spark、NHaml 等)。在这种情况下,我们需要重写的不是视图创建逻辑,而是VirtualPathProviderViewEngine
类中的FindPartialView
和FindView
方法。
感谢你的幸运星,这些方法实际上是虚拟的,因为 VirtualPathProviderViewEngine
中的其他所有内容甚至都可访问 - 它是私有的,这使得它非常 em> 重写查找逻辑很烦人,因为如果您希望它与位置缓存和位置格式很好地配合,您基本上必须重写一半已经编写的代码。在对 Reflector 进行了一些挖掘之后,我终于想出了一个可行的解决方案。
我在这里所做的是首先创建一个抽象的AreaAwareViewEngine
,它直接派生自VirtualPathProviderViewEngine
,而不是WebFormViewEngine
。我这样做是为了如果你想创建 Spark 视图(或其他),你仍然可以使用这个类作为基类型。
下面的代码相当冗长,所以给你一个快速总结它的实际作用:它可以让你将2
放入位置格式,它对应于区域名称,同样的方式@987654329 @ 对应于控制器名称。而已!这就是我们必须编写所有这些代码的目的:
BaseAreaAwareViewEngine.cs
public abstract class BaseAreaAwareViewEngine : VirtualPathProviderViewEngine
private static readonly string[] EmptyLocations = ;
public override ViewEngineResult FindView(
ControllerContext controllerContext, string viewName,
string masterName, bool useCache)
if (controllerContext == null)
throw new ArgumentNullException("controllerContext");
if (string.IsNullOrEmpty(viewName))
throw new ArgumentNullException(viewName,
"Value cannot be null or empty.");
string area = getArea(controllerContext);
return FindAreaView(controllerContext, area, viewName,
masterName, useCache);
public override ViewEngineResult FindPartialView(
ControllerContext controllerContext, string partialViewName,
bool useCache)
if (controllerContext == null)
throw new ArgumentNullException("controllerContext");
if (string.IsNullOrEmpty(partialViewName))
throw new ArgumentNullException(partialViewName,
"Value cannot be null or empty.");
string area = getArea(controllerContext);
return FindAreaPartialView(controllerContext, area,
partialViewName, useCache);
protected virtual ViewEngineResult FindAreaView(
ControllerContext controllerContext, string areaName, string viewName,
string masterName, bool useCache)
string controllerName =
controllerContext.RouteData.GetRequiredString("controller");
string[] searchedViewPaths;
string viewPath = GetPath(controllerContext, ViewLocationFormats,
"ViewLocationFormats", viewName, controllerName, areaName, "View",
useCache, out searchedViewPaths);
string[] searchedMasterPaths;
string masterPath = GetPath(controllerContext, MasterLocationFormats,
"MasterLocationFormats", masterName, controllerName, areaName,
"Master", useCache, out searchedMasterPaths);
if (!string.IsNullOrEmpty(viewPath) &&
(!string.IsNullOrEmpty(masterPath) ||
string.IsNullOrEmpty(masterName)))
return new ViewEngineResult(CreateView(controllerContext, viewPath,
masterPath), this);
return new ViewEngineResult(
searchedViewPaths.Union<string>(searchedMasterPaths));
protected virtual ViewEngineResult FindAreaPartialView(
ControllerContext controllerContext, string areaName,
string viewName, bool useCache)
string controllerName =
controllerContext.RouteData.GetRequiredString("controller");
string[] searchedViewPaths;
string partialViewPath = GetPath(controllerContext,
ViewLocationFormats, "PartialViewLocationFormats", viewName,
controllerName, areaName, "Partial", useCache,
out searchedViewPaths);
if (!string.IsNullOrEmpty(partialViewPath))
return new ViewEngineResult(CreatePartialView(controllerContext,
partialViewPath), this);
return new ViewEngineResult(searchedViewPaths);
protected string CreateCacheKey(string prefix, string name,
string controller, string area)
return string.Format(CultureInfo.InvariantCulture,
":ViewCacheEntry:0:1:2:3:4:",
base.GetType().AssemblyQualifiedName,
prefix, name, controller, area);
protected string GetPath(ControllerContext controllerContext,
string[] locations, string locationsPropertyName, string name,
string controllerName, string areaName, string cacheKeyPrefix,
bool useCache, out string[] searchedLocations)
searchedLocations = EmptyLocations;
if (string.IsNullOrEmpty(name))
return string.Empty;
if ((locations == null) || (locations.Length == 0))
throw new InvalidOperationException(string.Format("The property " +
"'0' cannot be null or empty.", locationsPropertyName));
bool isSpecificPath = IsSpecificPath(name);
string key = CreateCacheKey(cacheKeyPrefix, name,
isSpecificPath ? string.Empty : controllerName,
isSpecificPath ? string.Empty : areaName);
if (useCache)
string viewLocation = ViewLocationCache.GetViewLocation(
controllerContext.HttpContext, key);
if (viewLocation != null)
return viewLocation;
if (!isSpecificPath)
return GetPathFromGeneralName(controllerContext, locations, name,
controllerName, areaName, key, ref searchedLocations);
return GetPathFromSpecificName(controllerContext, name, key,
ref searchedLocations);
protected string GetPathFromGeneralName(ControllerContext controllerContext,
string[] locations, string name, string controllerName,
string areaName, string cacheKey, ref string[] searchedLocations)
string virtualPath = string.Empty;
searchedLocations = new string[locations.Length];
for (int i = 0; i < locations.Length; i++)
if (string.IsNullOrEmpty(areaName) && locations[i].Contains("2"))
continue;
string testPath = string.Format(CultureInfo.InvariantCulture,
locations[i], name, controllerName, areaName);
if (FileExists(controllerContext, testPath))
searchedLocations = EmptyLocations;
virtualPath = testPath;
ViewLocationCache.InsertViewLocation(
controllerContext.HttpContext, cacheKey, virtualPath);
return virtualPath;
searchedLocations[i] = testPath;
return virtualPath;
protected string GetPathFromSpecificName(
ControllerContext controllerContext, string name, string cacheKey,
ref string[] searchedLocations)
string virtualPath = name;
if (!FileExists(controllerContext, name))
virtualPath = string.Empty;
searchedLocations = new string[] name ;
ViewLocationCache.InsertViewLocation(controllerContext.HttpContext,
cacheKey, virtualPath);
return virtualPath;
protected string getArea(ControllerContext controllerContext)
// First try to get area from a RouteValue override, like one specified in the Defaults arg to a Route.
object areaO;
controllerContext.RouteData.Values.TryGetValue("area", out areaO);
// If not specified, try to get it from the Controller's namespace
if (areaO != null)
return (string)areaO;
string namespa = controllerContext.Controller.GetType().Namespace;
int areaStart = namespa.IndexOf("Areas.");
if (areaStart == -1)
return null;
areaStart += 6;
int areaEnd = namespa.IndexOf('.', areaStart + 1);
string area = namespa.Substring(areaStart, areaEnd - areaStart);
return area;
protected static bool IsSpecificPath(string name)
char ch = name[0];
if (ch != '~')
return (ch == '/');
return true;
现在如上所述,这不是一个具体的引擎,因此您也必须创建它。幸运的是,这部分要容易得多,我们需要做的就是设置默认格式并实际创建视图:
AreaAwareViewEngine.cs
public class AreaAwareViewEngine : BaseAreaAwareViewEngine
public AreaAwareViewEngine()
MasterLocationFormats = new string[]
"~/Areas/2/Views/1/0.master",
"~/Areas/2/Views/1/0.cshtml",
"~/Areas/2/Views/Shared/0.master",
"~/Areas/2/Views/Shared/0.cshtml",
"~/Views/1/0.master",
"~/Views/1/0.cshtml",
"~/Views/Shared/0.master"
"~/Views/Shared/0.cshtml"
;
ViewLocationFormats = new string[]
"~/Areas/2/Views/1/0.aspx",
"~/Areas/2/Views/1/0.ascx",
"~/Areas/2/Views/1/0.cshtml",
"~/Areas/2/Views/Shared/0.aspx",
"~/Areas/2/Views/Shared/0.ascx",
"~/Areas/2/Views/Shared/0.cshtml",
"~/Views/1/0.aspx",
"~/Views/1/0.ascx",
"~/Views/1/0.cshtml",
"~/Views/Shared/0.aspx"
"~/Views/Shared/0.ascx"
"~/Views/Shared/0.cshtml"
;
PartialViewLocationFormats = ViewLocationFormats;
protected override IView CreatePartialView(
ControllerContext controllerContext, string partialPath)
if (partialPath.EndsWith(".cshtml"))
return new System.Web.Mvc.RazorView(controllerContext, partialPath, null, false, null);
else
return new WebFormView(controllerContext, partialPath);
protected override IView CreateView(ControllerContext controllerContext,
string viewPath, string masterPath)
if (viewPath.EndsWith(".cshtml"))
return new RazorView(controllerContext, viewPath, masterPath, false, null);
else
return new WebFormView(controllerContext, viewPath, masterPath);
请注意,我们在标准 ViewLocationFormats
中添加了一些条目。这些是新的2
条目,其中2
将映射到我们放入RouteData
的area
。我已经单独留下了MasterLocationFormats
,但显然你可以根据需要更改它。
现在修改您的global.asax
以注册此视图引擎:
Global.asax.cs
protected void Application_Start()
RegisterRoutes(RouteTable.Routes);
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new AreaAwareViewEngine());
...并注册默认路由:
public static void RegisterRoutes(RouteCollection routes)
routes.IgnoreRoute("resource.axd/*pathInfo");
routes.MapRoute(
"Area",
"",
new area = "AreaZ", controller = "Default", action = "ActionY"
);
routes.MapRoute(
"Default",
"controller/action/id",
new controller = "Home", action = "Index", id = ""
);
现在创建我们刚刚引用的AreaController
:
DefaultController.cs(在 ~/Controllers/ 中)
public class DefaultController : Controller
public ActionResult ActionY()
return View("TestView");
显然我们需要目录结构和视图来配合它——我们将保持这个超级简单:
TestView.aspx(在 ~/Areas/AreaZ/Views/Default/ 或 ~/Areas/AreaZ/Views/Shared/ 中)
<%@ Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
<h2>TestView</h2>
This is a test view in AreaZ.
就是这样。 终于,我们完成了。
在大多数情况下,您应该能够将 BaseAreaAwareViewEngine
和 AreaAwareViewEngine
放入任何 MVC 项目中,因此即使完成此操作需要大量代码,您只需编写一次。之后,只需在global.asax.cs
中编辑几行并创建您的站点结构即可。
【讨论】:
这很可能是当前最好的解决方案,但远非理想。如上所述,一旦添加 Actionlink 或存在相同的问题。 @Pino:我认为您应该能够通过将相同的area = "AreaZ"
添加到global.asax.cs
中的“默认”路由映射来解决ActionLink
问题。不过我并不积极;试试看。
在 MVC4 中“默认”路由声明从 Global.asax 移动到 ~/App_Start/RouteConfig.cs/RegisterRoutes()
我讨厌投反对票,但我真的不敢相信@Chris Alderson 的以下回答没有获得更多选票。这是一个比这个更简单的解决方案,并且似乎解决了边缘情况(ActionLinks 等)。
这里似乎有一个错误。例如,名为“Re”的区域的视图将位于 ~/Areas/Re/Views/Ctrlr/blah.aspx,但此处的代码使用 ~/2/1/0,即 ~ /Re/Ctrl/blah.aspx,路径中缺少关键区域目录。它应该是“~/Areas/2/Views/1/0.aspx”【参考方案2】:
我就是这样做的。我不知道为什么 MapRoute() 不允许您设置区域,但它确实返回了路线对象,因此您可以继续进行任何您想要的其他更改。我使用它是因为我有一个模块化 MVC 站点,该站点出售给企业客户,他们需要能够将 dll 放入 bin 文件夹以添加新模块。我允许他们在 AppSettings 配置中更改“HomeArea”。
var route = routes.MapRoute(
"Home_Default",
"",
new controller = "Home", action = "index" ,
new[] "IPC.Web.Core.Controllers"
);
route.DataTokens["area"] = area;
编辑:您也可以在 AreaRegistration.RegisterArea 中尝试让用户默认进入的区域。我还没有测试过,但是 AreaRegistrationContext.MapRoute 确实为你设置了route.DataTokens["area"] = this.AreaName;
。
context.MapRoute(
"Home_Default",
"",
new controller = "Home", action = "index" ,
new[] "IPC.Web.Core.Controllers"
);
【讨论】:
它有效。注意新的 web.config 文件,它可能会覆盖旧的全局配置。【参考方案3】:即使它已经被回答 - 这是简短的语法(ASP.net 3、4、5):
routes.MapRoute("redirect all other requests", "*url",
new
controller = "UnderConstruction",
action = "Index"
).DataTokens = new RouteValueDictionary(new area = "Shop" );
【讨论】:
这对我很有用。我在根目录没有任何控制器,只使用区域。对于 MVC 4,我将其替换为 RouteConfig.cs 中的默认值。谢谢! 我正在使用 MVC4,这对我来说是最简单的解决方案。允许应用程序将特定区域内的索引视图用作站点的“主页”。 此解决方案在未来将不再适用(来自 Asp.Net MVC6 及更高版本)。 @PatrickDesjardins : 有什么理由不支持上述解决方案? @SeriousM 你的回答是常青树。它仍然有帮助。你救了我一个晚上。【参考方案4】:感谢 Aaron 指出这是关于定位视图,我误解了这一点。
[更新] 我刚刚创建了一个项目,默认情况下将用户发送到一个区域,而不会弄乱任何代码或查找路径:
在 global.asax 中,照常注册:
public static void RegisterRoutes(RouteCollection routes)
routes.IgnoreRoute("resource.axd/*pathInfo");
routes.MapRoute(
"Default", // Route name
"controller/action/id", // URL with parameters
new controller = "Home", action = "Index", id = "" // Parameter defaults,
);
在Application_Start()
中,请务必使用以下顺序;
protected void Application_Start()
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
在您所在地区注册,使用
public override void RegisterArea(AreaRegistrationContext context)
context.MapRoute(
"ShopArea_default",
"controller/action/id",
new action = "Index", id = "", controller = "MyRoute" ,
new controller = "MyRoute"
);
可以在以下位置找到一个示例 http://www.emphess.net/2010/01/31/areas-routes-and-defaults-in-mvc-2-rc/
我真的希望这是你所要求的......
////
我不认为在这种情况下写一个伪ViewEngine
是最好的解决方案。 (缺乏声誉,我无法评论)。 WebFormsViewEngine
是区域感知的,包含 AreaViewLocationFormats
,默认情况下定义为
AreaViewLocationFormats = new[]
"~/Areas/2/Views/1/0.aspx",
"~/Areas/2/Views/1/0.ascx",
"~/Areas/2/Views/Shared/0.aspx",
"~/Areas/2/Views/Shared/0.ascx",
;
我相信你不遵守这个约定。你发了
public ActionResult ActionY()
return View("~/Areas/AreaZ/views/ActionY.aspx");
作为一个有效的黑客,但这应该是
return View("~/Areas/AreaZ/views/ControllerX/ActionY.aspx");
如果您不想遵循约定,但是,您可能希望通过从 WebFormViewEngine
派生(例如,在 MvcContrib 中完成)采取一条短路径,您可以在其中设置查找路径构造函数,或者-有点hacky-通过在Application_Start
上指定这样的约定:
((VirtualPathProviderViewEngine)ViewEngines.Engines[0]).AreaViewLocationFormats = ...;
当然,这应该更加小心,但我认为它表明了这个想法。这些字段是 MVC 2 RC 中 VirtualPathProviderViewEngine
中的 public
。
【讨论】:
值得注意的是,这仅适用于 MVC 2 RC - MVC 1VirtualPathProviderViewEngine
没有此属性,也不是区域感知的。虽然这个问题确实是关于 MVC 2 的,但很多人仍然没有使用它(并且在一段时间内不会使用它)。因此,对于特定问题,您的答案更容易,但我的答案是唯一适用于偶然发现此问题的 MVC1 用户的答案。我喜欢提供不依赖于可能会发生变化的预发布功能的答案。
另外,它不是一个“伪视图引擎”——视图引擎类被故意设计成可扩展的,以便可以使用不同类型的视图。
这不是要侮辱你,对不起。它是“伪”的,因为它不会显着改变视图的处理方式,而只是替换了一些值。
我没有被冒犯,我只是想澄清一个事实,即派生自定义视图引擎并不是一个特别不寻常的原因,相关方法是可覆盖的事实证明了这一点。跨度>
关于RegisterAreas
在RegisterRoutes
之前的重要提示。想知道为什么我的代码突然停止工作并注意到重构;)【参考方案5】:
我猜您希望用户在访问过~/
URL 后被重定向到~/AreaZ
URL。
我将通过您的根目录HomeController
中的以下代码来实现。
public class HomeController
public ActionResult Index()
return RedirectToAction("ActionY", "ControllerX", new Area = "AreaZ" );
以及Global.asax
中的以下路线。
routes.MapRoute(
"Redirection to AreaZ",
String.Empty,
new controller = "Home ", action = "Index"
);
【讨论】:
这可行,但它会更改为用户浏览器上的 URL。真的不理想。【参考方案6】:首先,您使用的是哪个版本的 MVC2?从 preview2 到 RC 发生了重大变化。
假设您使用 RC,我认为您的路线映射应该看起来不同。在您所在地区的AreaRegistration.cs
,您可以注册某种默认路由,例如
context.MapRoute(
"ShopArea_default",
"controller/action/id",
new action = "Index", id = "", controller="MyRoute"
);
默认情况下,上面的代码会将用户发送到我们ShopArea
中的MyRouteController
。
使用空字符串作为第二个参数会引发异常,因为必须指定控制器。
当然,您必须更改 Global.asax
中的默认路由,这样它就不会干扰此默认路由,例如通过使用主站点的前缀。
另请参阅此线程和 Haack 的回答:MVC 2 AreaRegistration Routes Order
希望这会有所帮助。
【讨论】:
谢谢,但我不确定这是否能解决问题中解释的问题。以及它的 MVC RC【参考方案7】:将以下内容添加到我的 Application_Start 对我有用,但我不确定您在 RC 中是否有此设置:
var engine = (WebFormViewEngine)ViewEngines.Engines.First();
// These additions allow me to route default requests for "/" to the home area
engine.ViewLocationFormats = new string[]
"~/Views/1/0.aspx",
"~/Views/1/0.ascx",
"~/Areas/1/Views/1/0.aspx", // new
"~/Areas/1/Views/1/0.ascx", // new
"~/Areas/1/Views/0.aspx", // new
"~/Areas/1/Views/0.ascx", // new
"~/Views/1/0.ascx",
"~/Views/Shared/0.aspx",
"~/Views/Shared/0.ascx"
;
【讨论】:
【参考方案8】:我为使其正常工作所做的工作如下:
-
我在根/Controllers 文件夹中创建了一个默认控制器。我将控制器命名为 DefaultController。
在控制器中我添加了以下代码:
namespace MyNameSpace.Controllers
public class DefaultController : Controller
// GET: Default
public ActionResult Index()
return RedirectToAction("Index", "ControllerName", new area = "FolderName");
在我的 RouterConfig.cs 中,我添加了以下内容:
routes.MapRoute(
name: "Default",
url: "controller/action/id",
defaults: new controller = "Default", action = "Index", id = UrlParameter.Optional);
这一切背后的诀窍是我创建了一个默认构造函数,每次我的应用程序启动时它始终是启动控制器。当它点击该默认控制器时,它将重定向到我在默认索引操作中指定的任何控制器。在我的情况下是
www.myurl.com/FolderName/ControllerName
.
【讨论】:
【参考方案9】:routes.MapRoute(
"Area",
"area/",
new area = "AreaZ", controller = "ControlerX ", action = "ActionY "
);
你试过了吗?
【讨论】:
是的,问题在于现在该站点在根目录中查找视图。未找到视图“ActionY”或其主视图。搜索了以下位置:~/Views/ActionY/ActionY.aspx ~/Views/ActionY/ActionY.ascx ~/Views/Shared/ActionY.aspx ~/Views/Shared/ActionY.ascx 我明白了。我将尝试找到解决方案。为问题 +1【参考方案10】:定位不同的构建块是在请求生命周期中完成的。 ASP.NET MVC 请求生命周期中的第一步是将请求的 URL 映射到正确的控制器操作方法。这个过程称为路由。默认路由在 Global.asax 文件中初始化,并向 ASP.NET MVC 框架描述如何处理请求。双击MvcApplication1项目中的Global.asax文件会显示如下代码:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing;
namespace MvcApplication1
public class GlobalApplication : System.Web.HttpApplication
public static void RegisterRoutes(RouteCollection routes)
routes.IgnoreRoute("resource.axd/*pathInfo");
routes.MapRoute(
"Default", // Route name
"controller/action/id", // URL with parameters
new controller = "Home", action = "Index",
id = "" // Parameter defaults
);
protected void Application_Start()
RegisterRoutes(RouteTable.Routes);
在 Application_Start() 事件处理程序中,每当编译应用程序或重新启动 Web 服务器时都会触发该事件处理程序,它会注册一个路由表。默认路由名为 Default,并以 http://www.example.com/controller/action/id 的形式响应 URL。 和 之间的变量使用请求 URL 中的实际值填充,如果 URL 中没有覆盖,则使用默认值填充。此默认路由将根据默认路由参数映射到 Home 控制器和 Index 操作方法。我们不会对这个路由图进行任何其他操作。
默认情况下,所有可能的 URL 都可以通过此默认路由进行映射。也可以创建我们自己的路线。例如,让我们将 URL http://www.example.com/Employee/Maarten 映射到 Employee 控制器、Show 操作和 firstname 参数。下面的代码 sn -p 可以插入到我们刚刚打开的 Global.asax 文件中。因为ASP.NET MVC框架使用的是第一个匹配路由,所以这段代码sn -p应该插入到默认路由上面;否则该路由将永远不会被使用。
routes.MapRoute(
"EmployeeShow", // Route name
"Employee/firstname", // URL with parameters
new // Parameter defaults
controller = "Employee",
action = "Show",
firstname = ""
);
现在,让我们为这条路线添加必要的组件。首先,在 Controllers 文件夹中创建一个名为 EmployeeController 的类。您可以通过向项目中添加一个新项目并选择位于 Web | 下的 MVC 控制器类模板来完成此操作。 MVC 类别。删除 Index 操作方法,并将其替换为名为 Show 的方法或操作。此方法接受 firstname 参数并将数据传递到 ViewData 字典。视图将使用该字典来显示数据。
EmployeeController 类会将一个 Employee 对象传递给视图。这个 Employee 类应该被添加到 Models 文件夹中(右键单击这个文件夹,然后从上下文菜单中选择 Add | Class)。这是 Employee 类的代码:
namespace MvcApplication1.Models
public class Employee
public string FirstName get; set;
public string LastName get; set;
public string Email get; set;
【讨论】:
谢谢,不过我不太确定这与设置默认区域有何关系。 :-/【参考方案11】:好吧,虽然创建自定义视图引擎可以解决这个问题,但您仍然可以有其他选择:
决定您需要默认显示的内容。 那个东西有控制器和动作(和区域),对吧? 打开该区域注册并添加如下内容:public override void RegisterArea(AreaRegistrationContext context) //this makes it work for the empty url (just domain) to act as current Area. context.MapRoute( "Area_empty", "", new controller = "Home", action = "Index", id = UrlParameter.Optional , namespaces: new string[] "Area controller namespace" ); //other routes of the area
干杯!
【讨论】:
同意。虽然我认为这个路由定义更合适的地方是在 Global.asax 文件中。 在这种情况下,您的 global.asax 定义会知道区域控制器命名空间的存在,我认为这是不对的。区域是一项附加功能,这意味着您必须能够在不触及 global.asax 定义的情况下添加/删除一个。在我解决这个问题的方法中,我更喜欢一个区域来“接管”请求,而不是一个 [全球] 网站来“移交”请求。【参考方案12】:这个问题的公认解决方案是,虽然在总结如何创建自定义视图引擎方面是正确的,但没有正确回答这个问题。这里的问题是 Pino 错误地指定了他的默认路线。特别是他的“区域”定义是不正确的。 “区域”是通过 DataTokens 集合检查的,应该这样添加:
var defaultRoute = new Route("",new RouteValueDictionary()"controller","Default","action","Index",null/*constraints*/,new RouteValueDictionary()"area","Admin",new MvcRouteHandler());
defaultRoute.DataTokens.Add("Namespaces","MyProject.Web.Admin.Controller");
routes.Add(defaultRoute);
默认对象中指定的“区域”将被忽略。上面的代码创建了一个默认路由,它捕获对您站点根目录的请求,然后调用默认控制器,管理区域中的索引操作。另请注意将“命名空间”键添加到 DataTokens,仅当您有多个具有相同名称的控制器时才需要。此解决方案已通过 Mvc2 和 Mvc3 .NET 3.5/4.0 验证
【讨论】:
【参考方案13】:ummm,我不知道为什么要这么编程,我认为通过指定这个默认路由很容易解决原来的问题......
routes.MapRoute("Default", "*id",
new controller = "Home"
, action = "Index"
, id = UrlParameter.Optional
);
【讨论】:
以上是关于如何在 MVC 中设置默认路由(到某个区域)的主要内容,如果未能解决你的问题,请参考以下文章
在 React/Material ui 路由中设置默认活动选项卡
如何使用 asp.net mvc 中的标记在 Select2 输入中设置默认值