2012-02-01 43 views
14

Thông thường tôi sẽ không đặt một tiêu đề như thế này trong câu hỏi, nhưng tôi khá chắc chắn đó là lỗi (hoặc theo thiết kế?)Lỗi có thể với định tuyến ASP.NET MVC 3?

Tôi đã tạo một ứng dụng ASP.NET MVC 3 Web hoàn toàn mới.

Sau đó, tôi đã truy cập trang/Trang chủ/Giới thiệu.

URL cho trang này là:

http://localhost:51419/Home/About

Sau đó, tôi đã thay đổi địa chỉ URL này:

http://localhost:51419/(A(a))/Home/About

Và trang làm việc? Nhìn vào các giá trị tuyến đường, controller = Home, Action = About. Nó bị bỏ qua phần đầu tiên?

Và nếu tôi nhìn vào tất cả các liên kết trong nguồn:

<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> 

Xem cách nó duy trì một phần đầu tiên? Nó giống như các công cụ định tuyến nghĩ rằng đó là một phần của tên miền hoặc một cái gì đó?

Tôi đã có một cảm giác đó là một regex điều , bởi vì nếu tôi thay đổi địa chỉ URL:

http://localhost:51419/(a(a))/Home/About

(ví dụ thay đổi chữ hoa A đến chữ thường)

Nó 404 của.

Có ai có thể làm sáng tỏ điều này không? Đây có phải là lỗi hoặc do thiết kế không?

+2

Thật hiếm khi một bài đăng có "lỗi có thể xảy ra" trong tựa đề được bầu chọn xứng đáng, IMO. Cái này là. –

+1

@AndrewBarber - tôi biết. :) Đó là fluke tinh khiết tôi đã xem qua này. Google đã lập chỉ mục một số URL lạ với các hướng dẫn trong chúng, gây ra bởi một lỗi trong ứng dụng của chúng tôi. – RPM1984

Trả lời

5

Điều này dường như có liên quan đến Phiên làm việc vô dụng trong đường dẫn ASP.NET. Nó dải rằng mẫu URL bên CookielessHelper.cs (System.Web.Security) trong khi xử lý yêu cầu:

// 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*/); 
       } 
      } 
     } 
    } 

mẫu của bạn phù hợp này:

/////////////////////////////////////////////////////////////////////// 
    /////////////////////////////////////////////////////////////////////// 
    // 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; 
    } 
+0

Hmm, sooo ... đây có phải là lỗi không? Không chắc chắn nếu nó là một điều cốt lõi ASP.NET, như mã đó có ý nghĩa. NHƯNG, các công cụ định tuyến ASP.NET (tốt, MVC định tuyến một ít nhất), IMO không nên chấp nhận rằng như là một phần của tuyến đường (ví dụ như nó không nên phù hợp). Tôi có nên nâng cao điều này với MS? – RPM1984

+0

@ RPM1984 Không, rõ ràng là "theo thiết kế" là cách họ theo dõi người dùng nào đã đăng nhập khi cookie không khả dụng. Chỉ cần giả vờ bạn không bao giờ nhận thấy điều này và mọi thứ sẽ ổn. –

+0

@RobertLevy - tôi không thể bỏ qua nó. Điều này thực sự xảy ra với tôi với một ứng dụng trực tiếp. Như tôi đã nói trong nhận xét, google đang lập chỉ mục một số URL lạ khớp với mẫu này. Vì vậy, bởi vì MVC chấp nhận chúng như là các tuyến hợp lệ, chúng đơn giản là nhận được các bộ điều khiển của tôi sau đó sẽ chết sau này. Khi thực sự họ nên được 404'ed từ nhận được đi. URL cũng là ngẫu nhiên, vì vậy tôi không thể dễ dàng viết lại tại chỗ. Công bằng đủ điều này là "bởi thiết kế" cho ASP.NET, nhưng tôi nghĩ rằng đây là một lỗi trong MVC. KHÔNG nên chấp nhận điều này như một tuyến đường. – RPM1984

-1

Tôi đồng ý với phân tích @pjumble, nhưng không phải để giải pháp của anh ấy.
Vô hiệu hóa xác thực không cần thiết cho việc xác thực biểu mẫu hoặc xác thực ẩn danh.

Điều này sẽ ngăn người dùng bị vô hiệu hóa cookie để xác thực. Nhưng những người quan tâm anyway, tất cả mọi người nowdays có cookie kích hoạt như không có trang web hiện đại sẽ làm việc mà không có.

Thêm trong web.config:

<anonymousIdentification enabled="false" /> 
<authentication mode="None" /> 

hoặc

<anonymousIdentification enabled="true" cookieless="UseCookies" ... /> 
<authentication mode="Forms"> 
    <forms name="Auth" cookieless="UseCookies" ... /> 
</authentication> 
+0

BTW, giải pháp "pjumble" là gì, tôi không thấy, chỉ là chẩn đoán. – RPM1984

+0

bạn sẽ chặn một số nhóm người dùng đăng nhập chỉ vì một cú pháp vô nghĩa ngớ ngẩn trong phân tích cú pháp url của .net? –

+0

"Nhưng ai quan tâm" hầu hết các bộ phận bán hàng để bắt đầu ... – Basic

0

Bạn có thể muốn thử thêm một IgnoreRoute để lập bản đồ lộ trình của bạn - nhưng tôi thừa nhận tôi không chắc chắn những gì định dạng để cung cấp để phù hợp với tất cả các đường dẫn cookieless có thể của bạn.

Các vấn đề liên quan