2014-05-13 18 views
0

我使用AttributeRouting:http://attributerouting.net/爲Url.Action指定HTTP VERB?

如果我有兩個名稱相同的動作,但對於獲得路由比這一職位的路線不同,爲什麼Url.Action生成我的GET動作相匹配的URL,即使我的行動方法指向的是一個職位?

我試圖傳遞動詞作爲

Url.Action("CreateEdit", new { method = "POST" }) 

然而,這將返回其對應於POST字符串/enrollments/create代替/enrollments/createedit

我不希望這個工作,但嘗試了一些路由配置使用這種技術:

Url.Action("CreateEdit", new { HttpMethodConstraint = new HttpMethodConstraint("POST") }) 

但是這兩種不解決問題,而URL仍然是我的GET路線。

我已驗證我可以發佈到/enrollments/createedit的硬編碼網址,因此POST操作確實具有該路由,只是爲了排除POST操作的默認[POST]默認爲預期路由的可能性。

問題是,我通常會避免硬編碼的網址,並使用Url.Action或Html.BeginForm(這也表現出同樣的問題),使所有的網址將行動路線的。

下面是我如何定義我的行動:

[GET("create")] 
[GET("edit/{id:guid?}")]  
public ActionResult CreateEdit(Guid? id) 
... 

[POST] //default to "createedit" 
public ActionResult CreateEdit() 
... 

注意這個問題是不是爲了實際的請求,但生成的路線的URL。

你如何指示Url.Action它應該使用的路線從[POST],而不是GET。沒有重載需要約束或HTTP動詞?請注意,Html.BeginForm在生成動作URL屬性時表現出同樣的問題,這顯然是一種面向POST的方法。

它還如果我簡化我的行動路線(雖然以上是我的目標路線)不工作:

[GET("create")] 
public ActionResult CreateEdit() 
... 

[POST("createedit")] //default to "createedit" 
public ActionResult CreateEdit() 
... 

Url.Action("CreateEdit", new { method = "POST" })返回「/入學/製造」顯然是因爲method = 'POST'是不正確的方法指定Url.Action的所需路線。 有沒有辦法告訴Url.Action或Html.BeginForm指定POST路由是所需? BeginForm的方法PARAM影響method="post" HTML屬性,但動作屬性仍與錯/enrollments/create URL生成。我見過area="Admin"用於指定路由參數中的區域。是否有一些可以添加指定動詞的魔法屬性?如果沒有,那麼顯然沒有辦法一致地獲得正確的URL,如果我需要維護期望的路線,我可能需要重命名我的一個動作。我的希望是有一些航線價值,我可以類似添加到new { area = "SomeArea" }method = "POST"只是我猜測什麼可能工作。

請求管道方面路由約束,如果他們都是相同的路線,然後正常工作。因此,如果兩者都是[POST("creatededit")][GET("create"]那麼它會正常工作,因爲兩者的URL都是相同的,然後當實際的請求被做出時,由於HttpMethodContraint而由管道進行區分。

如果我使用參數,使路線不同,它的工作原理,但只有當我消除[GET("create")]

如果Url.Action沒有已知/支持/記錄的方式,採取的路線屬性,那麼答案可能僅僅是那Url.Action沒有任何方法讓你告訴它所需的VERB。

  • 如果有人問:有沒有辦法指定Url.Action的區域?
  • 答案很簡單:Url.Action("SomeAction", new { area ="SomeArea" })
  • 答案是不是:淤泥與周圍的路線,所以你不必在不同領域的兩個同名的動作(或任意數量的其他事情不解決問題)。
  • 答案不是:你不應該在不同的領域有相同的名字。 (這可能是一個有效的觀點,但對於處於絕對必須爲不同區域生成URL的情況下,它不會創建有用的資源)。

我不明白什麼是如此複雜。

我不問如何提出POST請求。我知道如何做到這一點,但我不打算將網址硬編碼到我的視圖中。這變成了維護噩夢。

我可以改變我的路線,如果我的老闆不是這樣設置在國有企業。所以我不能消除[GET(「創建」)]路線。

我可以重新命名的動作,像這樣解決:

[GET("create")] 
[GET("edit/{id:guid?}")]  
public ActionResult CreateEdit(Guid? id) 
... 

[POST("createedit")] 
public ActionResult CreateEditPost() 
... 

這是一個有點髒,但工程。它仍然沒有回答這個問題。

如果有一種方法來指定Url.Action的VERB,我認爲答案是一個有用的資源。也許不會像Url.Action("SomeAction", new { area ="SomeArea" })那麼多人,但它會記錄Url.Action的一個特徵,對我來說這一直是難以捉摸的。也許它不支持它。也許我需要深入研究源代碼。

+0

點擊瀏覽器中的鏈接永遠是一個GET。從瀏覽器發佈的唯一方法是使用POST方法提交表單。使用哪個動詞不會發布到URL本身。 – vcsjones

+0

Url.Action可以用於POST以及GET。 BeginForm也會出現同樣的問題。這是一個URL生成問題,而不是請求問題。 BeginForm使用相同的流程來創建動作屬性URL Url.Action。兩者都表現出同樣的問題。這不是關於請求,而是關於URL。 – AaronLS

+1

「這是一個URL生成問題,而不是請求問題」我完全不同意。這可能是因爲生成的URL與您的POST路由不匹配,但URL是一個URL。他們自己並不指出要使用什麼動詞。這就是使用決定的URL的機制,例如表單與鏈接。 – vcsjones

回答

2

我在我原來的答案愚蠢。我沒有真正想到它,可能回答得太快。這是什麼歸結爲:

Url.Action與控制器/動作風格路由相當固有。當有兩個匹配的動作(一個是GET版本,另一個是POST的重載)時,URL 應該是,因此返回GET或真正的第一個版本。請參閱AttributeRouting,通過讓您自定義面向外的URL,但只是在內部,Url.Action只是試圖找到一條路線,可以讓您執行所請求的操作。一旦找到匹配,它就會認爲這足夠好了,特別是在MVC5之前,它應該是。作爲第一級公民,MVC5引入了屬性路由,但是從我所見到的情況來看,這個邊緣案例(其中同一個動作的GET和POST版本具有不同的URL並且特別需要POST版本)具有沒有被覆蓋。

這麼說,我看到一對夫婦可能的解決辦法的:

  1. 使用不同的動作名稱。如果您的POST動作被命名爲CreateEditPost,那麼您可以非常輕鬆地執行Url.Action("CreateEditPost")並獲取正確的URL。由於您的路線不受操作名稱的直接影響,因此它的名稱並不重要。

  2. 使用命名路線。如果您爲路線命名,那麼您可以使用Url.RouteUrl,並請求準確的路線。例如:

    [POST("createedit", RouteName = "CreateEditPost")] 
    public ActionResult CreateEdit() 
    { 
        ... 
    } 
    

    然後:

    @Url.RouteUrl("CreateEditPost") 
    
+0

「是的,你可以在Url.Action中指定方法爲post」這是如何完成的?你在哪裏傳入Url.Action?是'new {method = 「POST」}'這樣做的正確方法?這只是我的猜測而已。 – AaronLS

+0

並感謝解決這個問題。我確實瞭解我使用URL的環境很重要,因此它用於POST請求。 – AaronLS

+0

對不起。我最初的回答非常糟糕。我沒有真正花時間,我應該與它並且做出我不應該有的假設。看到我編輯的答案。 –

相關問題