1

我在我的項目中使用RouteAttributes,他們正常工作,除了在這種情況下: 我有兩個類似的操作,一個接受兩個int參數,另一個只接受一個。RedirectToAction生成錯誤的URL(查詢字符串參數,而不是routedata參數)

第一個接受兩個參數並使用它們加載一個對象並將其傳遞給View; 第二個只是試圖找到第二個變量的默認值,並重定向到第一個操作,傳遞兩個變量。

問題是,在ActionResultExample(int idVar1),我預計將重定向到ControllerExample/Edit/idVar1/Brands/idVar2;但是我被重定向到ControllerExample/Edit/idVar1/Brands?idVar2=idVar2。 這當然會生成一個無限重定向循環。

下面是示例代碼:

[Route("ControllerExample/Edit/{idVar1}/Brands/{idVar2}")] 
    public ActionResult ActionResultExample(int idVar1, int idVar2) 
    { 
     var objectForView= ObjectController.Get(idVar1, idVar2); 

     return View("ActionResultExample", objectForView); 
    } 

    [Route("ControllerExample/Edit/{idVar1}/Brands")] 
    public ActionResult ActionResultExample(int idVar1) 
    { 
     ... 
     var idVar2 = getDefaultVar2(); 
     return RedirectToAction("ActionResultExample", //redirects to ControllerExample/Edit/idVar1/Brands?idVar2=idVar2 instead of ControllerExample/Edit/idVar1/Brands/idVar2 
      new {idVar1= idVar1, idVar2 = idVar2 }); 
    } 

回答

3

您可以用1路和1的操作方法做到這一點:

在這裏,我們使用?表示最後一個URL參數是可選的,我們在action方法中使用默認方法參數做同樣的事情。

[Route("ControllerExample/Edit/{idVar1}/Brands/{idVar2?}")] 
public ActionResult ActionResultExample(int idVar1, int? idVar2 = null) 
{ 
    var idVar2Int = !idVar2.HasValue ? getDefaultVar2() : idVar2.Value; 
    var objectForView= ObjectController.Get(idVar1, idVar2Int); 

    return View("ActionResultExample", objectForView); 
} 

如果你真的想有這樣的2種獨立的動作方式,您可能需要升級到5.1 System.Web.Mvc(可通過的NuGet來完成)。然後,您可以使用RouteAttribute上的Order參數。不過,你也應該rename at least one of the action methods because in MVC, you should not have 2 GET overloads with the same name

[Route("ControllerExample/Edit/{idVar1}/Brands/{idVar2}", Order = 1)] 
public ActionResult ActionResultExample(int idVar1, int idVar2) 
{ 
    var objectForView= ObjectController.Get(idVar1, idVar2); 

    return View("ActionResultExample", objectForView); 
} 

[Route("ControllerExample/Edit/{idVar1}/Brands", Order = 2)] 
public ActionResult ActionResultExampleWithoutDefaults(int idVar1) 
{ 
    ... 
    var idVar2 = getDefaultVar2(); 
    return RedirectToAction("ActionResultExample", //redirects to ControllerExample/Edit/idVar1/Brands?idVar2=idVar2 instead of ControllerExample/Edit/idVar1/Brands/idVar2 
     new {idVar1= idVar1, idVar2 = idVar2 }); 
} 
+0

我已經使用了第一種解決方案;我只是想通過兩種不同的行動將它分開來看起來更清楚。 這一個看起來像我最完整的答案。謝謝! –

+0

如果將第二個動作重命名爲「ActionResultExample」之外的其他動作,它會起作用嗎?從技術上講,你的重載對於MVC控制器來說是非法的(參見我的答案中的鏈接) – danludwig

0

我沒有用RouteAttribute還,但它看起來像一個順序的問題。

檢查http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2#order

做路由的老辦法。\ App_Start \ RouteConfig.cs你必須爲了你的路線的正確途徑。如果一切都失敗了,最後的路線被使用了。

因此,使用RouteAttribute,您需要設置路由順序。也許這可能與RouteAttribute可能不是。如果不是這樣,你將不得不回到舊的做事方式。

0

不支持對所有參數使用相同的名稱,因爲ASP.NET MVC無法區分是否要使用idVar1和idVar2作爲路由值或使用idVar2作爲查詢字符串值。 的代碼更改爲第二種方法使用另一條路線值名稱:

[Route("ControllerExample/Edit/{idVar3}/Brands")] 
    public ActionResult ActionResultExample(int idVar3) 
    { 
     var idVar2 = 100; 
     return RedirectToAction("ActionResultExample", 
      new { idVar1 = idVar3, idVar2 = idVar2 }); 
    } 

這應該按預期工作。

但是,如果您僅使用2種方法爲idVar2提供默認值,請注意您並不需要。你可以這樣做:

[Route("ControllerExample/Edit/{idVar1}/Brands/{idVar2=100}")] 

要設置的100 缺省值或在控制器上使用可空類型:

[Route("ControllerExample/Edit/{idVar1}/Brands/{idVar2?}")] 
public ActionResult ActionResultExample(int idVar1, int? idVar2) 

注意,routevalue名稱與路由屬性問號結束設置它是一個可選參數。

相關問題