VS2013中的MVC5模板部署到mono上的艰辛历程
部署环境:CentOS7 + Mono 3.10 + Jexus 5.6
在Xamarin.Studio创建的asp.net项目,部署过程非常顺利,没有遇到什么问题;但在VS2013中创建的asp.net项目,部署过程会有一些波折。现在想想,原因是Xamarin.Studio中的项目模板比较简单,只是显示几个文字,并没有用到mvc5中的东西。
vs2013新建一个asp.net的项目(目标框架是.net4.5),选择mvc,并且更改身份验证为不适用身份验证。


编译,并发布到jexus默认站点指向的目录,访问之。报出的错误信息如下图。


根据异常堆栈信息,应该是调用HtmlHelper的ActionLink方法的时候,Helper友用到了RouteCollectionExtention的获取虚拟路径方法,问题就处在这个方法中。
看提示应该是RouteCollection少了AppendTrailingSlash这个属性(bool,用来控制在转换成虚拟路径的时候是否在最后添加“/”)。
其实,Asp.net 路由框架的代码位于System.web.dll中,System.Web.Routing.dll是个没有代码的空程序集。RouteCollectionExtention是mvc中为了方便使用而对路由框架中RouteCollection的一系列的扩展方法。
打开mvc的RouteCollectionExtention源码(http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/RouteCollectionExtensions.cs),发现了对RouteCollection的AppendTrailingSlash调用。

0(uy@w%240k7t.png)
对比下.net和mono中的RouteCollection类,发现mono中没有实现AppendTrailingSlash这个属性,同样也没有LowercaseUrls这个属性(代码地址分别是,.net:http://referencesource.microsoft.com/#System.Web/xsp/system/Web/Routing/RouteCollection.cs#8f054052ef9931ac#references,mono:https://github.com/mono/mono/blob/master/mcs/class/System.Web.Routing/System.Web.Routing/RouteCollection.cs)。


再看一下mono中RouteCollection这个文件的最后更新时间,++,两年前,好吧。


因为属性无法像扩展方法一样扩展,而且路由中又没有针对RouteCollection进行抽象,都是直接引用的RouteCollection,这个问题我暂时没招了。翻遍了google,只有问题,没有答案。
只能先绕过去了,找到View/Share/_Layout.cshtml,注释掉调用Html.ActionLink的代码,重新发布。


这时候可以正常访问,但页面的样式是乱的,在浏览器的开发人员工具中可以看到如下404信息,原因肯定是bundle框架并没有起作用。


解决办法是,找到bin文件夹删除Microsoft.Web.Infrastructure.dll,因为mono在lib中有关于这个程序集的自己的实现,为了开发和部署方便,也可以直接把Microsoft.Web.Infrastructure.dll设置为不复制到本地。
再次访问,可以看到清新的Bootstrap界面了,只是菜单上哪几个倒霉的链接被注释掉了。


以上可知,mono目前对mvc5的兼容性还不够好,可能在等vNext不屑于兼容mvc5了吧。
MVC5在mono上显示几个文字还是没有问题的,但HtmlHelper某些方法因为间接调用了mono没有实现的路由框架的属性,所以无法使用。
RouteCollectionExtention中获取虚拟路径的方法是非常重要而且使用频繁的,为了这个,只能弃用mvc5了,将其降级为mvc4了。
降级的过程是一部血泪史,有血,有泪,有屎。mvc相关的nuget包主要有:Microsoft Asp.Net MVC、Microsoft Asp.net Web Pages 、Microsoft Asp.net Razor,比较坑爹的是这三个包的不同版本之间不一定兼容。本来想是直接在NuGet中引入MVC4就好,但是遇到了各种问题,不是这个包少个方法就是那个包少个方法,最终试了很多种组合也没有成功。
最后不得已才用了一个投机取巧的方法,先创建一个mvc4的项目(在vs2013中的创建项目框中展开web选中vs2012就可以看到mvc4的模板),然后把vs自动创建的mvc4、webPage、razor包,复制到原解决方案的package目录下。

在NuGet中依次卸载MVC5、WebPages、Razor,然后添加对上面复制过来的三个包中的程序集的引用,这时在vs2013中编译运行会遇到下面的异常:


打开View文件夹下的Web.config,configSections中依然保留着对最初的那几个程序集的引用,把mvc4项目中的这段配置复制过来,编译运行,又看到下面的异常:


找不到System.Web.Helpers命名空间,可以我明明引用了System.Web.Helpers这个程序集啊,但bin中竟然没有System.Web.Helpers.dll。仔细查看,原来是没有设置为复制到本地,相应的检查一下上面手动添加的几个引用是否都设置了复制到本地,再次编译运行,在windows下已经可以正常浏览了。
把上面layout.cshtml中被注释掉的调用Html.ActionLink的代码解开注释。
编译运行,OK;部署到CentOS上,在bin文件夹中删除Microsoft.Web.Infrastructure.dll,重启jexus,浏览之,正常显示,点击菜单上通过HtmlHelper生成的几个连接,Perfect!!! 倒霉的菜单又回来了!!!

最终的代码在这里。
VS2013中的MVC5模板部署到mono上的艰辛历程的更多相关文章
- MVC5模板部署到mono
VS2013中的MVC5模板部署到mono上的艰辛历程 2014-10-27 09:30 by FuzhePan, 3954 阅读, 46 评论, 收藏, 编辑 部署环境:CentOS7 + Mono ...
- React开发中react-route-dom使用BrowserRouter部署到服务器上刷新时报404的问题
React项目部署中遇到的问题 react开发中react-route使用BrowserRoute路径在iis服务器上刷新时报404的问题 解决:在发布的项目根目录添加web.config配置文件 在 ...
- 使用Visual Studio 2015 开发ASP.NET MVC 5 项目部署到Mono/Jexus
最新的Mono 4.4已经支持运行asp.net mvc5项目,有的同学听了这句话就兴高采烈的拿起Visual Studio 2015创建了一个mvc 5的项目,然后部署到Mono上,浏览下发现一堆错 ...
- mono上部署web程序初体验
早就想体验一下mono,但一直琐事缠身.难得有时间,便在网上一通狂搜mono相关的资料. 如果想使用Apache服务器,只能使用mod_mono的方式,这里有详细的介绍.这种方式有点繁琐,需要安装一大 ...
- vmware vSphere client中,选择文件->部署OVF模板,报错处理方法
在vmware vSphere client中,选择文件->部署OVF模板,选择指定的OVA文件,按步骤进行,则会出现这样的错误:此OVF软件包使用了不受支持的功能.OVF软件包需要不支持的硬件 ...
- 在VS2013中使用水晶报表
又遇到了在B/S系统中打印,打印格式要求比较高,打印出的效果要求高大上.用VS2013中微软自带的报表,实在难以实现应用的效果,主要问题表现在: 1.不能插入用Word做好的打印模板,自己按照模板来做 ...
- .net程序部署(mono方式)
某一次 我同事用了这个词 ,说这样才显得够专业 擦.把某某项目 部署到服务器上 .擦 不就是拷个文件过去运行么.月亮 还是绵羊 我搞不清楚了 咱英文不好,绵羊叫的声音?.你就叫我山寨程序猿 随意 一 ...
- 如何在VS2013中进行Boost单元测试
对于如何在VS2013中进行Boost单元测试,这方面资料太少.自己也因此走了不少弯路.下文将会阐述一下如何在VS2013中进行Boost单元测试. 在开始Boost单元测试之前,我们需要先安装VS2 ...
- Ansible_使用jinja2模板部署自定义文件
一.jinja2简介 1.jinja2模板 1️⃣:Ansible将jinja2模板系统用于模板文件,Ansible还使用jinja2语法来引用playbook中的变量 2️⃣:变量和逻辑表达式置于标 ...
随机推荐
- node-webkit 环境搭建与基础demo
首先去github上面下载(地址),具体更具自己的系统,我的是windows,这里只给出windows的做法 下载windows x64版本 下载之后解压,得到以下东西 为了方便,我们直接在这个目录中 ...
- SQL Server镜像自动生成脚本
SQL Server镜像自动生成脚本 镜像的搭建非常繁琐,花了一点时间写了这个脚本,方便大家搭建镜像 执行完这个镜像脚本之后,最好在每台机器都绑定一下hosts文件,不然的话,镜像可能会不work 1 ...
- 浅谈我对DDD领域驱动设计的理解
从遇到问题开始 当人们要做一个软件系统时,一般总是因为遇到了什么问题,然后希望通过一个软件系统来解决. 比如,我是一家企业,然后我觉得我现在线下销售自己的产品还不够,我希望能够在线上也能销售自己的产品 ...
- Spring框架概述
Spring是最流行的Java企业级应用开发框架,全球数以百万的开发者在使用Spring框架创建高性能.易测试.可重用的代码. Spring框架的核心特性可以应用于任何Java应用,但扩展的JavaE ...
- Mediaplayer error (-19,0)
Android MediaPlayer 发生 error (-19,0) 错误解决方法. 引起原因:由于多次实例化MediaPlayer.start() 进行播放操作引起的.由于没有及时释放内存资源导 ...
- Node.js:进程、子进程与cluster多核处理模块
1.process对象 process对象就是处理与进程相关信息的全局对象,不需要require引用,且是EventEmitter的实例. 获取进程信息 process对象提供了很多的API来获取当前 ...
- 9、委托、事件、Lambda
开始 关于委托,肯定是要有问题的. 第一个问题,委托用来干什么? 看.net中的表述:在.net平台下,委托类型用来定义和相应应用程序中的回调.(回调?处理内存中两个实体双向通信的一种技术.) 第 ...
- NGINX引入线程池 性能提升9倍
1. 引言 正如我们所知,NGINX采用了异步.事件驱动的方法来处理连接.这种处理方式无需(像使用传统架构的服务器一样)为每个请求创建额外的专用进程或者线程,而是在一个工作进程中处理多个连接和请求.为 ...
- js 入门级常见问题
写在前面:以下是个人总结的关于js常见的入门级的问题一些总结. js是有 ECMAScript Dom Bom 三部分组成. 1,undefined,NaN,Null,infinity 1) unde ...
- Android 指纹认证
安卓指纹认证使用智能手机触摸传感器对用户进行身份验证.Android Marshmallow(棉花糖)提供了一套API,使用户很容易使用触摸传感器.在Android Marshmallow之前访问触摸 ...