在ASP.NET MVC中编码returnUrl查询字符串

时间:2011-12-31 18:32:47

标签: asp.net-mvc-3 authentication query-string urlencode returnurl

我正在尝试将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

(没有编码)并登录,我已成功重定向到指定的路径。

我想我错过了一些明显的东西。但是找不到什么。

感谢。

2 个答案:

答案 0 :(得分:3)

当您将其传递给Html.BeginForm()时,您无需对其进行编码只需使用该值而不对其进行编码,因为在将值分配给TagBuilder时由action进行编码生成的<form>元素的属性

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

    @* form here *@    
}

我已经删除了null-coalescing运算符和Request.Path,因为如果ReturnUrl为null,则对分配给action属性的生成的url无关紧要(假设它是路由中的可选参数,或ViewModel上的可选属性。)

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('"');
    } 
}

答案 1 :(得分:2)

您可能希望使用此功能来避免对返回的Url进行编码:

@Html.Raw([Your Return Url])

希望这有帮助!

马特