首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >stackoverflow URL重写

stackoverflow URL重写
EN

Stack Overflow用户
提问于 2012-03-21 22:00:39
回答 2查看 552关注 0票数 3

如果我们只输入问题ID,那么如何执行URL重写?

代码语言:javascript
复制
questions/{id}/{whatever}

代码语言:javascript
复制
questions/{id}/{question-slug}

我使用MVC已经有一段时间了,我让它正常工作(路由,动作,一切),这样它就可以根据提供的ID选择正确的内容。

但是,{id}后面的部分( slug部分)与键入的部分相同。因此,如果有人输入了content/5/foobar,它将显示正确的内容,但会将foobar留在其中。

在控制器中(或其他地方,请建议在哪里)我需要进入数据库并取出正确的插件,将其放入路由数据中,然后使用此正确数据执行重定向到相同的操作,我猜?

这是一个try with Execute结果重写。它可以工作,但不会在浏览器中重定向或替换/显示正确的URL:

代码语言:javascript
复制
    protected override void Execute(System.Web.Routing.RequestContext requestContext) {

        if (requestContext.RouteData.Values["id"] != null) {
            string currentSlug = _repository.Find(int.Parse(requestContext.RouteData.Values["id"].ToString())).Slug;
            if (requestContext.RouteData.Values["slug"] != null) {
                requestContext.RouteData.Values.Remove("slug");
            }
            requestContext.RouteData.Values.Add("slug", currentSlug);
        }

        base.Execute(requestContext);
    }

这是另一个运行良好的Display操作版本,因此您可以看到它的作用,并了解我想要什么:

代码语言:javascript
复制
    //
    // GET: {culture}/directory/5/{slug}
    public virtual ActionResult Display(int id, string slug)
    {
        var model = _repository.Find(id);
        if (model != null) {
            if (!model.Slug.Equals(slug, System.StringComparison.OrdinalIgnoreCase)) {
                return RedirectToActionPermanent(pndng.DirectoryEntry.ActionNames.Display, pndng.DirectoryEntry.Name, new { id = model.Id, slug = model.Slug });
            }
            return View(model);
        }
        // no model found
        return InvokeHttp404(HttpContext);
    }

它执行永久重定向(它做了我想要的),但是它是正确的吗?我想我需要重定向来刷新浏览器URL,不是吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-03-21 22:36:55

代码语言:javascript
复制
  public ActionResult Details(int id, string slug)
        {
            var session = MvcApplication.CurrentRavenSession;

            var blogPostRelations = session
                .Query<BlogPost, BlogPosts_WithRelatedData>()
                .Where(x => x.IntId == id)
                .As<BlogPostRelations>()
                .FirstOrDefault()
                ;


            if (blogPostRelations == null)
                return HttpNotFound();

            if (blogPostRelations.BlogPost.DisplayData.Slug.Value != slug)
                return RedirectToActionPermanent("Details", new { id = id, slug = blogPostRelations.BlogPost.DisplayData.Slug.Value });

            return View(blogPostRelations);
        }

请注意:

代码语言:javascript
复制
if (blogPostRelations.BlogPost.DisplayData.Slug.Value != slug)
                    return RedirectToActionPermanent("Details", new { id = id, slug = blogPostRelations.BlogPost.DisplayData.Slug.Value });

所以你的2号方法是正确的。

票数 2
EN

Stack Overflow用户

发布于 2012-03-21 22:49:22

您可以为此编写一个自定义路由:

代码语言:javascript
复制
public class QuestionsRoute : Route
{
    public QuestionsRoute()
        : base(
            "questions/{id}/{slug}",
            new RouteValueDictionary(new
            {
                controller = "questions",
                action = "index",
                slug = UrlParameter.Optional
            }),
            new RouteValueDictionary(new
            {
                id = @"\d+"
            }),
            new MvcRouteHandler()
        )
    { }

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        var rd = base.GetRouteData(httpContext);
        if (rd == null)
        {
            return null;
        }

        var id = rd.GetRequiredString("id");
        var slug = rd.Values["slug"] as string;
        if (string.IsNullOrEmpty(slug))
        {
            slug = GoFetchSlugFromDb(id);
            if (string.IsNullOrEmpty(slug))
            {
                return null;
            }

            httpContext.Response.RedirectToRoutePermanent(new
            {
                action = "index",
                controller = "questions",
                id = id,
                slug = slug
            });
            return null;
        }
        return rd;
    }

    private string GoFetchSlugFromDb(string id)
    {
        // TODO: you know what to do here
        throw new NotImplementedException();
    }
}

将在Application_Start中注册的

代码语言:javascript
复制
public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    routes.Add("questions", new QuestionsRoute());
}

现在,您的QuestionsController将非常简单:

代码语言:javascript
复制
public class QuestionsController: Controller
{
    public ActionResult Index(int id, string slug)
    {
        ...
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9806134

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档