Định tuyến: Yêu cầu hành động hiện tại […] không rõ ràng giữa các phương thức hành động sau


100

Tôi có một Chế độ xem được gọi là Browse.chtmlnơi người dùng có thể nhập cụm từ tìm kiếm hoặc để trống cụm từ tìm kiếm. Khi nhập cụm từ tìm kiếm, tôi muốn chuyển hướng trang đến http://localhost:62019/Gallery/Browse/{Searchterm} và khi không có gì được nhập, tôi muốn hướng trình duyệt đến http://localhost:62019/Gallery/Browse/Start/Here.

Khi tôi thử điều này, tôi gặp lỗi:

Yêu cầu hiện tại cho hành động 'Duyệt qua' trên loại bộ điều khiển 'GalleryController' là không rõ ràng giữa các phương thức hành động sau: System.Web.Mvc.ActionResult Browse (System.String) trên loại AutoApp_MVC.Controllers.GalleryController System.Web.Mvc.ActionResult Browse (Int32, System.String) trên loại AutoApp_MVC.Controllers.GalleryController

Mọi thứ tôi đang làm với MVC là lần đầu tiên. Tôi không chắc chắn những gì khác để thử vào thời điểm này.

public ActionResult Browse(string id)
{
    var summaries = /* search using id as search term */
    return View(summaries);
}

public ActionResult Browse(string name1, string name2)
{
    var summaries = /* default list when nothing entered */
    return View(summaries);
}

Tôi cũng có cái này trong Global.asax.cs:

    routes.MapRoute(
         "StartBrowse",
         "Gallery/Browse/{s1}/{s2}",
         new
         {
             controller = "Gallery",
             action = "Browse",
             s1 = UrlParameter.Optional,
             s2 = UrlParameter.Optional
         });



    routes.MapRoute(
         "ActualBrowse",
         "Gallery/Browse/{searchterm}",
         new
         {
             controller = "Gallery",
             action = "Browse",
             searchterm=UrlParameter.Optional
         });

Câu trả lời:


161

Bạn chỉ có thể có tối đa 2 phương thức hành động có cùng tên trên bộ điều khiển và để làm được điều đó, 1 phương thức phải có [HttpPost]và phương thức còn lại phải có [HttpGet].

Vì cả hai phương thức của bạn đều là GET, bạn nên đổi tên một trong các phương thức hành động hoặc chuyển nó sang một bộ điều khiển khác.

Mặc dù 2 phương thức Duyệt của bạn là quá tải C # hợp lệ, bộ chọn phương thức hành động MVC không thể tìm ra phương thức nào sẽ gọi. Nó sẽ cố gắng so khớp một tuyến đường với phương thức (hoặc ngược lại) và thuật ngữ này không được gõ mạnh.

Bạn có thể thực hiện những gì bạn muốn bằng cách sử dụng các tuyến tùy chỉnh trỏ đến các phương pháp hành động khác nhau:

... trong Global.asax

routes.MapRoute( // this route must be declared first, before the one below it
     "StartBrowse",
     "Gallery/Browse/Start/Here",
     new
     {
         controller = "Gallery",
         action = "StartBrowse",
     });

routes.MapRoute(
     "ActualBrowse",
     "Gallery/Browse/{searchterm}",
     new
     {
         controller = "Gallery",
         action = "Browse",
         searchterm = UrlParameter.Optional
     });

... và trong bộ điều khiển ...

public ActionResult Browse(string id)
{
    var summaries = /* search using id as search term */
    return View(summaries);
}

public ActionResult StartBrowse()
{
    var summaries = /* default list when nothing entered */
    return View(summaries);
}

Bạn cũng có thể giữ cho các phương thức hành động được đặt tên giống nhau trong bộ điều khiển , bằng cách áp dụng một [ActionName]thuộc tính cho một để phân biệt nó. Sử dụng cùng Global.asax như trên, bộ điều khiển của bạn sau đó sẽ trông giống như sau:

public ActionResult Browse(string id)
{
    var summaries = /* search using id as search term */
    return View(summaries);
}

[ActionName("StartBrowse")]
public ActionResult Browse()
{
    var summaries = /* default list when nothing entered */
    return View(summaries);
}

Vì vậy, tôi sẽ cần tạo một chế độ xem mới trong ví dụ của bạn ở trên? Có vẻ như không hữu ích khi sử dụng thẻ ActionName, vì tôi nghĩ rằng điều đó chỉ có tác dụng đổi tên tất cả các phương thức hành động (không thể giữ cả hai cùng một lúc). Thật tốt khi biết cách MVC hoạt động. Cảm ơn.
Dave

6
Không, bạn không cần tạo bất kỳ chế độ xem mới nào. Bạn vẫn có thể sử dụng lại cùng một chế độ xem cho cả hai hành động. Chỉ cần chuyển tên chế độ xem làm đối số đầu tiên choreturn View("Browse", summaries);
danludwig

Quá tải có được đưa vào một số bản phát hành trong tương lai không? Sửa đổi các tuyến đường là công việc bổ sung và cần phải bảo trì bổ sung khi thực hiện các thay đổi.
Old Geezer

@OldGeezer có thể không, vì có một cách giải quyết (ở trên) và vì các phương thức hành động quá tải trong bộ điều khiển thường không phải là một ý tưởng hay.
danludwig

4

Tôi không biết câu hỏi được đặt ra khi nào thì giải pháp này có sẵn nhưng bạn có thể sử dụng:

Request.QueryString["key"]

Vì vậy, điều này sẽ hoạt động tốt cho vấn đề của bạn:

[HttpGet]
public ActionResult Browse()
{
    if( Request.QueryString["id"] != null )        
        var summaries = /* search using id as search term */
    else /*assuming you don't have any more option*/
        var summaries = /* default list when nothing entered */

    return View(summaries);
} 

2

Thêm mã sau vào RouteConfig.cs trước Tuyến đường mặc định

routes.MapMvcAttributeRoutes();

Và thêm các thuộc tính tuyến đường trong bộ điều khiển như:

    [Route("Cars/deteals/{id:int}")]
    public ContentResult deteals(int id)
    {
        return Content("<b>Cars ID Is " + id + "</b>");
    }

    [Route("Cars/deteals/{name}")]
    public  ContentResult deteals(string name)
    {
        return Content("<b>Car name Is " + name + "</b>");

    }

1

Tôi nghĩ rằng điểm đang được thực hiện là bạn không cần phải kiểm tra ngầm các tham số chuỗi truy vấn bằng cách sử dụng lớp yêu cầu.

MVC thực hiện ánh xạ cho bạn (trừ khi bạn đã thực hiện những thay đổi nghiêm trọng trong các tuyến MVC của mình).

Do đó, một đường dẫn liên kết hành động của

/umbraco/Surface/LoginSurface/Logout?DestinationUrl=/home/

sẽ tự động có sẵn cho bộ điều khiển (bề mặt) của bạn với tham số được xác định:

public ActionResult Logout(string DestinationUrl)

MVC thực hiện công việc.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.