2013-02-05 23 views
13

Tôi có một trường hợp thú vị Tôi không thể giải thích, và tôi cần được giúp đỡ để tìm ra những gì vấn đề của tôi là trên IIS7:ASP.NET MVC4 không xử lý yêu cầu POST trong chế độ tích hợp IIS7, nhưng trong IIS7.5

Given:

  • ASP.NET MVC ứng dụng 4 web đường
  • mặc định đăng ký {controller}/{action}

Xem bộ điều khiển sau:

public class ServiceController : Controller 
{ 
    public ActionResult Test() 
    { 
     return Content("Test"); 
    } 

    [HttpPost] 
    public ActionResult Test2() 
    { 
     return Content("Test2"); 
    } 
} 

Thêm vào đó, trong Global.asax có mã này:

protected void Application_EndRequest() 
{ 
    if (Context.Response.StatusCode == 404) 
    { 
     ExecuteIndexPage(); 
    } 
} 

protected void Application_Error(object sender, EventArgs e) 
{ 
    var error = Server.GetLastError(); 
    ExceptionLogger.Log(error); 

    ExecuteIndexPage(); 
} 

Vì vậy, bất cứ khi nào có một lỗi máy chủ, điều này được ghi lại. Trong trường hợp này và trong trường hợp của một 404 bình thường, trang bắt đầu được trả về. Điều này làm việc (gần như) tốt. Thêm vào đó sau.

Thiết lập này mang lại các hành vi rất khác nhau trên IIS7 (Windows Server 2008, môi trường sản xuất) và IIS7.5 (Win7 Pro, môi trường phát triển và Windows Server 2008 R2, môi trường sản xuất).

Với cấu hình như sau trong IIS (cả hai phiên bản):

  • Web trong IIS được cấu hình sử dụng một chế độ tích hợp ASP.NET 4 ứng dụng hồ bơi
  • < module runAllManagedModulesForAllRequests = "true"/> được đặt trong phần system.webServer

Trong IIS 7.5 hành vi là:

  • yêu cầu GET đến /: Returns trang index
  • POST yêu cầu /: Returns trang index
  • GET yêu cầu/Dịch vụ/Kiểm tra: Trả thử nghiệm
  • yêu cầu POST đến/Dịch vụ/Kiểm tra : Trả về Kiểm tra
  • Nhận yêu cầu đến/Dịch vụ/Test2: Thực thi Global.asax Application_Error: HttpException: Phương thức hành động công khai 'Test2' không được tìm thấy trên bộ điều khiển 'MyTestProject.Controllers.ServiceController'.
  • POST yêu cầu/Dịch vụ/Test2: Trả Test2
  • yêu cầu GET đến một cái gì đó có không đường cho: Thực thi Global.asax End_Request.

Trong IIS 7 hành vi thay thế là:

  • GET yêu cầu /: Returns trang index
  • POST yêu cầu /: IIS 404 trang
  • GET Yêu cầu/Dịch vụ/Kiểm tra: Trả về Kiểm tra
  • Yêu cầu POST đến/Dịch vụ/Kiểm tra: IIS 404 trang
  • GET Request to/Service/Test2: Thực hiện Global.asax Application_Error: HttpException: Một phương thức hành động công khai 'Test2' không được tìm thấy trên bộ điều khiển 'MyTestProject.Controllers.ServiceController'.
  • POST Yêu cầu/Dịch vụ/Test2: Returns IIS 404 trang
  • GET Yêu cầu một cái gì đó có không đường cho: IIS 404 trang

Vì vậy, IIS 7 và IIS 7.5 công việc tuyệt vời khi sử dụng Nhận yêu cầu, ngoại trừ khi không có tuyến đường. Khi không có tuyến đường, IIS 7.5 thực hiện yêu cầu kết thúc Global.asax với mã trạng thái 404 và cung cấp trang chỉ mục. IIS 7 thực hiện NOT thực hiện yêu cầu kết thúc Global.asax. Tại sao? Tôi có thể (và hiện tại) làm việc xung quanh vấn đề này bằng cách đăng ký một tuyến đường {* catchall} để tuyến đường phù hợp tồn tại.

Ngay sau khi tôi đang cố gắng sử dụng HTTP POST, IIS 7 hoạt động thậm chí ít hơn tôi mong đợi.

Khi gửi yêu cầu, IIS 7 không thực thi bất kỳ mã nào trong ứng dụng của tôi, và trực tiếp trả về trang IIS 404. Vì vậy, câu hỏi của tôi là: Tại sao IIS 7 từ chối khó xử lý các yêu cầu POST trong ứng dụng MVC 4 của tôi, và tôi có thể làm gì để nó cũng xử lý yêu cầu đăng bài?

Trả lời

1

Chúng tôi đã tìm ra - cuối cùng.

Các chèn mặc định cấu hình này trong web.config:

<system.webServer> 
    <validation validateIntegratedModeConfiguration="false" /> 
    <modules runAllManagedModulesForAllRequests="true" /> 
    <handlers> 
    <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" /> 
    <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" /> 
    <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> 
    <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" /> 
    <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" /> 
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> 
    </handlers> 
</system.webServer> 

Vấn đề là "*." đường dẫn, sẽ bao gồm /test.aspx nhưng không chỉ đơn giản là/kiểm tra.

Nếu bạn thay đổi thành "*", thì tất cả các yêu cầu sẽ được xử lý bởi ExtensionlessUrlHandler, bao gồm cả các yêu cầu đối với các tệp tĩnh sẽ không được phân phát nữa.

Vì vậy, giải pháp là: Di động từ POST từ các mục xử lý và thêm các mục mới cho ExtensionlessUrlHandler với đường dẫn thiết lập để "*" và chỉ cho các yêu cầu POST:

<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" /> 
    <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" /> 
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> 
    <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit_post" path="*" verb="POST" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" /> 
    <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit_post" path="*" verb="POST" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" /> 
    <add name="ExtensionlessUrlHandler-Integrated-4.0_post" path="*" verb="POST" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> 

Lý tưởng nhất là loại bỏ những người thân bạn không cần (x86 và x64 trong đường ống cổ điển và tích hợp).

0

Điều này có thể liên quan đến một số tính năng không được cài đặt trên IIS 7 để ngăn URL không hoạt động hoạt động chính xác.

Vui lòng kiểm tra các mục sau đây:

Trong mục "Turn Windows Features On hoặc Off" hộp thoại của Windows Control Panel "Programs and Features" ứng dụng:

  1. Tới Internet Information Services> Các dịch vụ Web toàn cầu> Các tính năng HTTP phổ biến
  2. Đảm bảo rằng tùy chọn "Chuyển hướng lỗi HTTP" được chọn.
  3. Đảm bảo rằng tùy chọn "Nén nội dung tĩnh" được chọn. Sau khi một trong hai tùy chọn đã được chọn, hãy nhấp vào "OK" để lưu thay đổi.

tham khảo: http://support.microsoft.com/kb/2023146

0

Có lẽ 7 và 7,5 định tuyến khác nhau trong sự tôn trọng để trao ra một POST để một hành động mà không có lập luận cho rằng có thể chấp nhận các dữ liệu bài mẫu.

Nếu mã của bạn không bao giờ bị tấn công, nó sẽ chỉ ra rằng định tuyến không tìm thấy kết quả phù hợp cho chữ ký, đối số và các ràng buộc được xây dựng mà nó kiểm tra trước khi chuyển sang mã.

Có thể bước tiếp theo sẽ là thử thêm đối số vào POST để chấp nhận mô hình, ngay cả khi bạn không chuyển mô hình đó vào. Mô hình sẽ rõ ràng là không có kết quả.

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