在mvc中显示url slug而不是id

时间:2015-04-20 16:08:30

标签: c# sql asp.net-mvc linq entity-framework

我有一个博客应用程序,用户可以创建帖子,我使用Entity框架从数据库创建模型。在帖子中,我有UrlSlug的条目。

但是,当我查看帖子的详细信息时:

控制器:

    public ActionResult Details(int id = 0)
    {
        Post post = db.Posts.Find(id);
        if (post == null)
        {
            return HttpNotFound();
        }
        return View(post);
    }

它会在结尾处返回一个id的网址:http://localhost:52202/Post/Details/1

我已经尝试返回post.UrlSlug(抛出错误)以及更改我的RouteConfig.cs文件以使用urlslug而不是id(它显示urlslug,但它无法找到页面因为控制器)。如何更改此设置以显示urlslug而不是Post Table Id

RouteConfig.cs

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

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

查看:

@for (int i = 0; i < Model.Count(); i += 3)
{
    <div class="row">
        @foreach (var item in Model.Skip(i).Take(3))
        {
            <div class="col-md-4 portfolio-item">
                <a href="@Url.Action("Details", "Post", new { id = item.Id })">
                    <img class="img-responsive" src="http://placehold.it/700x400" alt="">
                </a>
                <h3>
                    <a href="@Url.Action("Details", "Post", new { id = item.Id })">@Html.DisplayFor(modelItem => item.Title)</a>
                </h3>

                <p>@Html.DisplayFor(modelItem => item.ShortDescription)</p>

            </div>
        }

    </div>
}

@Html.PagedListPager(Model, page => Url.Action("Index", new { page, pageSize = Model.PageSize }))

修改

我注意到的问题就在这一行:

    public ActionResult Details(string urlslug)
    {
        Post post = db.Posts.Find(urlslug); //find only finds an eitity with a given primary key, how can I change this to find the string urlslug

2 个答案:

答案 0 :(得分:3)

操作方法不指示URL,它只匹配请求。你需要打印slu ::

@Url.Action("Details", "Post", new { slug = item.Slug })

然后添加到路由以支持您想要的URL结构:

routes.MapRoute(
    name: "PostWithSlug",
    url: "Post/Details/{slug}",
    defaults: new {  }

并改变行动方法:

public ActionResult Details(string slug)
{
}

但除此之外,你想要一个ID在URL中。否则你不能两次使用相同的帖子标题。

答案 1 :(得分:-1)

您可以在控制器中重命名您的参数以匹配&#39; slug&#39;名称。而不是

public ActionResult Details(int id = 0)

使用

public ActionResult Details(int urlslug = 0)

替代方法是从路由配置中删除id,如

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

请记住,您的Action中的参数名称是什么,该名称在您的网址中用作GET变量。所以如果参数是int id,那么你的url必须是?id = 1。