0

NopCommerce2.30を使用してサイトを構築しています。箱から出して、製品のURLは次のようになります。

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

URLを次のようにするためにいくつかの変更を加えました。

/build-your-own-computer/

パラメータRouteの使用を停止するようにに変更を加えました。Idただし、サイト全体のすべてのリンクは、Url.RouteUrlメソッドを介してIdパラメーターを渡します。

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

これにより、次のURLになります。

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

productIdメソッド呼び出しからパラメーターを削除するだけで済みます。ただし、一部のプラグインは、を含むリンクも追加しますがproductId、これは変更できません。

メソッドをオーバーライドUrl.RouteUrlして製品へのリクエストをチェックしてからRoute削除する方法はありproductIdますか?

4

2 に答える 2

1

これを少し修正したソリューションを使用して問題を解決できました: 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" });
于 2012-02-28T14:14:18.067 に答える
0

RouteUrlをオーバーライドする必要はありません。キーと値のペアのコレクションを取り込みます。ルートを変更してIDを予期しないようにし、@Url.RouteUrl呼び出しから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);
 }
于 2012-02-27T18:20:17.250 に答える