ASP.NET MVC URL路由,具有层次结构

时间:2016-10-29 12:14:32

标签: c# asp.net-mvc

我正在尝试在ASP.NET MVC中进行一些路由,我希望URL在某个区域基本上看起来像这样(AdminArea Section)

http://localhost/admin/folders/folder1/folder2

我想要上面的结构,但是我遇到了一些我无法解决的问题。

第一个问题是,有时URL最终会成为像

这样的查询字符串

?永久= FOLDERNAME

这不是我想要的。

这是我定义的路线。

            context.MapRoute
        (
                "folder_route",
                "Administration/folders/{*permalink}",
                defaults: new { controller = "folders", action = "Index",permalink = UrlParameter.Optional },
                constraints: new { permalink = new FolderURLConstraint() }

        );

约束:

    public class FolderURLConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        if (values[parameterName] != null)
        {
            var permalink = values[parameterName].ToString();
            return new FolderDAL().ValidateFolderURLSlug(permalink);
        }
        return false;
    }
}

验证:

        public bool ValidateFolderURLSlug(string folderName)
    {
        if (!string.IsNullOrEmpty(folderName))
        {

            string[] splitFolder = folderName.Split(new string[] { "/"}, StringSplitOptions.RemoveEmptyEntries);
            string lastValue = splitFolder[splitFolder.Length - 1];

            string[] folderNames = GetFolderBreadCrumb(lastValue.ToLower()).Select(p => p.FolderName.ToLower()).ToArray();;

            splitFolder = splitFolder.Select(s => s.ToLower()).ToArray();

            bool isEqual = Enumerable.SequenceEqual(splitFolder, folderNames);

            return isEqual;
        }

        return false;

    }

索引页面:     @ grid.GetHtml(tableStyle:“table table-bordered table-condensed table-striped”,

    columns:grid.Columns(

            grid.Column("FolderName", "Folder Name",
            format:(item) => Html.ActionLink((string)item.FolderName, "index", "folders", new {permalink=item.FolderName}, null)),
            grid.Column("DateCreated", "Date Created"),
            grid.Column(header:"Action", format:
            @<text>
            <a href="@Url.Action("delete", "Folders", new {id=item.PrimaryKey })"><span class="fa fa-trash"></span></a>
            <a href="@Url.Action("edit", "Folders", new {id=item.PrimaryKey })"><span class="fa fa-edit"></span></a>
            </text>)

        )

我希望HTML.ActionLink生成像/ folder1 / folder2这样的网址,例如,如果你点击页面文件夹,你会得到一个像/ pages这样的网址,但当你点击页面中的主文件夹时,你会得到一个网址喜欢/ pages / home等

我无法让它工作,也出于某种原因它似乎在第一个层次结构删除后添加了查询字符串。

单击您要转到

的文件夹时,在主页面(/ folders /)上单击

/页/

但页面内的文件夹(让我们说回家)

会有像/ folders?permalink = Home

这样的链接

但是,如果我输入/ pages / home,这仍然可以。

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:0)

你好Agent47我会考虑使用另一种方法。

通常我会创建一个自定义处理程序和一个自定义html帮助程序来覆盖Html.ActionLink。

RouteConfig:

routes.MapRoute(
       "IUrlRouteHandler",
       "{*url}",
       new[] { "YourApp.Controllers" }).RouteHandler = new UrlRouteHandler();

因此,您需要实现一个名为 UrlRouteHandler 的类,它将接收任何“url”,例如http://localhost/admin/folders/folder1/folder2

public sealed class UrlRouteHandler : IRouteHandler
{
     public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        var url = requestContext.HttpContext.Request.Url.ToString();
        var routeData = requestContext.RouteData.Values;

        // manage your rules here!

        routeData["controller"] = "YourController";
        routeData["action"] = "YourAction";

        return new MvcHandler(requestContext);
    }
}

使用上面的url变量来管理规则,不要忘记提供控制器和操作名称。您可以在数据库中查看URL,在静态类中,拆分所有段以确定应用程序将响应哪个控制器和操作。