视图页面的命名约定和视图的设置控制器操作

时间:2013-05-24 15:05:36

标签: asp.net-mvc-4

我不确定如何命名我的View页面,它们都是CamelCase.cshtml,在浏览器中查看时看起来像“http://www.website.com/Home/CamelCase”。

当我在.NET之外构建时,我的页面被命名为“this-is-not-camel-case.html”。我将如何在我的MVC4项目中执行此操作?

如果我确实使用了这个,那么我如何告诉视图查看相关的控制器? 查看/主页/骆驼case.cshtml

虚假编辑:对不起,如果之前有人询问,我无法通过搜索或Google找到任何内容。感谢。

1 个答案:

答案 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;
        }
    }
}