使用GUID作为id的MVC 5路由,隐藏在URL中

时间:2013-09-11 22:29:35

标签: c# asp.net-mvc asp.net-ajax

我在项目MVC 5(.NET 4.5而不是4.5.1)下使用W8.1上的VS2013预览版,我一直在研究过去几个小时尝试各种各样的事情,看来我只是不这样做得到我所缺少的东西。

我正在通过建立一个论坛来开展学校项目,我希望URL是分层的,即 localhost:1234/Forum/Science/Physics/String%20Theory

这是RouteConfig:

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{action}/{*title}",
            defaults: new { controller = "Home", action = "Index", title = UrlParameter.Optional }
        );
    }

控制器:

public ActionResult Index()
    {
        return View(db.Categories.Where(x => x.ParentId == null).ToList());
    }

public ActionResult Forum(string parentId)
    {
        return View("Index", db.Categories.Where(x => x.ParentId == parentId));
    }

并查看(这是索引页面):

@foreach (var item in Model)
    {
        <div class="CatLevel0">
            <h2>@Ajax.ActionLink(item.Title, "Forum", new { parentId = item.Id, title = item.Title }, new AjaxOptions() { HttpMethod = "POST" })</h2>
            <h4>@Html.DisplayFor(modelItem => item.Description)</h4>
        </div>
    }

这就是问题所在。上面的链接(例如“科学”)指示: "http://localhost:1234/Forum/Science?parentId=b8bd9ded-7284-462d-b0cc-d8ce09717b8a", 在转发到“科学”并被重定向到“社会科学”之后的第二级我得到: "http://localhost:1234/Forum/Social%20Sciences?parentId=2a9f1c24-c6d4-44ab-b000-3268f38794f3"

因此,我不仅在查询字符串中获得冗余的GUID(我不想要!),但我也失去了“〜/ Forum / Science / Social%20Sciences”中的前驱“科学”;

在其他一些SO问题中,我们注意到Ajax.ActionLink需要jquery不引人注目的ajax,它可以在Chrome开发者工具的网络选项卡中正确呈现。

更新:我设法解决了@TimothyWalters提到的问题,使用以下内容:

控制器:

public ActionResult Forum(string parentId, string title)
    {
        TempData["fullTitle"] = title + "/";
        return View("Index", db.Categories.Where(x => x.ParentId == parentId));
    }

查看:

@foreach (var item in Model)
    {
        <div class="CatLevel0">
            @*<h2>@Html.ActionLink(item.Title, "Forum", new { parentId = item.Id, title = item.Title })</h2>*@
            <h2>@Ajax.ActionLink(item.Title, "Forum", new { parentId = item.Id, title = TempData["fullTitle"] + item.Title }, new AjaxOptions() { HttpMethod = "POST" })</h2>
            <h4>@Html.DisplayFor(modelItem => item.Description)</h4>
        </div>
    }

所以现在我有了http://localhost:5465/Forum/Science/Social%20Sciences?parentId=2a9f1c24-c6d4-44ab-b000-3268f38794f3,这使得查询字符串中的GUID问题得以处理。

Update2 :呃 - 现在我明白了:http://localhost:5465/Forum/Science/Social%20Sciences/Science/Social%20Sciences?parentId=2a9f1c24-c6d4-44ab-b000-3268f38794f3。 。 。

1 个答案:

答案 0 :(得分:0)

如果您不想在查询字符串中使用GUID,请停止将其放在那里。如果你不打算在那里,你将需要一些可靠的方法从你的道路中提取意义。

您明确告诉它将GUID放在查询字符串中,并在您的parentId调用中包含ActionLink()的视图中的代码。删除该参数,您将不再拥有GUID。

要从您的路径中提取意义,您需要一种方法将“科学/物理/弦理论”转换为您之前通过GUID找到的父级的“字符串理论”子项。

var parts = title.Split('/');
var categories = db.Categories
    .Where(c => parts.Contains(c.Title))
    .ToList();

// start at the root
var category = categories.Where(c => c.ParentId == null && c.Title == parts[0]);

// look for anything past the root level (starting at index 1 not 0)
for (var i = 1; i < parts.Length; i++)
{
    category = categories.Where(c => c.ParentId == category.Id && c.Title == parts[i]);
}

// use category to create new view
return View(category);