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

发布于 2024-12-23 17:46:44 字数 1103 浏览 5 评论 0原文

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

(不带编码)并登录,我会成功重定向到指定路径。

我想我错过了一些明显的东西。但又查不出是什么。

谢谢。

I'm trying to pass ReturnUrl query string to my login page. I have a partial Login view (kind of like a login box) and a login view. Right now, I have the following line in my partial view:

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

When I click on my partial view's submit button(e.g. from
http://localhost:12345/Product/1234/Product1),

I'll get redirected to my login page with the following url:

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

But if I log on, I'll see an http 400 response, because the page is returning to

http://localhost:12345/Account/%2fProduct%2f1234%2fproduct1.

Also, if I type in the wrong credentials, I cause the returnUrl query string to be encoded again thus every % character is converted to %25 again!

I should mention if I manually type in

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

(without encoding) and log in, I'm successfully redirected to the specified path.

I guess I'm missing something obvious. But couldn't find out what.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

谜泪 2024-12-30 17:46:44

当您将其传递给 Html.BeginForm() 时,无需对其进行编码 只需使用该值而不对其进行编码,因为在分配值时它是由 TagBuilder 编码的对于生成的

元素的 action 属性,

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

    @* form here *@    
}

我也删除了空合并运算符和 Request.Path 因为 if <代码>返回网址为 null,这对于分配给 action 属性的生成 url 来说并不重要(假设它是路由中的可选参数,或者 ViewModel 上的可选属性)。

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

You don't need to encode it when you pass it to Html.BeginForm() Just use the value without encoding it as it is encoded by the TagBuilder when assigning the value to the action attribute of the generated <form> element

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

    @* form here *@    
}

I've removed the null-coalescing operator and Request.Path too because if ReturnUrl is null, it's not going to matter to the generated url assigned to the action attribute (assuming it's an optional parameter in your routing, or an optional property on your ViewModel).

The relevant source code in TagBuilder is (comment mine)

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('"');
    } 
}
飘过的浮云 2024-12-30 17:46:44

您可能想使用它来避免对返回网址进行编码:

@Html.Raw([Your Return Url])

希望这会有所帮助!

马特

You may want to use this to avoid encoding of your return Url:

@Html.Raw([Your Return Url])

Hope this helps!

Matt

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文