Asp.net
ASP.NET MVC 3 路由可能存在的錯誤?
通常我不會在問題中加上這樣的標題,但我很確定這是一個錯誤(或設計使然?)
我創建了一個全新的 ASP.NET MVC 3 Web 應用程序。
然後我去了 /Home/About 頁面。
該頁面的網址是:
然後我將 URL 更改為:
http://localhost:51419/(A(a))/Home/About
頁面有效嗎?查看路由值,controller = Home,Action = About。它忽略了第一部分?
如果我查看原始碼中的所有連結:
<link href="/(A(a))/Content/Site.css" rel="stylesheet" type="text/css" /> <script src="/(A(a))/Scripts/jquery-1.5.1.min.js" type="text/javascript"></script> <script src="/(A(a))/Scripts/modernizr-1.7.min.js" type="text/javascript"></script> <li><a href="/(A(a))/">Home</a></li> <li><a href="/(A(a))/Home/About">About</a></li>看看它是如何維護第一部分的?就像路由引擎認為它是域的一部分還是什麼?
我有一種感覺,這是一個正則表達式,因為如果我將 URL 更改為:
http://localhost:51419/(a(a))/Home/About
(例如將大寫的 A 更改為小寫)
它是 404 的。
任何人都可以對此有所了解嗎?這是一個錯誤還是設計使然?
這似乎與 ASP.NET 管道中的無 Cookie 會話有關。它在處理請求時去除 CookielessHelper.cs (System.Web.Security) 中的 URL 模式:
// This function is called for all requests -- it must be performant. // In the common case (i.e. value not present in the URI, it must not // look at the headers collection internal void RemoveCookielessValuesFromPath() { // See if the path contains "/(XXXXX)/" string path = _Context.Request.ClientFilePath.VirtualPathString; // Optimize for the common case where there is no cookie if (path.IndexOf('(') == -1) { return; } int endPos = path.LastIndexOf(")/", StringComparison.Ordinal); int startPos = (endPos > 2 ? path.LastIndexOf("/(", endPos - 1, endPos, StringComparison.Ordinal) : -1); if (startPos < 0) // pattern not found: common case, exit immediately return; if (_Headers == null) // Header should always be processed first GetCookielessValuesFromHeader(); // if the path contains a cookie, remove it if (IsValidHeader(path, startPos + 2, endPos)) { // only set _Headers if not already set if (_Headers == null) { _Headers = path.Substring(startPos + 2, endPos - startPos - 2); } // Rewrite the path path = path.Substring(0, startPos) + path.Substring(endPos+1); // remove cookie from ClientFilePath _Context.Request.ClientFilePath = VirtualPath.CreateAbsolute(path); // get and append query string to path if it exists string rawUrl = _Context.Request.RawUrl; int qsIndex = rawUrl.IndexOf('?'); if (qsIndex > -1) { path = path + rawUrl.Substring(qsIndex); } // remove cookie from RawUrl _Context.Request.RawUrl = path; if (!String.IsNullOrEmpty(_Headers)) { _Context.Request.ValidateCookielessHeaderIfRequiredByConfig(_Headers); // ensure that the path doesn't contain invalid chars _Context.Response.SetAppPathModifier("(" + _Headers + ")"); // For Cassini and scenarios where aspnet_filter.dll is not used, // HttpRequest.FilePath also needs to have the cookie removed. string filePath = _Context.Request.FilePath; string newFilePath = _Context.Response.RemoveAppPathModifier(filePath); if (!Object.ReferenceEquals(filePath, newFilePath)) { _Context.RewritePath(VirtualPath.CreateAbsolute(newFilePath), _Context.Request.PathInfoObject, null /*newQueryString*/, false /*setClientFilePath*/); } } } }您的模式與此匹配:
/////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Make sure sub-string if of the pattern: A(XXXX)N(XXXXX)P(XXXXX) and so on. static private bool IsValidHeader(string path, int startPos, int endPos) { if (endPos - startPos < 3) // Minimum len is "X()" return false; while (startPos <= endPos - 3) { // Each iteration deals with one "A(XXXX)" pattern if (path[startPos] < 'A' || path[startPos] > 'Z') // Make sure pattern starts with a capital letter return false; if (path[startPos + 1] != '(') // Make sure next char is '(' return false; startPos += 2; bool found = false; for (; startPos < endPos; startPos++) { // Find the ending ')' if (path[startPos] == ')') { // found it! startPos++; // Set position for the next pattern found = true; break; // Break out of this for-loop. } if (path[startPos] == '/') { // Can't contain path separaters return false; } } if (!found) { return false; // Ending ')' not found! } } if (startPos < endPos) // All chars consumed? return false; return true; }