Asp.net mvc 3 创建包含id和标题段塞的规范URL

Asp.net mvc 3 创建包含id和标题段塞的规范URL,asp.net-mvc-3,seo,asp.net-mvc-routing,http-status-code-301,Asp.net Mvc 3,Seo,Asp.net Mvc Routing,Http Status Code 301,我想复制StackOverflow对其URL的作用 例如: - 或 - 将带您进入同一页面,但当它们返回到浏览器时,始终返回第一个页面 如何实现更改以返回更大的URL?我以前处理此问题的方法是按此顺序注册两个路由 routes.MapRoute( null, "questions/{id}/{title}", new { controller = "Questions", action = "Index" }, new { id = @"\d+", title =

我想复制StackOverflow对其URL的作用

例如:

-

-

将带您进入同一页面,但当它们返回到浏览器时,始终返回第一个页面


如何实现更改以返回更大的URL?

我以前处理此问题的方法是按此顺序注册两个路由

routes.MapRoute(
    null,
    "questions/{id}/{title}",
    new { controller = "Questions", action = "Index" },
    new { id = @"\d+", title = @"[\w\-]*" });

routes.MapRoute(
    null,
    "questions/{id}",
    new { controller = "Questions", action = "Index" },
    new { id = @"\d+" });
现在在控制器操作中

public class QuestionsController 
{
    private readonly IQuestionRepository _questionRepo;

    public QuestionsController(IQuestionRepository questionRepo)
    {
        _questionRepo = questionRepo;
    }

    public ActionResult Index(int id, string title)
    {
        var question = _questionRepo.Get(id);

        if (string.IsNullOrWhiteSpace(title) || title != question.Title.ToSlug())
        {
            return RedirectToAction("Index", new { id, title = question.Title.ToSlug() }).AsMovedPermanently();
        }

        return View(question);
    }
}
如果我们只有id,我们将永久重定向到包含标题slug小写标题并使用连字符作为分隔符的URL。我们还将通过对照问题标题的slug版本进行检查来确保传递的标题是正确的,从而为包含id和正确标题的问题创建规范URL

有几个帮手用过

public static class PermanentRedirectionExtensions
{
    public static PermanentRedirectToRouteResult AsMovedPermanently
        (this RedirectToRouteResult redirection)
    {
        return new PermanentRedirectToRouteResult(redirection);
    }
}

public class PermanentRedirectToRouteResult : ActionResult
{
    public RedirectToRouteResult Redirection { get; private set; }
    public PermanentRedirectToRouteResult(RedirectToRouteResult redirection)
    {
        this.Redirection = redirection;
    }
    public override void ExecuteResult(ControllerContext context)
    {
        // After setting up a normal redirection, switch it to a 301
        Redirection.ExecuteResult(context);
        context.HttpContext.Response.StatusCode = 301;
        context.HttpContext.Response.Status = "301 Moved Permanently";
    }
}

public static class StringExtensions
{
    private static readonly Encoding Encoding = Encoding.GetEncoding("Cyrillic");

    public static string RemoveAccent(this string value)
    {
        byte[] bytes = Encoding.GetBytes(value);
        return Encoding.ASCII.GetString(bytes);
    }

    public static string ToSlug(this string value)
    {
        if (string.IsNullOrWhiteSpace(value))
        {
            return string.Empty;
        }

        var str = value.RemoveAccent().ToLowerInvariant();

        str = Regex.Replace(str, @"[^a-z0-9\s-]", "");

        str = Regex.Replace(str, @"\s+", " ").Trim();

        str = str.Substring(0, str.Length <= 200 ? str.Length : 200).Trim();

        str = Regex.Replace(str, @"\s", "-");

        str = Regex.Replace(str, @"-+", "-");

        return str;
    }
}

我以前处理这件事的方法是按这个顺序注册两条路线

routes.MapRoute(
    null,
    "questions/{id}/{title}",
    new { controller = "Questions", action = "Index" },
    new { id = @"\d+", title = @"[\w\-]*" });

routes.MapRoute(
    null,
    "questions/{id}",
    new { controller = "Questions", action = "Index" },
    new { id = @"\d+" });
现在在控制器操作中

public class QuestionsController 
{
    private readonly IQuestionRepository _questionRepo;

    public QuestionsController(IQuestionRepository questionRepo)
    {
        _questionRepo = questionRepo;
    }

    public ActionResult Index(int id, string title)
    {
        var question = _questionRepo.Get(id);

        if (string.IsNullOrWhiteSpace(title) || title != question.Title.ToSlug())
        {
            return RedirectToAction("Index", new { id, title = question.Title.ToSlug() }).AsMovedPermanently();
        }

        return View(question);
    }
}
如果我们只有id,我们将永久重定向到包含标题slug小写标题并使用连字符作为分隔符的URL。我们还将通过对照问题标题的slug版本进行检查来确保传递的标题是正确的,从而为包含id和正确标题的问题创建规范URL

有几个帮手用过

public static class PermanentRedirectionExtensions
{
    public static PermanentRedirectToRouteResult AsMovedPermanently
        (this RedirectToRouteResult redirection)
    {
        return new PermanentRedirectToRouteResult(redirection);
    }
}

public class PermanentRedirectToRouteResult : ActionResult
{
    public RedirectToRouteResult Redirection { get; private set; }
    public PermanentRedirectToRouteResult(RedirectToRouteResult redirection)
    {
        this.Redirection = redirection;
    }
    public override void ExecuteResult(ControllerContext context)
    {
        // After setting up a normal redirection, switch it to a 301
        Redirection.ExecuteResult(context);
        context.HttpContext.Response.StatusCode = 301;
        context.HttpContext.Response.Status = "301 Moved Permanently";
    }
}

public static class StringExtensions
{
    private static readonly Encoding Encoding = Encoding.GetEncoding("Cyrillic");

    public static string RemoveAccent(this string value)
    {
        byte[] bytes = Encoding.GetBytes(value);
        return Encoding.ASCII.GetString(bytes);
    }

    public static string ToSlug(this string value)
    {
        if (string.IsNullOrWhiteSpace(value))
        {
            return string.Empty;
        }

        var str = value.RemoveAccent().ToLowerInvariant();

        str = Regex.Replace(str, @"[^a-z0-9\s-]", "");

        str = Regex.Replace(str, @"\s+", " ").Trim();

        str = str.Substring(0, str.Length <= 200 ? str.Length : 200).Trim();

        str = Regex.Replace(str, @"\s", "-");

        str = Regex.Replace(str, @"-+", "-");

        return str;
    }
}