WinServer2008R2 + IIS 7.5 + .NET4.0 經典模式 運行WebAPI程序報404錯誤的解決方案


在Windows Server 2008 R2系統下,IIS 7.5 + .NET Framework 4.0的運行環境,以經典模式(Classic Mode)部署一個用.NET 4.0編譯的 WebAPI 程序。

這是非常簡易的一個Demo,只有一個TestController和WebApiConfig,並且已確保在Global.asax的Application_Start事件中調用WebApiConfig注冊路由,大體如下:

 1 using System;
 2 using System.Web.Http;
 3 
 4 namespace WebAPI
 5 {
 6     public class Global : System.Web.HttpApplication
 7     {
 8         protected void Application_Start(object sender, EventArgs e)
 9         {
10             WebApiConfig.Register(GlobalConfiguration.Configuration);
11         }
12     }
13 }
Global
 1 using System.Web.Http;
 2 
 3 namespace WebAPI
 4 {
 5     public static class WebApiConfig
 6     {
 7         public static void Register(HttpConfiguration config)
 8         {
 9             //配置路由
10             config.Routes.MapHttpRoute(
11                 name: "DefaultApi3",
12                 routeTemplate: "api/{controller}/{action}/{id}",
13                 defaults: new { id = RouteParameter.Optional }
14             );
15 
16             config.Routes.MapHttpRoute(
17                 name: "DefaultApi2",
18                 routeTemplate: "api/{controller}/{action}"
19             );
20             
21             config.Routes.MapHttpRoute(
22                 name: "DefaultApi1",
23                 routeTemplate: "api/{controller}/{id}",
24                 defaults: new { id = RouteParameter.Optional }
25             );
26         }
27     }
28 }
WebApiConfig
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Web.Http;
 4 
 5 namespace WebAPI.Controllers
 6 {
 7     public class TestController : ApiController
 8     {
 9         // GET api/test
10         public IEnumerable<string> Get()
11         {
12             return new string[] { "value1", "value2", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff") };
13         }
14 
15         // GET api/test/5
16         public string Get(int id)
17         {
18             return "value";
19         }
20 
21         // POST api/test
22         public void Post([FromBody]string value)
23         {
24         }
25 
26         // PUT api/test/5
27         public void Put(int id, [FromBody]string value)
28         {
29         }
30 
31         // DELETE api/test/5
32         public void Delete(int id)
33         {
34         }
35     }
36 }
TestController
 1 <?xml version="1.0" encoding="utf-8"?>
 2 
 3 <!--
 4   有關如何配置 ASP.NET 應用程序的詳細信息,請訪問
 5   http://go.microsoft.com/fwlink/?LinkId=169433
 6   -->
 7 
 8 <configuration>
 9   <system.web>
10     <compilation debug="true" targetFramework="4.0" defaultLanguage="c#" />
11   </system.web>
12 
13   <system.webServer>
14     <handlers>
15       <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
16       <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
17       <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
18       <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" />
19       <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" />
20       <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" />
21     </handlers>
22   </system.webServer>
23 </configuration>
web.config

 本地IIS 7.5是沒有問題的,直接訪問localhost/api/test,成功輸出XML格式的數據。

但是發布上去之后,卻報404錯誤。

搜了一些解決方案,都是比較片面不全的,沒一個能起作用。

比如,讓我們在<system.webServer>節點下加<modules>或<validation>或兩個都加上,像這樣:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 
 3 <!--
 4   有關如何配置 ASP.NET 應用程序的詳細信息,請訪問
 5   http://go.microsoft.com/fwlink/?LinkId=169433
 6   -->
 7 
 8 <configuration>
 9   <system.web>
10     <compilation debug="true" targetFramework="4.0" defaultLanguage="c#" />
11   </system.web>
12 
13   <system.webServer>
14     <modules runAllManagedModulesForAllRequests="true">
15       <remove name="WebDAVModule" />
16     </modules>
17     <validation validateIntegratedModeConfiguration="false" />
18     <handlers>
19       <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
20       <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
21       <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
22       <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" />
23       <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" />
24       <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" />
25     </handlers>
26   </system.webServer>
27 </configuration>

又或者,讓我們在站點的處理程序映射里添加通配符腳本映射,像這樣:

按照上面這些做完之后,還是不行,百思不得其解。

最后幾經折騰,終於解決!!!

流程如下:

第一步,更改WebAPI站點的web.config文件:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 
 3 <!--
 4   有關如何配置 ASP.NET 應用程序的詳細信息,請訪問
 5   http://go.microsoft.com/fwlink/?LinkId=169433
 6   -->
 7 
 8 <configuration>
 9   <system.web>
10     <compilation debug="true" targetFramework="4.0" defaultLanguage="c#" />
11   </system.web>
12 
13 <system.webServer>
14         <!--以下配置為了讓IIS7+支持Put/Delete方法-->
15         <httpProtocol>
16             <customHeaders>
17                 <add name="Access-Control-Allow-Origin" value="*" />
18                 <add name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE,OPTIONS" />
19                 <add name="Access-Control-Allow-Headers" value="Content-Type" />
20             </customHeaders>
21         </httpProtocol>
22         <!--IIS7/7.5上必須加這個配置,否則訪問報錯-->
23         <modules runAllManagedModulesForAllRequests="true">
24             <remove name="WebDAVModule" />
25         </modules>
26         <validation validateIntegratedModeConfiguration="false" />
27         <handlers>
28             <remove name="WebDAV" />
29             <remove name="WebAPI_64bit" />
30             <remove name="WebAPI_32bit" />
31             <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
32             <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
33             <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
34             <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" resourceType="Unspecified" requireAccess="Script" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
35             <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" resourceType="Unspecified" requireAccess="Script" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
36             <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" resourceType="Unspecified" requireAccess="Script" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
37             <add name="WebAPI_64bit" path="*" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="None" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
38             <add name="WebAPI_32bit" path="*" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="None" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
39         </handlers>
40         <!--提高GET URL長度限制上限-->
41         <security>
42             <requestFiltering>
43                 <requestLimits maxUrl="409600" maxQueryString="204800" />
44             </requestFiltering>
45         </security>
46     </system.webServer>
47 </configuration>
web.config

第二步,無論是否確定已注冊,都再注冊一次:

Win+R鍵輸入cmd確定,打開命令提示符(Win7以上系統都需要以管理員身份運行,且當前登錄賬戶最好是Administrator)。

依次輸入如下命令,並且按確定,等待執行完畢:

cd /d %windir%\Microsoft.NET\Framework\v4.0.30319

aspnet_regiis -i

如果服務器是64位系統,你還需要輸入如下命令:

cd /d %windir%\Microsoft.NET\Framework64\v4.0.30319

aspnet_regiis -i

第三步,清理IIS站點垃圾(緩存):

 在資源管理器中,打開%windir%\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files文件夾

刪除該文件夾下的所有文件和文件夾,root文件夾除外,但root文件夾下的文件和文件夾也要刪除。

如果碰到無法刪除,提示權限不足或該文件/文件夾被占用之類的,請先停止IIS服務(在運行窗口或cmd窗口輸入iisreset /stop可以停止IIS服務),再重試刪除。

第四步,重啟服務器。

第五步,在運行窗口或cmd窗口輸入iisreset /start啟動IIS服務,接着訪問yourserver.com/api/xxx,成功響應並且返回數據,大功告成!!!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM