2013-03-13 23 views
0

您好,我一直在试图解决一个问题很长一段时间,它与路由和链接没有运气有关。重新格式化路由系统生成的URL

我有一个存储大量书籍的应用程序。每本书都有显示详细信息的链接。为了获得详细信息,我在链接中使用了每本书的ID。这是该链接的代码:

@Html.ActionLink(book.Name, "Details", new { bookId = book.Id , book = book.BookUrl }) 

当用户点击这个链接,一个是被称为控制器,我不准修改:

public ActionResult Details (int bookId){..} 

这是怎么我的链接将显示:

http://localhost:51208/Home/Details/C-sharp-5.0-in-a-Nutshell-The-Definitive-Reference/BookId-2 

我想什么是好歹停止显示CONTROLER动作和BookId.So我的链接会是这个样子:

从我可以告诉到目前为止,没有办法使用路由的标准功能来做到这一点,所以我想我必须以某种方式扩展它的功能。

我一直在阅读关于这个PRO ASP.NET MVC 4和我读过的东西,我必须创建一个类并继承自RouteBase

这将导致必须实现两个方法之一是RouteData GetRouteData(HttpContextBase httpContext)和其他VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)

到目前为止,我只知道,GetVirtualPath负责生成的链接,这样我想这是我必须创建实现获得我想要的功能。

如果是这种情况,有人可以给我一个想法,我应该如何实施这种方法?

如果这不是要采取的路线,那我该如何实现我想要的?

回答

1

你可以通过实现你自己的版本的RouteBase来做到这一点。您需要实施GetRouteDataGetVirtualPath

如果您的GetRouteData的实施需要检查您的书籍数据库,以查看该URL是否包含数据库中书籍的名称,然后返回正确的路由数据,例如

public class BookRoute : RouteBase 
{ 
    public override RouteData GetRouteData(HttpContextBase httpContext) 
    { 
     var url = httpContext.Request.AppRelativeCurrentExecutionFilePath; 
     url = url.Replace(@"~/", ""); 

     var book = getBookWithTheNameThatMatchesTheUrl(url); 

     if (book != null) 
     { 
      var rd = new RouteData(this, new MvcRouteHandler()); 
      rd.Values.Add("controller", "Home"); 
      rd.Values.Add("action", "Details"); 
      rd.Values.Add("bookId", book.Id); 
      return rd; 
     } 

     return null; 
    } 

和你的GetVirtualPath实施将需要做的正好相反 - 找到这本书给定ID的名称,并返回相应的URL。

例如

public override VirtualPathData GetVirtualPath(RequestContext requestContext, 
               RouteValueDictionary values) 
{ 
    if ((string)values["action"] == "Details" && 
     (string)values["controller"] == "Home") 
    { 
     var bookId = (int)values["bookId"]; 
     var bookName = LookUpTheBookNameForTheBookWithThisId(bookId); 
     return new VirtualPathData(this, bookName);  
    } 

    return null; 
} 

最后,添加routes.Add(new BookRoute());你在哪里注册的途径,以使被检查这条新航线。

鉴于方法getBookWithTheNameThatMatchesTheUrl()将触及每个页面的数据库,您希望缓存查找。

2

你可以把额外路由在RouteConfig.cs如下:

routes.MapRoute(
     "Book Details", // Route name 
     "{ bookName }", // URL with parameters 
      new { controller = "BookController", 
        action = "Details", 
        name = UrlParameter.Optional 
       } // Parameter defaults 
     ); 

相应更改Details方法,但是它的参数必须是bookName

注:

把这个路线,在您为避免歧义定义的所有路线的底部。

+0

这不能做我不允许以任何方式修改控制器,但这有助于我在去除控制器和网址中的操作我仍然必须找到不去显示身份证 – aleczandru 2013-03-13 12:42:29

+0

那么你只能把'bookId'在你的路径中,而不是'bookName'。 – 2013-03-13 12:43:47

+0

@aleczandru那你怎么知道'int bookId'没有在url中提供? – hometoast 2013-03-13 12:43:56