Asp.net

ASP.NET MVC 3 路由可能存在的錯誤?

  • February 9, 2012

通常我不會在問題中加上這樣的標題,但我很確定這是一個錯誤(或設計使然?)

我創建了一個全新的 ASP.NET MVC 3 Web 應用程序。

然後我去了 /Home/About 頁面。

該頁面的網址是:

http://localhost:51419/首頁/關於

然後我將 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; 
   }

引用自:https://stackoverflow.com/questions/9089745