2

我試圖將ReturnUrl查詢字符串傳遞到我的登錄頁面。我有一個部分登錄視圖(有點像登錄框)和一個登錄視圖。現在,我有以下線在我的部分觀點:在ASP.NET MVC中編碼returnUrl查詢字符串

using (Html.BeginForm("Login" 
        , "Account" 
        , new { returnUrl=HttpUtility.UrlEncode(
             Request.QueryString["ReturnUrl"]) 
             ?? HttpUtility.UrlEncode(Request.Path) 
          } 
        , FormMethod.Post)) 

當我點擊我的部分觀點的提交按鈕(例如,從 http://localhost:12345/Product/1234/Product1),

我會被重定向到我的登錄頁面以下網址:

http://localhost:12345/Account/Login?returnUrl=%2FProduct%2F1234%2FProduct1 

但如果我登錄,我會看到一個http 400的響應,因爲頁面返回

http://localhost:12345/Account/%2fProduct%2f1234%2fproduct1。另外,如果我輸入了錯誤的憑證,則會導致returnUrl查詢字符串被再次編碼,因此每個%字符都會再次轉換爲%25

我應該提到如果我手動鍵入

http://localhost:12345/Account/Login?returnUrl=/Product/1234/Product1

(不進行編碼),並登錄,我成功地重定向到指定的路徑。

我想我錯過了一些明顯的東西。但無法找出什麼。

謝謝。

+1

是不是自動爲您完成的編碼?你不需要自己編碼。 – 2011-12-31 18:38:19

回答

3

您不需要時將其傳遞給Html.BeginForm()只需使用值,而不因爲它是由TagBuilder分配值所產生的<form>元素的action屬性時編碼對其進行編碼器編碼

@using(Html.BeginForm(
    "Login", 
    "Account", 
    new { returnUrl= Request.QueryString["ReturnUrl"] }, 
    FormMethod.Post)) { 

    @* form here *@  
} 

我已經刪除了空合併運算符和Request.Path,因爲如果ReturnUrl爲空,它將不會影響分配給action屬性的生成url(假設它是您路由中的可選參數,或者是您的可選屬性視圖模型)。

relevant source code in TagBuilder是(評論礦)

private void AppendAttributes(StringBuilder sb) { 
    foreach (var attribute in Attributes) { 
     string key = attribute.Key; 
     if (String.Equals(key, "id", StringComparison.Ordinal /* case-sensitive */) && String.IsNullOrEmpty(attribute.Value)) { 
      continue; // DevDiv Bugs #227595: don't output empty IDs 
     } 

     // --------------------------------------- 
     // Value will be HTML attribute encoded by 
     // the Encoder set for the application 
     // --------------------------------------- 
     string value = HttpUtility.HtmlAttributeEncode(attribute.Value); 
     sb.Append(' ') 
      .Append(key) 
      .Append("=\"") 
      .Append(value) 
      .Append('"'); 
    } 
} 
2

你可能想利用這一點避免你的返回URL編碼:

@Html.Raw([Your Return Url]) 

希望這有助於!

Matt