Uri ToString()方法解码Uri查询 - c#

在我的WebAPI项目中,重定向存在一些问题。这是因为Uri.ToString()方法的行为表现为“防御性”,换句话说,一旦调用被提及方法,他便会解码查询字符串的安全部分。

考虑以下失败的单元测试:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace UriTest
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            // Arrange
            const string expectedUrlRaw = 
                "http://localhost/abc?proxy=http%3A%2F%2Ftarget.nl%3Fparam1%3Dvalue1%26param2%3Dvalue2";
            const string expectedUrlInHttpsRaw =
                "https://localhost/abc?proxy=http%3A%2F%2Ftarget.nl%3Fparam1%3Dvalue1%26param2%3Dvalue2";

            Uri expectedUri = new Uri(expectedUrlRaw);
            Uri expectedUriInHttps = new Uri(expectedUrlInHttpsRaw);

            // Act
            string returnsUriInHttpsRaw = expectedUri.ToHttps().ToString();

            // Assert
            Assert.AreEqual(expectedUrlInHttpsRaw, returnsUriInHttpsRaw);
        }
    }
    public static class StringExtensions
    {
        public static Uri ToHttps(this Uri uri)
        {
            UriBuilder uriBuilder = new UriBuilder(uri);
            uriBuilder.Scheme = Uri.UriSchemeHttps;
            uriBuilder.Port = 443;
            return uriBuilder.Uri;
        }
    }
}

现在,由于无法控制Uri属性,因此无法通过构造自己的链接来修改此行为。
在我的控制器中,我确实以以下方式响应get消息以重定向呼叫:

HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Found);
            response.Headers.Location = // my Uri object

这可以正常工作到一定程度。如果我的重定向Uri包含一个包含编码链接的查询,它将返回错误的结果。 (这可能是因为Headers.Location是通过对该属性调用ToString来读取的。

有谁对如何解决这个问题有想法?

谢谢

参考方案

Uri.ToString()确实解码URL编码的序列。 (例如%20 =>空格)。
在.net框架的不同版本之间,行为也会发生变化。

简而言之,不要使用Uri.ToString(),而要使用Uri.AbsoluteUri或Uri.OriginalString。

请参阅以下文章进行深入调查
https://dhvik.blogspot.com/2019/12/uritostring-automatically-decodes-url.html

java.net.URI.create异常 - java

java.net.URI.create("http://adserver.adtech.de/adlink|3.0") 抛出java.net.URISyntaxException: Illegal character in path at index 32: http://adserver.adtech.de/adlink|3.0 虽然n…

不会将toString()方法中的super关键字隐式转换为super.toString() - java

我有以下两个类,如下所示。为了简单起见,仅显示toString重写的方法。 public class Circle { @Override public String toString() { return "Circle"; } } public class Cylinder extends Circle { @Override pub…

对数字变量使用'.ToString()' - c#

将数值转换为.ToString()时省略string有什么缺点吗?int i = 1234; string s; // Instead of s = "i is " + i.ToString(); // Writing s = "i is " + i; 参考方案 在这种情况下没有什么区别。"Count: &#…

ASP.NET Web API 2中AuthorizeAttribute发生了什么变化? - c#

我已经将项目和一组单元测试从ASP.NET Web API升级到ASP.NET Web API 2。我们将自定义DelegatingHandler用于自定义身份验证机制。它将Thread.CurrentPrincipal和HttpContext.Current.User设置为适当的System.Security.Claims.ClaimsPrincipal。…

如何从uri确定文件的文件扩展名 - java

假设给我一个URI,并且我想查找返回的文件的文件扩展名,那么在Java中该做什么。例如,位于http://www.daml.org/2001/08/baseball/baseball-ont的文件是http://www.daml.org/2001/08/baseball/baseball-ont.owl当我做 URI uri = new URI(addres…