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