我不确定如何命名我的View页面,它们都是CamelCase.cshtml,在浏览器中查看时看起来像“http://www.website.com/Home/CamelCase”。
当我在.NET之外构建时,我的页面被命名为“this-is-not-camel-case.html”。我将如何在我的MVC4项目中执行此操作?
如果我确实使用了这个,那么我如何告诉视图查看相关的控制器? 查看/主页/骆驼case.cshtml
虚假编辑:对不起,如果之前有人询问,我无法通过搜索或Google找到任何内容。感谢。
答案 0 :(得分:2)
有几种方法可以做到这一点:
这非常简单,您只需将ActionName
属性添加到所有操作中,并按照您希望网址的样式指定它们,然后将CamelCase.cshtml文件重命名为camel-case。 cshtml文件。
与上面相同,nuget上有一个插件,用于启用属性路由,允许您将每个操作的完整URL指定为操作的属性。它具有约定属性来帮助您使用控制器名称等。我通常更喜欢这种方法,因为我喜欢在我的应用程序中非常明确地使用路径。
可能通过扩展MVC框架来做一些基于约定的事情,但这将是一个相当大的工作量。为了在控制器上选择正确的操作,您需要在将框架使用它来定位控制器上的操作之前,将操作名称映射到MVC到其CamelCase等效项。最简单的方法是在Route中,这是MVC框架接管请求之前发生的最后一件事。您还需要在出路时转换另一种方式,以便生成的网址看起来像您想要的那样。
由于你真的不想改变现有方法来注册路由,所以最好在应用程序init中编写一个函数,它在注册后循环遍历所有路由并用新功能包装它们。
以下是应用程序启动的示例路由和修改,以实现您要执行的操作。不过我还是会选择路线属性方法。
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
WrapRoutesWithNamingConvention(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();
}
private void WrapRoutesWithNamingConvention(RouteCollection routes)
{
var wrappedRoutes = routes.Select(m => new ConventionRoute(m)).ToList();
routes.Clear();
wrappedRoutes.ForEach(routes.Add);
}
private class ConventionRoute : Route
{
private readonly RouteBase baseRoute;
public ConventionRoute(RouteBase baseRoute)
: base(null, null)
{
this.baseRoute = baseRoute;
}
public override RouteData GetRouteData(HttpContextBase httpContext)
{
var baseRouteData = baseRoute.GetRouteData(httpContext);
if (baseRouteData == null) return null;
var actionName = baseRouteData.Values["action"] as string;
var convertedActionName = ConvertHyphensToPascalCase(actionName);
baseRouteData.Values["action"] = convertedActionName;
return baseRouteData;
}
private string ConvertHyphensToPascalCase(string hyphens)
{
var capitalParts = hyphens.Split('-').Select(m => m.Substring(0, 1).ToUpper() + m.Substring(1));
var pascalCase = String.Join("", capitalParts);
return pascalCase;
}
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
var valuesClone = new RouteValueDictionary(values);
var pascalAction = valuesClone["action"] as string;
var hyphens = ConvertPascalCaseToHyphens(pascalAction);
valuesClone["action"] = hyphens;
var baseRouteVirtualPath = baseRoute.GetVirtualPath(requestContext, valuesClone);
return baseRouteVirtualPath;
}
private string ConvertPascalCaseToHyphens(string pascal)
{
var pascalParts = new List<string>();
var currentPart = new StringBuilder();
foreach (var character in pascal)
{
if (char.IsUpper(character) && currentPart.Length > 0)
{
pascalParts.Add(currentPart.ToString());
currentPart.Clear();
}
currentPart.Append(character);
}
if (currentPart.Length > 0)
{
pascalParts.Add(currentPart.ToString());
}
var lowers = pascalParts.Select(m => m.ToLower());
var hyphens = String.Join("-", lowers);
return hyphens;
}
}
}