各位读者你们好,好长一段时间没有更新文章了,自从参加工做以后,天天等待去作的工做没完没了,我的的时间也变得奢侈起来,从此要尽可能从中脱身,抽更多的时间来完成本身想作的事情(但愿如此)。html
言归正传,上一回合中,咱们讨论学习了如何在Linux.NET中让一个 MVC 3.0 和 MVC 4.0 的项目在mono中跑起来。而就在早前几天,我在新浪微博中看到一位朋友转发了一篇有关如何将MVC4.0项目升级到MVC5.0的文章:《How to Upgrade an ASP.NET MVC 4 and Web API Project to ASP.NET MVC 5 and Web API 2》。我不由感叹,这时代的步伐还真快,MVC还真的一年一版本的出,同时,一个想法在脑海中造成:既然MVC都发展到5.0了,那当前可否让它在Mono中跑起来呢?web
进入本回合主题,本回合中咱们将讨论学习:api
一、获得一个ASP.NET MVC 5 的框架应用mvc
二、将一个简单的ASP.NET MVC 5 的应用部署到Linux中app
本回合的程序源码包,能够点击“这里”进行下载。框架
一、获得一个ASP.NET MVC 5 的框架应用asp.net
巧妇难为无米之炊,想要部署一个MVC 5的应用,必须先获得一个基于这个版本的MVC应用。当前我使用的开发工具是Visual Studio 2012,而ASP.NET MVC 5.0 倒是跟 Visual Studio 2013 绑定一同发布,官方貌似尚未提供独立的模板安装文件。固然,咱们也不可能为了作这么一个ASP.NET MVC 5.0的实验而跑去下载并安装一个Visual Studio 2013,所以咱们要经过一些其余办法来得到这么一个应用。ide
NuGet,果真是一枚好东西,咱们很容易的就在上面的发现了ASP.NET MVC 5.0 的包,这样,咱们能够先使用Visual Studio创建一个MVC 4.0(或如下)的项目,而后在经过NuGet为该项目升级便可。工具
首先,咱们先建一个ASP.NET MVC 4.0 的项目:学习
而后调出咱们的控制台程序(具体能够在:“工具->库程序包管理器->程序包管理器控制台”调出),输入:“Update-Package”,让它自动的把全部当前的版本库升级。
第三步,咱们须要对“~/View/Web.config”中的配置进行修改。
具体的修改内容,能够参照前言中说说起的那篇文章,“Update the web.config files under the Views folder”这一节中的一、2两个步骤,在这里,我把我修改后的Web.Config配置所有贴出来让各位读者参考。
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"> <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" /> <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" /> </sectionGroup> </configSections> <system.web.webPages.razor> <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <pages pageBaseType="System.Web.Mvc.WebViewPage"> <namespaces> <add namespace="System.Web.Mvc" /> <add namespace="System.Web.Mvc.Ajax" /> <add namespace="System.Web.Mvc.Html" /> <add namespace="System.Web.Routing" /> </namespaces> </pages> </system.web.webPages.razor> <appSettings> <add key="webpages:Enabled" value="false" /> </appSettings> <system.web> <httpHandlers> <add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/> </httpHandlers> <!-- 在视图页面中启用请求验证将致使验证在 控制器已对输入进行处理后发生。默认状况下, MVC 在控制器处理输入前执行请求验证。 若要更改此行为,请对控制器或操做 应用 ValidateInputAttribute。 --> <pages validateRequest="false" pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"> <controls> <add assembly="System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" /> </controls> </pages> </system.web> <system.webServer> <validation validateIntegratedModeConfiguration="false" /> <handlers> <remove name="BlockViewHandler"/> <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" /> </handlers> </system.webServer> </configuration>
最后,咱们再创建一个简单的控制器和页面,而后把它跑起来。
在这里,我有几点本小节的小建议或解析:
一、在创建初始项目的时候,建议选择MVC项目,而非WebForm应用程序。为何呢?这里并非说经过WebForm+MVC库的方式没法实现,而是若是各位读者采用WebForm+MVC库的方式实现的话,除了没有办法使用Visual Studio所提供的便利以外,创建的每个View页面,后方都有可能带一个CS文件(若是你是经过创建aspx页面而后改后缀名之类的),而且编译发布以后的代码,View中的内容也有可能被编进了dll中。总而言之,这都将形成极大的不便。
二、因为ASP.NET MVC 5仅支持.NET FrameWork 4.5以上的版本,所以新建项目是,FrameWork 4.0 或 如下的版本是没法升级到MVC 5 的。
三、使用NuGet升级,由于本次"Update-Package"没有带上任何的参数,所以系统会默认的帮你升级到最新的版本,换句话说,若是下次是MVC 6 的话,NuGet则会帮你升到最新版本(固然,是否成功则是另一个问题啦)。各位读者也能够经过在项目资源管理器中“右键本项目->管理NuGet程序包”来对这些库进行相关操做。
二、将一个简单的ASP.NET MVC 5 的应用部署到Linux中
好的,接下来,咱们要将这个简单的小项目部署进Linux当中,因为使用的是.NET FrameWork 4.5,我手头上的mono版本担忧会有所不足(原先版本为:mono 3.0.12)所以我把Linux中的Mono从新安装了一遍(提及惭愧,因为“rm -rf /usr/local/mono/” 时忘了关Jexus,从新编译的时候还Error了一次),如今的版本为:mono 3.2.3。
把环境搭建好以后,再把这个小项目发布到Linux中(jexus网站配置和网站发布过程这里再也不写了,又须要的读者能够翻阅前面的文章),而后尝试访问。
嗯嗯,就知道不会有这么顺利的,咱们把“CustomError”设为“Off”看看它报了些什么错。
第一个错误报出来了,说是没法加载“System.Web.Http.WebHost”程序集中的一个方法。
咱们先检查是不是由于缺乏程序集形成的。
检查发现,这个程序集已经自带在bin文件夹中,初步排除是缺乏程序集形成的,而且改程序集的版本也是5.0.0.0,也排除版本问题形成的。
再观察它是否和mono不兼容(如该版本库使用了和操做系统紧密关联的东西之类的),在观察以前这里有个小技巧,那就是先看看mono中有没有这个程序集,若是有,则把mono里面的库直接替换它,若是没有再慢慢观察。
很幸运的,找到了这一个对应的程序集,咱们把它抽取出来,直接替换掉bin里面的这个程序集。
而后再刷新页面:
好的,第二个问题报出来了,此次是程序集中缺乏方法了。
经过命名空间来查找,咱们寻寻觅觅的找到了bin文件夹中“System.Web.Http.dll”中的class HttpConfiguration:
虽然Methods没有明确的写有“get_Service”这个方法,不过留意红色框框那里,那里使用了语法糖,程序集编译后会自动的产生这个方法,所以此dll中是有这个方法存在的。
与此同时,咱们发现了mono中也存在这个程序集:
咱们再撬开mono中的这个程序集:
能够发现,这两个属性,虽然名称相同,可是倒是分别两个不一样的类型,细心的读者还可以发现,就连这个类自己都是有很多东西是不一样的。
这样的话,咱们就把mono的这个程序集拿来替换掉bin下的这个程序集。
再次刷新咱们的页面:
嘿嘿,出现了。结果证实,ASP.NET MVC 5又跑起来了。
写在本回合最后,最大的感想就是,在漫步漫长的失败的荆棘道路以后以后,成功的终点或许就在你面前的一步,只是由于雾太大了你没有看清而已。作这个实验时,前一个晚上折腾到三点半都没有结果出来,当时就放弃了,不过次日灵感一来了,又花了几分钟再次尝试,最后产生了这一篇文章。
好的,很少说,期待下一次见面。