2011-08-04 38 views
29

Tôi đang cố gắng để thiết lập một lộ trình tùy chỉnh trong MVC để có một URL từ một hệ thống khác trong các định dạng sau:Làm cách nào để định tuyến URL bằng chuỗi truy vấn trong ASP.NET MVC?

../ABC/ABC01?Key=123&Group=456

Các 01 sau khi ABC thứ hai là một số bước này sẽ thay đổi và Key và các tham số nhóm sẽ thay đổi. Tôi cần phải định tuyến này đến một hành động trong một bộ điều khiển với các phím số bước và nhóm như paramters. Tôi đã cố gắng đoạn mã sau tuy nhiên nó ném một ngoại lệ:

Code:

routes.MapRoute(
    "OpenCase", 
    "ABC/ABC{stepNo}?Key={key}&Group={group}", 
    new {controller = "ABC1", action = "OpenCase"} 
); 

Ngoại lệ:

`The route URL cannot start with a '/' or '~' character and it cannot contain a '?' character.` 

Trả lời

35

Bạn không thể bao gồm các chuỗi truy vấn trong các tuyến đường. Hãy thử với một con đường như thế này:

routes.MapRoute("OpenCase", "ABC/ABC{stepNo}", 
    new { controller = "ABC1", action = "OpenCase" }); 

Sau đó, trên bộ điều khiển của bạn thêm một phương pháp như thế này:

public class ABC1 : Controller 
{ 
    public ActionResult OpenCase(string stepno, string key, string group) 
    { 
     // do stuff here 
     return View(); 
    }   
} 

ASP.NET MVC sẽ tự động lập bản đồ các tham số chuỗi truy vấn đến các thông số trong phương pháp trong bộ điều khiển.

4

Khi xác định tuyến đường, bạn có thể không sử dụng một / vào đầu của đường dẫn:

routes.MapRoute("OpenCase", 
    "/ABC/{controller}/{key}/{group}", <-- Bad; see/at beginning 
    new { controller = "", action = "OpenCase" }, 
    new { key = @"\d+", group = @"\d+" } 
    ); 

routes.MapRoute("OpenCase", 
    "ABC/{controller}/{key}/{group}", <-- Good; No/at beginning 
    new { controller = "", action = "OpenCase" }, 
    new { key = @"\d+", group = @"\d+" } 
    ); 

Hãy thử điều này:

routes.MapRoute("OpenCase", 
    "ABC/{controller}/{key}/{group}", 
    new { controller = "", action = "OpenCase" }, 
    new { key = @"\d+", group = @"\d+" } 
    ); 

Sau đó, hành động của bạn sẽ giống như sau:

public ActionResult OpenCase(int key, int group) 
{ 
    //do stuff here 
} 

Có vẻ như bạn đang đặt cùng nhau stepNo và " ABC "để có bộ điều khiển là ABC1. Đó là lý do tại sao tôi đã thay thế phần URL đó bằng {controller}.

Vì bạn cũng có lộ trình xác định 'khóa' và 'nhóm', tuyến đường trên cũng sẽ bắt được URL ban đầu của bạn và gửi URL đó đến hành động.

1

Không có lý do gì để sử dụng định tuyến dựa trên chuỗi truy vấn trong dự án ASP.NET MVC mới. Nó có thể hữu ích cho dự án cũ đã được chuyển đổi từ dự án ASP.NET cổ điển và bạn muốn giữ lại các URL.

Một giải pháp có thể là định tuyến thuộc tính.

Một giải pháp khác có thể ở writting định tuyến tùy chỉnh bằng cách bắt nguồn từ RouteBase:

public class MyOldClassicAspRouting : RouteBase 
{ 

    public override RouteData GetRouteData(HttpContextBase httpContext) 
    { 
    if (httpContext.Request.Headers == null) //for unittest 
     return null; 

    var queryString = httpContext.Request.QueryString; 

    //add your logic here based on querystring 
    RouteData routeData = new RouteData(this, new MvcRouteHandler()); 
    routeData.Values.Add("controller", "..."); 
    routeData.Values.Add("action", "..."); 
    } 

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) 
    { 
    //Implement your formating Url formating here 
    return null; 
    } 
} 

Và đăng ký định tuyến lớp tùy chỉnh của bạn

đối số chuỗi
public static void RegisterRoutes(RouteCollection routes) 
{ 
    ... 

    routes.Add(new MyOldClassicAspRouting()); 
} 
0

Các truy vấn thường là đặc trưng của bộ điều khiển đó và điều đó logic ứng dụng cụ thể.

Vì vậy, sẽ tốt hơn nếu điều này không được viết trong quy tắc tuyến đường, nói chung.

Bạn có thể nhúng phát hiện chuỗi truy vấn trên đối số hành động theo cách sau.

Tôi nghĩ rằng tốt hơn nên có một Bộ điều khiển để xử lý StepNo.

public class ABC : Controller 
{ 
    public ActionResult OpenCase(OpenCaseArguments arg) 
    { 
     // do stuff here 
     // use arg.StepNo, arg.Key and arg.Group as You need 
     return View(); 
    }   
} 

public class OpenCaseArguments 
{ 
    private string _id; 
    public string id 
    { 
     get 
     { 
      return _id; 
     } 

     set 
     { 
      _id = value; // keep original value; 
      ParseQueryString(value); 
     } 
    } 

    public string StepNo { get; set; } 
    public string Key { get; set; } 
    public string Group { get; set; } 

    private void ParseQueryString(string qs) 
    { 
     var n = qs.IndexOf('?'); 
     if (n < 0) return; 
     StepNo = qs.Substring(0, n); // extract the first part eg. {stepNo} 
     NameValueCollection parms = HttpUtility.ParseQueryString(qs.Substring(n + 1)); 
     if (parms.Get("Key") != null) Key = parms.Get("Key"); 
     if (parms.Get("Group") != null) Group = parms.Get("Group"); 
    } 

} 

Chỉ định ModelBinder {id} vào trường id của OpenCaseArguments. Phương thức thiết lập xử lý logic tách truy vấn.

Và tiếp tục định tuyến theo cách này. Định tuyến lưu ý nhận chuỗi truy vấn của bạn trong đối số id.

routes.MapRoute(
    "OpenCase", 
    "ABC/OpenCase/{id}", 
    new {controller = "ABC", action = "OpenCase"} 
); 

Tôi đã sử dụng phương pháp này để nhận nhiều giá trị khóa của trường trên hành động của bộ điều khiển.

+0

Lưu ý rằng MVC sẽ tự động phân tích chuỗi truy vấn bằng 'QueryStringValueProvider'. Tất cả những gì bạn cần làm để có được các giá trị này trong một phương thức hành động là thêm các tham số có cùng tên như các chuỗi chuỗi truy vấn vào phương thức hoặc mô hình hành động. Không cần phải xây dựng trình phân tích chuỗi truy vấn của riêng bạn cho việc này. – NightOwl888

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