【问题标题】:MVC Core: Routing for displaying detailed information in the URLMVC Core:用于在 URL 中显示详细信息的路由
【发布时间】:2017-02-26 18:39:23
【问题描述】:

想象一个用 ASP.Net MVC 编写的在线商店,我有一个用于显示产品和产品详细信息的控制器。给定以下代码

public class ProductsController : Controller {

    public IActionResult Index(){
        return View(ProductList);
    }
    public IActionResult Details(String id){
        return View(FindProduct(id));
    }
}

查找产品时在网络浏览器的地址栏中显示的 URL 类似于:www.onlineshop.com/Products/Details?id=1234

我一直在研究 SEO,我一直认为如果我将 URL 重新路由到更详细的内容会更好,例如:

www.onlineshop.com/Products/Sony/Gaming/PlayStation/PS4Model12345

如何在 ASP.Net MVC (Core) 中实现这一点? (鉴于我提供的示例控制器)

【问题讨论】:

  • 也许去阅读一些教程,这是一个非常广泛的问题。
  • @DavidG:不是,它仅限于路由大卫。并且更多地限于路由 asp.net core。
  • 不,它是 MVC 路由,向您的实体添加 slug,它会影响您逻辑的整个管道。
  • @DavidG:您认为将Details 转发到另一个操作以重写URL 是个好主意吗?
  • 不,我认为这不是一个好主意。

标签: asp.net asp.net-mvc asp.net-core-mvc asp.net-routing


【解决方案1】:

这个问题的答案其实很简单。我不知道为什么这里的其他用户推荐相当冗长的解决方案,但我认为可以通过在Details API 上添加Route 属性来执行。当有人需要在View 中显示产品列表时,如果他们只显示Product Id 并且通常IEnumberable<Product> 在问题中提出的情况下传递给Index 视图,这是非常不可能和不合逻辑的.因此,可以做到以下几点:

[Route("Products/Details/{Manufacturer=unnamed}/{Category=unnamed}/{ActualProduct=unnamed}/{Model=unnamed}/{URLTrail=unnamed}")]
public IActionResult Details(GUID id) {
    return View(FindProduct(id));
} 

示例输出:www.MyOnlineShop.com/Products/Details/Microsoft/Surface/SurfacePro/xxxx-xxxx-....

现在,如果缺少其中一些 URL 参数确实无关紧要,但用户可以选择呈现他们喜欢的 URL!。

更新:

在视图内构建 URL 对 SEO 更友好,因为它可以创建合理的链接!

一个更好的例子,在stackoverflow的情况下,这个问题的URL是

http://stackoverflow.com/questions/42472547/mvc-core-routing-for-displaying-detailed-information-in-the-url

在这个例子中,实际的问题 ID 是 42472547 并且尾随部分用于 SEO,以便 Google 可以搜索问题。在此示例中,适用以下路线:

[Route("Questions/{id}/{SEOHint}"]

{id} 部分用于查找问题,而不是 {SEOHint} 部分。

更新的解决方案

我编写了以下属性,可以自定义以实现此功能。

public abstract class URLOptimizerAttributeBase : Attribute, IRouteTemplateProvider, IActionFilter
{
    public String Template { get; private set; }
    public int? Order { get; set; }
    public string Name { get; set; }
    public URLOptimizerAttributeBase(String Template) {
        this.Template = Template;
    }
    public abstract Boolean Validate(RouteData routeData);
    public abstract RedirectToRouteResult Redirect(RouteValueDictionary routeValueDictionary);
    public abstract void OnActionExecuted(ActionExecutedContext context);
    public virtual void OnActionExecuting(ActionExecutingContext context)
    {
        if (!Validate(context.RouteData))
        {
            context.Result = Redirect(context.RouteData.Values);
        }    
    }
}

下面提供了该属性的实现示例。

public class URLOptimization : URLOptimizerAttributeBase
{
    private String SEOHint;
    public URLOptimization(string Template) : base(Template)
    {
    }

    public object DbContext { get; private set; }

    public override void OnActionExecuted(ActionExecutedContext context)
    {
    }
    public override bool Validate(RouteData routeData)
    {
        return routeData.Values["SEOHint"].Equals(SEOHint);
    }
    public override RedirectToRouteResult Redirect(RouteValueDictionary routeValueDictionary)
    {
        routeValueDictionary["SEOHind"] = SEOHint;
        return new RedirectToRouteResult(routeValueDictionary);
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        var id = context.RouteData.Values["Id"];
        DbContext db = (DbContext)context.HttpContext.RequestServices.GetService(typeof(DbContext));
        var product = db.Find<Products>(id);
        if (product != null)
        {
            SEOHint = product.SEOURL;
            ((Controller)context.Controller).ViewBag.Data = product;
             base.OnActionExecuting(context);
        }
        else {
            context.Result = new RedirectResult("Error Page");
        }
    }
}

使用该属性的示例如下:

[URLOptimization("Products/Details/{Id}/{SEOHint=unnamed}")]
public IActionResult Details(){
    return View(ViewBag.Data);
}

【讨论】:

  • 但是我们如何获取信息:控制器内部的制造商、类别和产品名称?
  • @Alex:当您想要显示产品列表时,您可以将IEnumerable&lt;Product&gt; 之类的内容传递到列出产品的视图中。当您想查看详细信息时,由于模型已经在视图中,您可以创建 URL 并通过 Id 查找。
  • 但是这些参数是否应该包含在详细签名中?
  • @Alex:不一定,它们不是强制性的。但是,如果存在视图中不可用但必须是 URL 的一部分的参数,则 ActionFilter 可以解决问题。
猜你喜欢
  • 2021-09-14
  • 1970-01-01
  • 2020-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-24
  • 1970-01-01
相关资源
最近更新 更多