2013-02-05 29 views
13

我有一個有趣的情況下,我無法解釋,我需要幫助搞清楚我的問題是什麼在IIS7:ASP.NET MVC4不處理在IIS7集成模式POST請求,但在IIS7.5

鑑於:

  • ASP.NET MVC 4 web應用
  • 缺省路由註冊到{控制器}/{行動}

參見下面的控制器:

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

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

此外,在Global.asax中有這樣的代碼:

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(); 
} 

所以,每當有一個服務器錯誤,這是記錄。在這種情況下,如果是正常的404,則返回起始頁面。這工作(幾乎)罰款。稍後更多。

此設置在IIS7(Windows Server 2008,生產環境)和IIS7.5(Win7 Pro,開發環境和Windows Server 2008 R2以及生產環境)上提供了非常不同的行爲。

鑑於IIS以下配置(兩個版本):

  • 網絡中IIS是使用集成模式 ASP.NET 4應用池
  • <模塊runAllManagedModulesForAllRequests = 「真」/ >配置設置在system.webServer部分

IIS 7.5的行爲是:

  • GET請求/:返回索引頁
  • POST請求/:返回索引頁
  • GET請求/服務/測試:返回測試
  • POST請求/服務/測試:返回測試
  • GET請求/ Service/Test2:執行Global.asax Application_Error:HttpException:在控制器'MyTestProject.Controllers.ServiceController'上找不到公共操作方法'Test2'。
  • POST請求/服務/ Test2的:返回的Test2
  • GET請求來的東西有毫無路線:執行Global.asax中END_REQUEST。

IIS 7行爲改用:

  • GET請求/:返回索引頁
  • POST請求/:IIS 404頁
  • GET請求/服務/測試:返回測試
  • POST請求/服務/測試:IIS 404頁面
  • GET請求/服務/測試2:執行Global.asax Application_Error:HttpException:在控制器'MyTestProject.Controllers.ServiceController'上未找到公共操作方法'Test2'。
  • POST請求/服務/ Test2的:返回IIS 404頁
  • GET請求的東西有毫無路線:IIS 404頁

因此,IIS 7使用時,IIS 7.5工作高度GET請求,除非沒有路由。 當不存在路由時,IIS 7.5將執行狀態碼爲404的Global.asax結束請求並傳遞索引頁。 IIS 7不會不執行執行Global.asax結束請求。爲什麼? 我可以(現在也可以)通過註冊{* catchall}路線來解決此問題,以便存在匹配路線。

只要我嘗試使用HTTP POST,IIS 7的工作效率甚至比我預想的要低。

發佈請求時,IIS 7不會在我的應用程序中執行任何代碼,並直接返回IIS 404頁面。

所以我的問題是:爲什麼IIS 7拒絕如此難以處理我的MVC 4應用程序中的POST請求,以及我能做些什麼來處理POST請求?

回答

1

我們想通了 - 最後。

的默認配置插入這個在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> 

的問題是 「*」。路徑,它會覆蓋/test.aspx而不是簡單地/測試。

如果將其更改爲「*」,則所有請求都將由ExtensionlessUrlHandler處理,包括那些不再提供給靜態文件的請求。

因此,解決辦法是: 從處理程序條目刪除帖子動詞,與路徑爲「*」,只有POST請求設置添加新條目的ExtensionlessUrlHandler:

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

理想的情況下刪除的那些你不需要(經典與集成管道中的x86和x64)。

0

這可能與IIS 7上沒有(或不正確)安裝的某些功能有關,這些功能會阻止無擴展名的URL正常工作。

請檢查以下項目:

在「打開Windows功能打開或關閉」 Windows控制面板的對話框中的「程序和功能」應用:

  1. 轉到Internet信息服務>萬維網服務>常見HTTP功能
  2. 確保已選擇「HTTP錯誤重定向」選項。
  3. 確保已選中「靜態內容壓縮」選項。選擇任一選項後,單擊「確定」保存更改。

參考:http://support.microsoft.com/kb/2023146

0

也許7和7.5路由是在相對於越區切換一個POST到具有沒有參數可以接受後形式的數據的動作不同。

如果您的代碼永遠不會被觸及,則表明路由未找到與簽名,參數匹配的內容,並且在切換到代碼之前檢查它的內部約束。

也許下一步是嘗試將參數添加到POST以接受模型,即使您沒有傳入該模型。模型顯然將爲空。