MVC项目在IIS6上部署的几种思路

 微软在vista和win2008下集成了IIS7,与IIS6相比,有重大升级,看IIS7的十大改进,http://blogs.msdn.com/cqwang/archive/2007/09/10/iis7.aspx

而在2008年发布的MVC正式版中支持IIS6/IIS7。不过对iis6支持的有点变态。

 下面是邀月的一次正式部署MVC项目到IIS6的过程。为了项目接近实用,在演示项目中引用了一个Web service(主要根据地区邮编或地区名称来获取天气预报)

http://www.webservicex.net/WeatherForecast.asmx?WSDL 

第一步: 正式创建一MVC项目 ,本项目沿用上个示例,名称为MvcAppDemoFck。项目结构如下图:

 

第二步:添加web引用 ,这个与普通的web service没什么不同,输入地址 http://www.webservicex.net/WeatherForecast.asmx?WSDL 

 其他默认即可。如上图。

第三步:在Controller下添加新的Controller,名称为WeatherController ,添加代码如下:

view plaincopy to clipboardprint?
public ActionResult Index()  
       {  
           return View();  
       }  
       
       public ActionResult GetWeather(string Id)  
       {  
           //if (string.IsNullOrEmpty(Id)) { return null; }  
           if (string.IsNullOrEmpty(Id)) { Id = "New York"; }  
           StringBuilder sb = new StringBuilder();  
           WeatherForecast wf = new WeatherForecast();  
           WeatherForecasts wfs = wf.GetWeatherByPlaceName(Id);  
           WeatherData[] wd = wfs.Details;  
           sb.AppendFormat("<B>Weather Forecast for {0}</B><br /><br />", wfs.PlaceName);  
           foreach (WeatherData d in wd)  
           {  
               if (!string.IsNullOrEmpty(d.WeatherImage))  
               {  
                   sb.AppendFormat("<img src="/" mce_src="/""{0}/" >", d.WeatherImage);  
                   sb.AppendFormat(" {0}", d.Day);  
                   sb.AppendFormat(", High {0}F", d.MaxTemperatureF);  
                   sb.AppendFormat(", Low {0}F<br />", d.MinTemperatureF);  
               }  
           }  
           Response.Write(sb.ToString());  
           return null;  
       } 
 public ActionResult Index()
        {
            return View();
        }
     
        public ActionResult GetWeather(string Id)
        {
            //if (string.IsNullOrEmpty(Id)) { return null; }
            if (string.IsNullOrEmpty(Id)) { Id = "New York"; }
            StringBuilder sb = new StringBuilder();
            WeatherForecast wf = new WeatherForecast();
            WeatherForecasts wfs = wf.GetWeatherByPlaceName(Id);
            WeatherData[] wd = wfs.Details;
            sb.AppendFormat("<B>Weather Forecast for {0}</B><br /><br />", wfs.PlaceName);
            foreach (WeatherData d in wd)
            {
                if (!string.IsNullOrEmpty(d.WeatherImage))
                {
                    sb.AppendFormat("<img src="/" mce_src="/""{0}/" >", d.WeatherImage);
                    sb.AppendFormat(" {0}", d.Day);
                    sb.AppendFormat(", High {0}F", d.MaxTemperatureF);
                    sb.AppendFormat(", Low {0}F<br />", d.MinTemperatureF);
                }
            }
            Response.Write(sb.ToString());
            return null;
        }
并在 "public ActionResult Index{"处右键 Add View,新增一个View名称为GetWeather.aspx,即默认名称

第四步:修改默认的MainContent的内容部分为:

+ expand sourceview plaincopy to clipboardprint?
<mce:script type="text/javascript" src="<%= Url.Content(" mce_src="<%= Url.Content("~/Content/Js/jquery-1.3.2.min.js")%><!--  
">  
// --></mce:script>  
    <!--<mce:script type="text/javascript"  src="<%= Url.Content(" mce_src="&lt;%= Url.Content("~/Scripts/jquery-1.3.2.min.js")%><!--  
" >  
// --></mce:script>-->  
    <!--<mce:script type="text/javascript" src="/Scripts/jquery-1.3.2.min.js" mce_src="Scripts/jquery-1.3.2.min.js"></mce:script>-->  
    <!--<mce:script type="text/javascript" src="http://localhost:50002/Scripts/jquery-1.3.2.min.js" mce_src="http://localhost:50002/Scripts/jquery-1.3.2.min.js"></mce:script>-->  
    <!-- <mce:script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" mce_src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></mce:script>-->  
    <mce:script type="text/javascript"><!--  
        function getWeather() {  
            //var URl = '<%= Url.Content("/Weather/GetWeather/")%>';  
            var URL = "/Weather/GetWeather/" + $("#Location").val();  
            $.get(URL, function(data) {  
                $("#Result").html(data);  
            });  
        }  
      
// --></mce:script>  
    <mce:script type="text/javascript"><!--  
        function getWeatherJSON() {  
            var URL = "/Weather/GetJsonWeather/";  
            $.getJSON(URL, { Location: $("#Location").val() }, function(data) {  
                var result = "";  
                $.each(data, function(index, d) {  
                    if (d.WeatherImage != '') {  
                        result += '<br /><img src="' + d.WeatherImage + '" mce_src="' + d.WeatherImage + '" > ';  
                        result += d.Day;  
                        result += ', High ' + d.MaxTemperatureF + 'F';  
                        result += ', Low ' + d.MinTemperatureF + 'F';  
                    }  
                });  
                $("#Result").html(result);  
            });  
        }  
      
// --></mce:script>  
    <div>  
        <input type="text" id="Location" style="width: 325px" value="New York" />   
        <input type="button" id="btnSubmit" value="Get Weather" οnclick="javascript:getWeather();" />  
        <input type="button" id="btnSubmitJson" value="Get Weather JSON" οnclick="javascript:getWeatherJSON();" />  
        <br />  
        <br />  
        <div id="Result">  
        </div>  
    </div>  
    <div>  
        <ul>  
            <li>  
                <%= Html.ActionLink("WeatherJQuery", "GetWeather", "Weather")%>  
            </li>  
            <li>  
                <%= Html.ActionLink("WeatherJSON", "GetJsonWeather", "Weather")%>  
            </li>  
        </ul>  
    </div> 
<mce:script type="text/javascript" src="<%= Url.Content(" mce_src="<%= Url.Content("~/Content/Js/jquery-1.3.2.min.js")%><!--
">
// --></mce:script>
    <!--<mce:script type="text/javascript"  src="<%= Url.Content(" mce_src="&lt;%= Url.Content("~/Scripts/jquery-1.3.2.min.js")%><!--
" >
// --></mce:script>-->
    <!--<mce:script type="text/javascript" src="/Scripts/jquery-1.3.2.min.js" mce_src="Scripts/jquery-1.3.2.min.js"></mce:script>-->
    <!--<mce:script type="text/javascript" src="http://localhost:50002/Scripts/jquery-1.3.2.min.js" mce_src="http://localhost:50002/Scripts/jquery-1.3.2.min.js"></mce:script>-->
    <!-- <mce:script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" mce_src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></mce:script>-->
    <mce:script type="text/javascript"><!--
        function getWeather() {
            //var URl = '<%= Url.Content("/Weather/GetWeather/")%>';
            var URL = "/Weather/GetWeather/" + $("#Location").val();
            $.get(URL, function(data) {
                $("#Result").html(data);
            });
        }
   
// --></mce:script>
    <mce:script type="text/javascript"><!--
        function getWeatherJSON() {
            var URL = "/Weather/GetJsonWeather/";
            $.getJSON(URL, { Location: $("#Location").val() }, function(data) {
                var result = "";
                $.each(data, function(index, d) {
                    if (d.WeatherImage != '') {
                        result += '<br /><img src="' + d.WeatherImage + '" mce_src="' + d.WeatherImage + '" > ';
                        result += d.Day;
                        result += ', High ' + d.MaxTemperatureF + 'F';
                        result += ', Low ' + d.MinTemperatureF + 'F';
                    }
                });
                $("#Result").html(result);
            });
        }
   
// --></mce:script>
    <div>
        <input type="text" id="Location" style="width: 325px" value="New York" />
        <input type="button" id="btnSubmit" value="Get Weather" οnclick="javascript:getWeather();" />
        <input type="button" id="btnSubmitJson" value="Get Weather JSON" οnclick="javascript:getWeatherJSON();" />
        <br />
        <br />
        <div id="Result">
        </div>
    </div>
    <div>
        <ul>
            <li>
                <%= Html.ActionLink("WeatherJQuery", "GetWeather", "Weather")%>
            </li>
            <li>
                <%= Html.ActionLink("WeatherJSON", "GetJsonWeather", "Weather")%>
            </li>
        </ul>
    </div>
注意,这里一个端口号为50002,是iis的端口,而不是vs2008内置的端口,

看图:

 

 下面开始正式的部署:如果此时在浏览器中输入http://localhost:50002/,会提示404错误。出错原因如下:

This happens because IIS 6 only invokes ASP.NET when it sees a “filename extension” in the URL that’s mapped to aspnet_isapi.dll (which is a C/C++ ISAPI filter responsible for invoking ASP.NET). Since routing is a .NET IHttpModule called UrlRoutingModule , it doesn’t get invoked unless ASP.NET itself gets invoked, which only happens when aspnet_isapi.dll gets invoked, which only happens when there’s a .aspx in the URL. So, no .aspx , no UrlRoutingModule , hence the 404.

大意是:因为IIS6只对aspx文件才调用 aspnet_isapi.dll进行处理,而在默认的MVC设置里是无路径的,所以会出现404。有人说,为什么vs2008内建的浏览器会支持呢?那正是因为调用了aspnet_isapi.dll 的缘故。所以我们在IIS6中只要通知iis,需要对该网站的地址url进行解析处理即可。

 第一种尝试:Use a wildcard mapping for aspnet_isapi.dll,为aspnet_isapi.dll启用通配符映射。 这个翻译很别扭。^_^

iis-网站-属性-主目录-配置-映射-插入--(注意不是添加扩展名),可执行文件名一般为C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/aspnet_isapi.dll

 去掉"确认文件是否存在"的勾,即不选。

OK! 再打开浏览器, http://localhost:50002/,似乎一切都很美好!!但这就等于告诉IIS,每一次的请求,都要通过aspnet_isapi.dll,而无论是否是aspx文件。这不是我们想要的。

第二种尝试:Put .aspx in all your route entries’ URL patterns。在URL格式中设置.aspx路由入口 ,即

在Global.asax.cs文件的RegisterRoutes方法中修改默认的路由规则为

 routes.MapRoute("Default", "{controller}.aspx /{action}/{id}", new { controller = "Home", action = "Index", id = "" });
这样一来,这样相当于欺骗iis6,告诉IIS6 ,我是aspx文件,你处理一下我吧。

这样处理的结果就是地址栏变成了 http://localhost:50002/Home.aspx/Abouthttp://localhost:50002/Weather.aspx,但浏览一朷正常。就是地址太恶心了些。

第三种尝试:Use a custom filename extension in all your URL patterns,在所有的url规则中添加一个可定制的扩展名如mvc等。

 与第一种非常类似。iis-网站-属性-主目录-配置-映射-添加--(注意不是插入),可执行文件名一般为C:/WINDOWS /Microsoft.NET/Framework/v2.0.50727/aspnet_isapi.dll,扩展名为.mvc,动作限制为 “GET,HEAD,POST,DEBUG",同样去掉"确认文件是否存在"的勾,即不选。因为这些文件并不是真正存在的,只不过为了欺骗可怜的IIS6。其实与第二种的效果类似,只是可以定制后缀名,如".org"等。展示效果同第二种。

当然,第二种可以用.mvc。同时注意,第二种与第三种必须添加默认Root路径的路由规则,否则会找不到默认主页

view plaincopy to clipboardprint?
routes.MapRoute("Root", "", new { controller = "Home", action = "Index", id = "" });  
 routes.MapRoute("Root", "", new { controller = "Home", action = "Index", id = "" });

出错信息如下:

 

 如果vs2008中启动调试也会在这句出错。

第四种尝试:利用第三方URL组件。

1、发现原来用的ISAPI_Rewrite不能在MVC环境正常使用。可能版本过低,是1.3Full。

2、老赵推荐使用IIRF( Ionics Isapi Rewrite Filter)开源,地址为:http://iirf.codeplex.com/

官方提供了MVC的匹配规则:http://cheeso.members.winisp.net/Iirf20Help/html/1ccbf1ec-0984-49d9-9ab0-63eab3ff9c63.htm

view plaincopy to clipboardprint?
# IsapiRewrite4.ini  
#  
#  
## Turn off logging  
#RewriteLog  c:/temp/iirfLog.out  
#RewriteLogLevel 3   
IterationLimit 1  
RewriteEngine ON  
StatusUrl /iirfStatus  
RewriteRule ^/Default/.aspx /Home.mvc [I,L]   
RewriteRule ^/$ /Home.mvc [I,L]   
RewriteRule ^/([/w]+)$ /$1.mvc [I,L]   
RewriteRule ^/(?!Content)([/w]*)/(.*) /$1.mvc/$2 [I,L] 
# IsapiRewrite4.ini
#
#
## Turn off logging
#RewriteLog  c:/temp/iirfLog.out
#RewriteLogLevel 3
IterationLimit 1
RewriteEngine ON
StatusUrl /iirfStatus
RewriteRule ^/Default/.aspx /Home.mvc [I,L]
RewriteRule ^/$ /Home.mvc [I,L]
RewriteRule ^/([/w]+)$ /$1.mvc [I,L]
RewriteRule ^/(?!Content)([/w]*)/(.*) /$1.mvc/$2 [I,L]

按照官方文档,完成配置,需要在iis中设置,而且需要IsapiRewrite4.ini和IsapiRewrite4.dll在同一个目录下,还需要重启iis,希望你看到这些不要崩溃!

 安装见官方地址http://cheeso.members.winisp.net/Iirf20Help/html/c76efb95-05ba-4383-8022-7eff3e1174d0.htm

 配置http://cheeso.members.winisp.net/Iirf20Help/frames.htm
性能如何,没有测试。

配置成功,截图如下:

 

 

  第五种尝试:Upgrade to Windows Server 2008 and IIS 7。 据说IIS7对MVC提供了完美的支持。财力短缺,在此略去。

至此,一次mvc项目的部署告一段落。 希望有人能提供更好的方案。

结束语:MVC最好的支持应该是IIS7或者是IIS8,这是产品的生命周期使然。另外在部署过程中js的路径比较特殊,除了使用特殊的

view plaincopy to clipboardprint?
Url.Content("~/Content/Js/jquery-1.3.2.min.js") 
Url.Content("~/Content/Js/jquery-1.3.2.min.js")

外,最好将js文件放置在Content/js下。而不是默认的Scripts文件。其中出过几次错,特别是在第三方URL组件时更易错。

本文参考的文章:

 ASP.NET MVC on IIS 6 Walkthrough


Asp.net MVC项目的部署(一):IIS以及Asp.net与IIS相关的部分
Deploying ASP.NET MVC to IIS 6
JQuery AJAX with ASP.NET MVC
 ASP.NET MVC Framework体验(5):路径选择(URL Routing)

 ASP.NET MVC 入门3、Routing

 重提URL Rewrite(2):使用已有组件进行URL Rewrite

Using ASP.NET MVC with Different Versions of IIS
ASP.NET MVC URL Routing 学习


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/downmoon/archive/2009/11/03/4763321.aspx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值