2010-12-30 23 views
7

Tôi gặp sự cố với một ràng buộc cụ thể mà tôi đang cố gắng thiết lập trên tuyến đường. URL của tôi phải trông giống như sau: http://hostname/id-my-title-can-be-that-long trong đó id được tạo bằng chữ số và tiêu đề là ký tự chữ thường có dấu phân cách dấu gạch ngang. Id và tiêu đề cũng được phân tách bằng dấu gạch ngang. Ví dụ: http://hostname/123-my-title.Hạn chế lộ trình ASP.NET MVC regex

Dưới đây là định nghĩa con đường của tôi:

routes.MapRoute(
    "Test", 
    "{id}-{title}", 
    new { controller = "Article", action = "Index" }, 
    new { id = @"(\d)+", title = @"([a-z]+-?)+" } 
); 

URL được tạo ra một cách chính xác với các helper html:

<%: Html.ActionLink("My link", "Index", "Article", new { id = Model.IdArticle, title = Model.UrlTitle }, null) %> 

nơi, tất nhiên, Model.IdArticle là một Int32 và Model.UrlTitle một chuỗi preformed của tiêu đề của tôi phù hợp với yêu cầu của tôi (chỉ trường hợp thấp hơn, không gian thay thế bằng dấu gạch ngang).

Vấn đề là, khi tôi theo liên kết, điều khiển bên phải & phương pháp không được gọi, nó rơi xuống tuyến đường tiếp theo sai.

Để lưu bản ghi, tôi đang sử dụng ASP.NET MVC 2.

Có ai có ý tưởng không?

Cảm ơn trước, Fabian

+0

Cuối cùng, chúng tôi sẽ tách ID khỏi tiêu đề bằng dấu gạch dưới. Tôi vẫn tự hỏi tại sao điều này không hoạt động nhưng nó không còn chặn nữa. Cảm ơn bạn đã giúp đỡ! –

Trả lời

0

Bạn có thể thử đi qua các chuỗi đường toàn "{id} - {title}" và phân tích chuỗi bằng tay mình trước khi nó được thành hành động của bạn bằng cách làm một cái gì đó tương tự như Phil Haack của slug to id actionfilter attribute - link

Hy vọng điều này sẽ hữu ích.

+0

Tôi đã đọc bài đăng trên blog đó trước đây nhưng tôi thấy nó quá mức cần thiết khi tôi có thể chia nhỏ thông tin tuyến đường. Vì URL của tôi có thể được tạo từ tuyến đường nhưng không được giải quyết như một tuyến đường, tôi đang nghĩ về một số loại lỗi trong MVC. –

+0

Ah đủ công bằng. Sẽ có một suy nghĩ :-) – WestDiscGolf

0

Một số ký tự trong tuyến đường là "đặc biệt" và sẽ chia nhỏ các tham số như - và /. Nó có thể là thêm -s -s tuyến đường đang gây ra nó thất bại. Hãy thử "{id}-{*title}" vì điều này làm cho tiêu đề bao gồm mọi thứ tiếp theo.

Cập nhật

Câu trả lời ở trên là những gì sẽ xảy ra khi bạn đi trên StackOverflow trước khi bạn đã có đủ cà phê.

Chúng tôi gặp phải vấn đề tương tự với tên tệp đối với tệp do người dùng tải lên, tuyến đường được bao gồm '-' làm dấu phân cách nhưng cũng có thể được sử dụng trong giá trị trong tham số sau, nó có thể tạo URL chính xác nhưng không phù hợp với nó. Cuối cùng tôi đã viết một lớp SpecialFileRoute để xử lý vấn đề này và đăng ký tuyến đường này. Đó là một chút xấu xí mặc dù nhưng không công việc.

Lưu ý rằng tôi đã giữ nguyên tuyến đường MVC cũ để tạo URL, tôi đang chơi xung quanh với việc này để làm điều đó đúng cách nhưng đó là một cái gì đó để quay lại sau.

/// <summary> 
/// Special route to handle hyphens in the filename, a catchall parameter in the commented route caused exceptions 
/// </summary> 
public class SpecialFileRoute : RouteBase, IRouteWithArea 
{ 
    public string Controller { get; set; } 
    public string Action { get; set; } 
    public IRouteHandler RouteHandler = new MvcRouteHandler(); 
    public string Area { get; private set; } 

    //Doc/{doccode} - {CatNumber}.{version} - {*filename}, 

    public SpecialFileRoute(string area) 
    { 
     Area = area; 
    } 

    public override RouteData GetRouteData(HttpContextBase httpContext) 
    { 
     string url = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2); 
     var urlmatch = Regex.Match(url, @"doc/(\w*) - (\d*).(\d*) - (.*)", RegexOptions.IgnoreCase); 
     if (urlmatch.Success) 
     { 
      var routeData = new RouteData(this, this.RouteHandler); 

      routeData.Values.Add("doccode", urlmatch.Groups[1].Value); 
      routeData.Values.Add("CatNumber", urlmatch.Groups[2].Value); 
      routeData.Values.Add("version", urlmatch.Groups[3].Value); 
      routeData.Values.Add("filename", urlmatch.Groups[4].Value); 
      routeData.Values.Add("controller", this.Controller); 
      routeData.Values.Add("action", this.Action); 
      return routeData; 
     } 
     else 
      return null; 
    } 

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) 
    { 
     if (values.ContainsKey("controller") && (!string.Equals(Controller, values["controller"] as string, StringComparison.InvariantCultureIgnoreCase))) 
      return null; 
     if (values.ContainsKey("action") && (!string.Equals(Action, values["action"] as string, StringComparison.InvariantCultureIgnoreCase))) 
      return null; 
     if ((!values.ContainsKey("contentUrl")) || (!values.ContainsKey("format"))) 
      return null; 
     return new VirtualPathData(this, string.Format("{0}.{1}", values["contentUrl"], values["format"])); 
    } 
} 

Các tuyến đường được bổ sung như sau:

context.Routes.Add(new SpecialFileRoute(AreaName) { Controller = "Doc", Action = "Download" }); 

Như đã trình bày ở trên đây là một chút xấu xí và khi tôi có thời gian có rất nhiều công việc tôi muốn làm để cải thiện điều này, nhưng nó giải quyết vấn đề chia tách URL thành các tham số cần thiết. Nó khá gắn chặt với các yêu cầu cụ thể của tuyến đường này với mẫu url, Regex và Values ​​được mã hóa cứng mặc dù nó sẽ cho bạn một sự khởi đầu.

+0

Cảm ơn thông tin nhưng chúng tôi không thể sử dụng tham số catchall (*) trong phân đoạn chứa nhiều phần. –

+0

D'oh, tất nhiên rồi. Tôi đã đưa ra cùng một vấn đề một lúc trước – Chao

Các vấn đề liên quan