Add text to URLs instead of int ID

核能气质少年 提交于 2019-12-12 15:35:27

问题


At the moment our permalinks are not correct and hinder searching e.g. https://example.com/en/blogs/19 - this should have words in the URL that Google can pick up in the search, instead of a int id that is used to retrieve from Db.

Let's say an article for 'The Automotive Industry Latest' Google will give more weight in the algorithm if we had the ability to edit the link that included keywords. For example: https://example.com/en/blogs/news/The_Automotive_Industry_Latest - this link should point to https://example.com/en/blogs/19

I can accomplish this by using the following - but is this the way to achieve this?

[Route("en/blogs")]
public class BlogController : Controller
{
    [HttpGet("{id}")]
    [AllowAnonymous]
    public IActionResult GetId([FromRoute] int id)
    {
        var blog = _context.Blogs.Where(b => b.Id == id);

        return Json(blog);
    }

    [HttpGet("{text}")]
    [AllowAnonymous]
    public IActionResult GetText([FromRoute] string text)
    {
        var blog = _context.Blogs.Where(b => b.Title.Contains(text));

        if(blog != null)
            GetId(blog.Id)

        return Ok();
    }
}

I'm guessing this still wouldn't be indexed as text by Google, so would have to be done via sitemap.xml? This must be a common requirement but I can't find any documentation on it.

I'm aware of IIS URL rewrite but would like to stay away from this if possible.


回答1:


Referencing Routing in ASP.NET Core

You can use the * character as a prefix to a route parameter to bind to the rest of the URI - this is called a catch-all parameter. For example, blog/{*slug} would match any URI that started with /blog and had any value following it (which would be assigned to the slug route value). Catch-all parameters can also match the empty string.

Referencing Routing to Controller Actions in ASP.NET Core

you can apply route constraints to make sure that the id and title do not conflict with each other to get the desired behavior.

[Route("en/blogs")]
public class BlogController : Controller {
    //Match GET en/blogs/19
    //Match GET en/blogs/19/the-automotive-industry-latest
    [HttpGet("{id:long}/{*slug?}",  Name = "blogs_endpoint")]
    [AllowAnonymous]
    public IActionResult GetBlog(long id, string slug = null) {
        var blog = _context.Blogs.FirstOrDefault(b => b.Id == id);

        if(blog == null)
            return NotFound();

        //TODO: verify title and redirect if they do not match
        if(!string.Equals(blog.slug, slug, StringComparison.InvariantCultureIgnoreCase)) {
            slug = blog.slug; //reset the correct slug/title
            return RedirectToRoute("blogs_endpoint",  new { id = id, slug = slug });
        }

        return Json(blog);
    }
}

This follows a similar pattern to what StackOverflow does for their links

questions/50425902/add-text-to-urls-instead-of-int-id

So now your links can include search friendly words that should help with linking to the desired articles

GET en/blogs/19
GET en/blogs/19/The-Automotive-Industry-Latest.

I would suggest generating the slug as a field/property based on the blog title when saving the blog to the database, making sure to sanitize the title derived slug of any invalid URL characters.



来源:https://stackoverflow.com/questions/50425902/add-text-to-urls-instead-of-int-id

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!