设为首页 收藏本站
查看: 2127|回复: 0

[经验分享] IIS7部署MVC项目报错403.14的解决

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-4-28 08:38:52 | 显示全部楼层 |阅读模式
                      web.config添加
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
ASP.NET MVC 4 在 .NET 4.0 與 .NET 4.5 的專案範本差異
昨天在【ASP.NET MVC 4 開發實戰】課程中,學員們發現了一個問題,就是在實作與測試 ASP.NET MVC 的 Routing (路由) 機制的過程中,發現有個功能有些人做得出來,有些人卻做不出來,當我前去查看時也沒立即發現問題癥結,中午休息的空檔終於找到的這個細微的差異之處,所以還是寫篇文章提醒正準備開始使用 .NET Framework 4.5 的 ASP.NET MVC 開發人員。

在此我們先建立一個以 .NET Framework 4.0 為主的 ASP.NET MVC 4 專案:

專案範本則以「網際網路應用程式」為主要範本:

接著我們開啟專案下 App_Start\RouteConfig.cs 檔案,試圖修改預設路由的 url 參數定義:

我們試著將 {action} 修改成 {action}.aspx

這時,我們可以測試該專案,連接以下網址

    http://localhost:26618/Home/Index .aspx

你會看到網頁是可以正常顯示的,如下圖示:

image

接著,我們試著將 {action} 修改成 {action}.{ext} ,把 .aspx 修改成一個 路由變數

我們定義了 .{ext} 這個路由變數,代表我們可以在 {action} 後面加上任意 "副檔名”,然而事實上這不是個 “副檔名”,而是一個路由值而已!

這時,我們可以測試該專案,連接以下網址

    http://localhost:26618/Home/Index .php

  ( 備註:這是為了示範路由與網址的對應而設計的一個範例,你就算把 .php 改成 .jsp 都能執行 )

你會看到網頁是可以正常顯示的,如下圖示:

接下來,我們建立一個以 .NET Framework 4.5 為主的 ASP.NET MVC 4 專案:

然後完全使用上述的範例執行一次,但練習到最後,你卻會發現,使用以下網址可行:

    http://localhost:26636/Home/Index .aspx

但使用以下網址卻會引發 HTTP 錯誤 404.0 – Not Found 的錯誤 ( 而且該錯誤是從 IIS 傳來的 )

    http://localhost:26636/Home/Index .php

但是如果我在 .php 後面加上一條斜線 ( / ),問題竟然可以解決,例如:

    http://localhost:26636/Home/Index .php /

後來我用 WinMerge 工具比對兩個 ASP.NET MVC 專案資料夾的差異,這才發現,雖然兩個都是 ASP.NET MVC 4 專案,但是 web.config 的預設內容卻改變了,是在 <system.webServer> 區段下的 <modules> 區段,原本在 .NET 4.0 專案範本中有下圖這段 runAllManagedModulesForAllRequests 設定,但是在 .NET 4.5 卻被移除,進而導致此差異:

然而,這段設定最主要是針對 IIS7+ ( 含 IIS 7.5, IIS 8.0 ) 的 整合 (Integrated) 模式下進行設定,如果你不加上 <modules runAllManagedModulesForAllRequests="true" /> 的話,在預設的情況下,透過 .NET 撰寫的 HttpModules 只能針對 Managed 要求進行處裡 (也就是那些透過 .NET 執行的程式),那些透過原生模組 (native modules) 處裡的檔案,例如 JPEG, CSS, JavaScript 等靜態檔案,就不會流經這些 HttpModules 進行處裡,在這種情況下,如果你沒有明確註冊 HttpHandler 在 IIS 裡面的話,將會導致 IIS 無法判定明確的 MIME Type 而導致找不到網頁的情況,也就是我們這次遇到的問題。

當然,最簡單的應變措施就是直接把這段設定加回去,不過,加回去之前請三思,這條設定被拿掉是有原因的,而原因就出在: 效能衝擊 ( Performance Impact )!

在 IIS6 以前,IIS 在處理 HTTP 要求的過程中,只能透過 原生模組 (native modules) 處裡所有要求,並且預設透過副檔名來決定如何對應不同的原生模組,以 ASP.NET 為例,就會有一個 .aspx 對應到 c:\windows\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll 的設定,相關設定畫面可參考如下圖示,你可以發現,所有 HTTP 要求都必須透過「對應」的方式,才能得知正確的 Handler,接下來才能將 HTTP 要求委派給對應的 Handler 進行處理:

以下是從 聖哥 的【 Windows Server 2008 應用程式新平台 - IIS 7.0 】簡報中擷取的一段圖示,你可以從這裡看出 IIS 6.0 在處理要求的流程。

這裡你將會發現到,如果我們要透過「身分驗證」模組處裡本次要求,他是 IIS 內建的一個原生模組,雖然我們也可以在 ASP.NET 撰寫 HttpHandler 或 HttpModules 做到相同的事情,但是這些由 ASP.NET 撰寫的程式預設只能處理所有與 ASP.NET 相關的要求而已,也就是那些副檔名註冊在 IIS 裡面,並且設定到 aspnet_isapi.dll 的那些副檔名,才真正能執行到這段程式碼。反之,如果今天從用戶端傳來的 HTTP 要求是 *.htm 副檔名,他所對應到的只要不是 aspnet_isapi.dll 的話,就執行不到這段由 ASP.NET 開發框架下撰寫的 HttpHandler 或 HttpModules。我在 2007 年曾經寫過的一篇文章,就是試圖解決這個問題,參見: 如何讓 ASP.NET 的表單驗證功能保護 .htm 的檔案

從 IIS7 開始,這個所謂的 IIS Request Pipeline (要求管線) 做了一次重大個改進,一個名為「整合」模式的新式要求管線,把整個模組執行的過程做出了改善,他允許你用 .NET 撰寫 Managed Modules,並且可以套用在任何 HTTP 要求上面,徹底打破架構上的限制,以下是 IIS7+ 新式要求管線示意圖:
( 註 :若想深入研究的人,建議可閱讀 Introduction to IIS Architectures 文章。)

image

回到本文提出的問題,當我們 沒有 <modules runAllManagedModulesForAllRequests="true" /> 這項預設設定的話 ( 預設為 false ),代表的是,我們在 ASP.NET 定義的模組 (modules),只想處理 Managed 要求 (就是那些註冊為 .NET 相關的要求) 而已,而非 所有 HTTP 要求 (AllRequests),所以當你試圖要求 *.php 等尚未註冊的 handler 時,自然就會引發 HTTP 錯誤 404.0 – Not Found 的錯誤!

不過,可能會有人想問,為什麼我在 .php 後面加上一條斜線 ( / ),問題竟然可以解決呢?

因為從 ASP.NET 4.0 開始,新增了一個 ExtensionlessUrlHandler 要求處理器 (handler),這是一個專門用來處理那些「沒有副檔名的 HTTP 要求」。因為我們在撰寫 ASP.NET MVC 的時候,通常不會在網址加上所謂的「副檔名」,對於這些要求,IIS 會不知道應該將要求如何派送給那個 handler 處理,所以才衍生出這樣的需求,可以說是為了 ASP.NET MVC 量身打造的!

    像是 ExtensionlessUrlHandler 這樣的處理器,如果要在 IIS6 實現,必須要註冊所謂的 萬用字元應用程式對應 才有可能 (設定了這個會影響 IIS6 的執行效能),最主要還是 IIS 架構上的差異使然。

你可以從下圖看到 ASP.NET MVC 專案範本中,預設就會載入所謂的 ExtensionlessUrlHandler 處理器!

文字版本如下:

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

如果你想註冊 *.php 並且讓 ASP.NET MVC 路由可以辨識的話,可以參考以下設定:

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

<add name="(PHP) ExtensionlessUrlHandler-ISAPI-4.0_32bit"

path="*.php"

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="(PHP) ExtensionlessUrlHandler-ISAPI-4.0_64bit"

path="*.php"

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="(PHP) ExtensionlessUrlHandler-Integrated-4.0"

path="*.php"

verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"

type="System.Web.Handlers.TransferRequestHandler"

preCondition="integratedMode,runtimeVersionv4.0" />

</handlers>

最後想要補充說明的是,如果你自行開發 HTTP 模組 ( HttpModules ) 的話,就算你手動加上 <modules runAllManagedModulesForAllRequests=" false " /> 設定,可能會認為「任何原生模組相關的 HTTP 要求」( 例如: *.htm, *.css 之類的 ) 都不會再流經你自行開發的 HTTP 模組,然而,這是個錯誤觀念!

使用這個 runAllManagedModulesForAllRequests 設定,最主要的差異在於:

    當設定為 true 的時候,所有 HTTP 要求,包含 已註冊的 、 未註冊的 附檔名對應,都會流經你自己撰寫的 HTTP 模組。
    當設定為 false 的時候,所有 HTTP 要求,所有 已註冊的 附檔名對應,還是會流經你自己撰寫的 HTTP 模組。

這個小細節對於寫 HTTP 模組的開發人員來說非常重要!

                   


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-61398-1-1.html 上篇帖子: 解决win2003下IIS中建立ASP网站出现500内部错误的方法 下篇帖子: IIS 6.0/7.0/7.5、Nginx、Apache 等服务器解析漏洞总结 项目
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表