Кодирование строки запроса 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),

Я буду перенаправлен на мою страницу входа со следующим URL:

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 ответа

Решение

Вам не нужно кодировать его, когда вы передаете его Html.BeginForm() Просто используйте значение без его кодирования, так как оно кодируется TagBuilder при назначении значения action атрибут сгенерированного <form> элемент

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

    @* form here *@    
}

Я удалил нуль-объединяющий оператор и Request.Path тоже потому что если ReturnUrl является нулевым, это не будет иметь значения для сгенерированного URL, назначенного для action атрибут (при условии, что это необязательный параметр в вашей маршрутизации или необязательное свойство в вашей 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('"');
    } 
}

Вы можете использовать это, чтобы избежать кодирования вашего возвращаемого URL:

@Html.Raw([Your Return Url])

Надеюсь это поможет!

Matt

Другие вопросы по тегам