2012-02-27 31 views
5

Trong thông thường AccountController trong ứng dụng MVC3 của tôi, nếu returnUrl được đặt (trong trường hợp của tôi, tôi đặt thủ công), nó sẽ gọi Redirect(returnUrl).Chuyển hướng (relativeUrl) chuyển hướng đến đường dẫn sai trong IIS

Giả sử URL trả lại của tôi là /Admin/HealthCheck (thực sự là). Khi tôi đang gỡ lỗi, tôi nhận được một URL như http://localhost:3279/Admin/HealthCheck từ cuộc gọi chuyển hướng.

Sau đó, tôi đã triển khai ứng dụng của mình tới http://localhost/Test. Trong trường hợp này, Redirect(returnUrl) chuyển hướng tôi đến http://localhost/Admin/HealthCheckkhông dự kiến ​​http://localhost/Test/Admin/HealthCheck.

Điều gì đang xảy ra ở đây? Làm thế nào để sửa lỗi này (nếu nó có thể sửa chữa được)?

Dưới đây là đoạn trích từ Tài khoản MVC3 (tiêu chuẩn); bạn có thể thấy nơi tôi nhận được URL trả về từ chuỗi truy vấn (ví dụ: http://localhost/Test/LogOn?ReturnUrl=/Admin/HealthCheck, mặc dù URL được mã hóa).

[HttpPost] 
     public ActionResult LogOn(LogOnModel model, string returnUrl) 
     { 
      if (ModelState.IsValid) 
      { 
       if (Membership.ValidateUser(model.UserName, model.Password)) 
       { 
        returnUrl = Request.Params["ReturnUrl"]; 

        FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe); 
        if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/") 
         && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\")) 
        { 
         return Redirect(returnUrl); 
        } 
        else 
        { 
         return RedirectToAction("Index", "Home"); 
        } 
       } 
       else 
       { 
        ModelState.AddModelError("", "The user name or password provided is incorrect."); 
       } 
      } 

Trả lời

2

(trong trường hợp của tôi, tôi đặt nó bằng tay)

Bạn chưa thực sự thể hiện như thế nào cài đặt bằng tay điều này xảy ra, nhưng nếu bạn đã hardcoded một url như /Admin/HealthCheck thay vì sử dụng một trình trợ giúp url để tạo url này, chẳng hạn như Url.Action("HealthCheck", "Admin") không mong đợi phép lạ xảy ra.

LogOn của bạn là tốt. Nó làm những gì nó là nghĩa vụ phải làm => nó chuyển hướng đến url được thông qua như là đối số. Vấn đề của bạn nằm trong cách bạn đang thiết lập url này.

Kết luận: trong một ứng dụng ASP.NET MVC luôn sử dụng trợ giúp url khi xử lý các url. Không bao giờ mã hóa chúng.

+0

Quay lại đầu trang Làm thế nào tôi có thể làm điều đó? Có vẻ như cách tiếp cận của bạn sẽ là lưu trữ tên bộ điều khiển, tên hành động và các thông số khác và sử dụng nó trong 'Url.Action'. Điều đó có vẻ không đúng. – ashes999

+1

@ ashes999, nếu người dùng cố gắng truy cập một trang được bảo vệ, anh ta gõ địa chỉ trang này vào thanh địa chỉ, phải không? Và khi ứng dụng của bạn được triển khai trong IIS, anh ta gõ '/ Test/Admin/HealthCheck' thay vì'/Admin/HealthCheck', phải không? Bởi vì nếu anh ta gõ '/ Admin/HealthCheck', anh ta sẽ nhận được 404 từ IIS, phải không? Trong trường hợp này mọi thứ hoạt động như mong đợi. Tôi không hiểu vấn đề của bạn là gì. –

1

Đối với URL Test của bạn, bạn sẽ phải đặt ReturnUrl thành Test/Admin/HealthCheck.

Lưu ý MSDN Reference on Controller.Redirect():

Tạo một đối tượng RedirectResult đó chuyển hướng đến URL được chỉ định.

Nói cách khác, nếu bạn đặt "/Admin/HealthCheck" làm thông số của mình, đó chính xác là nơi chuyển hướng sẽ đến.

+1

Điều đó không có ý nghĩa, vì trong IIS, thư mục gốc là/Test. Có lẽ đó chỉ là tôi, nhưng các URL tương đối được cho là liên quan đến URL gốc của ứng dụng. – ashes999

0

Nếu miền kết thúc của bạn sắp là www.domain.com/Test/Admin/HealthCheck, bạn có thể muốn thay đổi thư mục ảo cho dự án của mình để không phải thực hiện thay đổi trong URL khi chuyển đổi giữa máy chủ cục bộ và máy chủ thực.

Nếu bạn đang sử dụng Visual Studio, bạn có thể thay đổi đường dẫn ảo được gán cho dự án của mình bằng cách nhấp vào dự án trong trình thám hiểm giải pháp và nhấn F4. Điều này sẽ hiển thị cửa sổ thuộc tính dự án có tùy chọn để thay đổi đường dẫn ảo. Trong trường hợp của bạn, bạn sẽ muốn thay đổi nó thành /Test. Bạn sẽ vẫn phải thay đổi các url của mình để chứa /Test.

Mặc dù như Darin đã chỉ ra, bạn nên sử dụng trình trợ giúp url.

+0

Xem nhận xét của tôi về câu trả lời của anh ấy. – ashes999

1

Bạn cần sử dụng Request.UrlReferrer.AbsoluteUri

[HttpPost] 
    public ActionResult LogOn(LogOnModel model, string returnUrl) 
    { 
     string refUri = Request.UrlReferrer.AbsoluteUri; 

     if (ModelState.IsValid) 
     { 
      if (Membership.ValidateUser(model.UserName, model.Password)) 
      { 
       FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe); 
       if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/") 
        && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\")) 
       { 
        return Redirect(returnUrl); 
       } 
       else 
       { 
        return Redirect(refUri + "#/account/login"); 
       } 
      } 
      else 
      { 
       ModelState.AddModelError("", "The user name or password provided is incorrect."); 
      } 
     } 
Các vấn đề liên quan