これを解決する方法は、基本となるサーバー変数を調べることです。 URL
変数には、がデコードされた値が含まれています。 QUERY_STRING
変数には、まだエンコードされたクエリが含まれています。 のエンコードは、URL
の部分には、/
などのオリジナルの形式が含まれているため、この部分を元に戻すことはできません。盲目的にエンコードすれば、不要な%2f
値が得られます。しかし、問題のあるケースを見つけることができます:
private static readonly Regex simpleUrlPath = new Regex("^[-a-zA-Z0-9_/]*$", RegexOptions.Compiled);
private static readonly char[] segmentsSplitChars = { '/' };
// ^^^ avoids lots of gen-0 arrays being created when calling .Split
public static Uri GetRealUrl(this HttpRequest request)
{
if (request == null) throw new ArgumentNullException("request");
var baseUri = request.Url; // use this primarily to avoid needing to process the protocol/authority
try
{
var vars = request.ServerVariables;
var url = vars["URL"];
if (string.IsNullOrEmpty(url) || simpleUrlPath.IsMatch(url)) return baseUri; // nothing to do - looks simple enough even for IIS
var query = vars["QUERY_STRING"];
// here's the thing: url contains *decoded* values; query contains *encoded* values
// loop over the segments, encoding each separately
var sb = new StringBuilder(url.Length * 2); // allow double to be pessimistic; we already expect trouble
var segments = url.Split(segmentsSplitChars);
foreach (var segment in segments)
{
if (segment.Length == 0)
{
if(sb.Length != 0) sb.Append('/');
}
else if (simpleUrlPath.IsMatch(segment))
{
sb.Append('/').Append(segment);
}
else
{
sb.Append('/').Append(HttpUtility.UrlEncode(segment));
}
}
if (!string.IsNullOrEmpty(query)) sb.Append('?').Append(query); // query is fine; nothing needing
return new Uri(baseUri, sb.ToString());
}
catch (Exception ex)
{ // if something unexpected happens, default to the broken ASP.NET handling
GlobalApplication.LogException(ex);
return baseUri;
}
}
考えている間、StackOverflowはスニペットサイトではなく、あなたが特定するもの、つまりブログを投稿する場所ではありません。質問と回答のタイムスタンプは、あなたがここに来て両方を投稿できる状態になったことを示しています。本当に助けが必要な質問のみ投稿してください。コミュニティーと情報を共有するより適切な方法があります。 –
@Chris [自己回答は常に受け入れられています](http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/)。尋ねる*の一部として*答えることを可能にする決定はまた非常に故意に取られた - そのコードは非常に意図的に加えられた。私は知っている:私はそのチームで働いています。さらに、このコードは、[この問題によって引き起こされるスタックオーバーフローのバグ](http://meta.stackexchange.com/q/169356)を修正した後で、ユーザーが「メタ」について要求する要求の一部として共有されています。 Dr:あなた自身の質問に答えることは、質疑応答が適切に形成され、適切である限り、明示的にOKです。 –