问题
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