2012-02-27 1 views
0

私はNopCommerce 2.30を使用してサイトを構築しています。箱から出して、製品のURLは次のようになります。UrlHelper.RouteUrlをオーバーライド

/build-your-own-computer/ 

は私がRouteに変更するにはを作った:私は、URLは次のように見てもらうためにいくつかの変更を加えました

/p/16/build-your-own-computer/ 

Idパラメータを使用しないようにしてください。しかし、サイト全体のすべてのリンクがまだUrl.RouteUrlメソッドを介してIDパラメータを渡している。

/build-your-own-computer/?productId=16 

私はちょうど通過し、productIdパラメータを削除できます。

@Url.RouteUrl("Product", new { productId = Model.Id, SeName = Model.SeName }) 

これは、次のURLになりメソッド呼び出しから取得します。ただし、プラグインによってはproductIdを含むリンクも追加されますが、変更することはできません。

Url.RouteUrlメソッドを無効にして、製品Routeへのリクエストを確認してから、productIdを削除する方法はありますか?

+1

ウム - IdはあなたがURL内のIDを渡していない場合は、ユーザーによってクリックされたものを製品あなたのコントローラ/アクションが知っているだろうか? – Tommy

+0

製品IDを使用して製品を入手するのではなく、製品名を使用します。 –

答えて

0

私はこれを少し変更した溶液を使用して、私の問題を解決するために管理してきました:http://erraticdev.blogspot.com/2011/03/removing-route-values-from-linksurls-in.html私はいくつかを作ったので、ロバートのソリューションは、名前空間が含まれていませんでした

以下の調整:

public static class CustomRouteExtensions 
{ 

    public static Route MapRoute(this RouteCollection routes, string name, string url, string excludeRouteValueNames, object defaults) 
    { 
     return MapRoute(routes, name, url, excludeRouteValueNames, defaults, null, null); 
    } 

    public static Route MapRoute(this RouteCollection routes, string name, string url, string excludeRouteValueNames, object defaults, string[] namespaces) 
    { 
     return MapRoute(routes, name, url, excludeRouteValueNames, defaults, null, namespaces); 
    } 

    public static Route MapRoute(this RouteCollection routes, string name, string url, string excludeRouteValueNames, object defaults, object constraints) 
    { 
     return MapRoute(routes, name, url, excludeRouteValueNames, defaults, constraints, null); 
    } 

    public static Route MapRoute(this RouteCollection routes, string name, string url, string excludeRouteValueNames, object defaults, object constraints, string[] namespaces) 
    { 
     if (routes == null) 
      throw new ArgumentNullException("routes"); 

     if (url == null) 
      throw new ArgumentNullException("url"); 

     Route item = new CustomRoute(url, new MvcRouteHandler(), excludeRouteValueNames) 
     { 
      Defaults = new RouteValueDictionary(defaults), 
      Constraints = new RouteValueDictionary(constraints), 
      DataTokens = new RouteValueDictionary() 
     }; 

     if ((namespaces != null) && (namespaces.Length > 0)) 
      item.DataTokens["Namespaces"] = namespaces; 

     routes.Add(name, item); 

     return item; 
    } 

} 

私のカスタムはRouteその後、次のようになります。

public class CustomRoute : Route 
{ 

    #region Properties 

    public ReadOnlyCollection<string> ExcludedRouteValuesNames { get; private set; } 

    #endregion 

    #region Constructor 

    public CustomRoute(string url, IRouteHandler routeHandler, string commaSeparatedRouteValueNames) 
     : this(url, routeHandler, (commaSeparatedRouteValueNames ?? string.Empty).Split(',')) 
    { 
    } 

    public CustomRoute(string url, IRouteHandler routeHandler, params string[] excludeRouteValuesNames) 
     : base(url, routeHandler) 
    { 
     ExcludedRouteValuesNames = new ReadOnlyCollection<string>(excludeRouteValuesNames.Select(val => val.Trim()).ToList()); 
    } 

    #endregion 

    #region Route overrides 

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) 
    { 
     if (requestContext == null) 
      throw new ArgumentNullException("requestContext"); 

     // create new route data and include only non-excluded values 
     var excludedRouteData = new RouteData(this, this.RouteHandler); 

     // add route values 
     requestContext.RouteData.Values 
      .Where(pair => !this.ExcludedRouteValuesNames.Contains(pair.Key, StringComparer.OrdinalIgnoreCase)) 
      .ToList() 
      .ForEach(pair => excludedRouteData.Values.Add(pair.Key, pair.Value)); 

     // add data tokens 
     requestContext.RouteData.DataTokens 
      .ToList() 
      .ForEach(pair => excludedRouteData.DataTokens.Add(pair.Key, pair.Value)); 

     // intermediary request context 
     var currentContext = new RequestContext(new HttpContextWrapper(HttpContext.Current), excludedRouteData); 

     // create new URL route values and include only none-excluded values 
     var excludedRouteValues = new RouteValueDictionary(
      values 
       .Where(v => !this.ExcludedRouteValuesNames.Contains(v.Key, StringComparer.OrdinalIgnoreCase)) 
       .ToDictionary(pair => pair.Key, pair => pair.Value) 
     ); 

     var result = base.GetVirtualPath(currentContext, excludedRouteValues); 

     return result; 
    } 

    #endregion 

} 

は私の新しいRoute.MapRouteは次のようになります。

routes.MapRoute("Product", 
       "{SeName}", 
       "productIdd", 
       new { controller = "Catalog", action = "UrlType" }, 
       new[] { "Nop.Plugin.FreshEgg.Seo.Controllers" }); 
0

RouteUrlを無効にする必要はありません。それは、キーと値のペアの集合を取ります。 @ Url.RouteUrl呼び出しからIDを削除し、idを削除するようにルートを変更するだけです。あなたは、次のようなURLを受け入れ、ルートを作成する必要があります。

/p/{productName}

あなたのGlobal.asaxの中でそれを行うことができます。

routes.MapRoute(
    "Products", 
    "/p/{productName}", 
    new { controller = "Products", action = "Details" } 
); 

今、あなたの代わりにこのようなルートが生成されます。

@Url.RouteUrl("Products", new { productName = Model.SeName }) 

コントローラでは、IDの代わりに名前から製品を見つけるために追加作業が必要です。これはおそらく、今、代わりに次のようになります:

public ActionResult Details(string productName) 
{ 
    var product = ProductRepository.FindByName(productName); 

    return View(product); 
} 
+0

こんにちは、ご意見ありがとうございます。これは私がすでにやっていることですが、 '@ Url.RouteUrl'オカレンスのすべてが' productId'をまだ送信しています。'productId'は' Route'の一部ではないので、それをクエリの文字列パラメータとしてリンクの最後に追加します。クエリ文字列パラメータを '@ Url.RouteUrl'から削除せずに追加するのを止める必要があります。 –

+0

@ScroobyこのIDが渡されることを期待しているあなたのコードがありますか?それはUrl.RouteUrlの呼び出しに渡されますが、コントローラには渡されませんか? – Dismissile

+0

@Dismissle私は、ビュー内の他の場所でIDを使用しているため、コントローラから削除することはできません。 –

関連する問題