怎样在linux Mint 14上开发asp.net mvc3网站

最近一直想体验下mono在web开发上到底进展到什么程度,挑战一下它对web开发的极限。因为asp.net mvc本身依赖windows平台的东西不太多,所以这些assembly移植到mono/linux上来应该不是大问题。网上很多人很早也介绍了相关主题,但是他们大部分是基于这样的模式:在Visual Studio里开发asp.net mvc网站,然后再部署到linux上。我个人觉得这种做法只能验证mono运行时有支持asp.net mvc的能力,这个确实也在mono 2.10的release note里提到了。但是如果想要在linux上开发asp.net mvc网站怎么办呢?有同学会说:那在linux上装个虚拟机做开发吧~~


本文我将会介绍怎样在linux上用用monodevelop开发一个简单的asp.net mvc3网站。asp.net mvc3是mono运行时目前支持的最新的版本,这个版本相对2比较成熟点 。然后会介绍我在这个过程中碰到的一些问题以及解决办法。从下面这个截图,我们可以知道请求是从ubuntu Chromium/28.0.1500.52上发出的,我本机是linux mint,属于ubuntu系的,再查看response,可以知道asp.net版本是4.0.30319,mvc版本是3.0,我用的开发服务器是Mono.WebServer.XSP/3.0.0.0。

怎样在linux Mint 14上开发asp.net mvc3网站_第1张图片


既然我们的目的是带有探索性的,那么我采用的是最近的源码,从github上我获取了3个项目:mono,monodevelop,xsp。第一个是mono运行时,第二个是IDE,第三个是开发版Web服务器。我会把所有的这些项目都安装到/usr/local目录下,以免跟从软件源里安装的版本冲突,另外,因为毕竟是不稳定版本,如果贸然装到/usr下的话,系统也不稳定。首先编译mono运行时,这个可以参考我以前的一篇文章在Linux Mint13下编译安装mono运行时 。接下来就是编译IDE,不出意外您也应该跟我一样碰到一些编译错误,主要是由于引用的DLL找不到引起的。很多依赖的csharp binding assembly找不到,例如,glib-sharp,gtk-sharp等,解决方法就是把这些assembly的pc文件从/usr/lib/pkgconfig下拷贝到/usr/local/lib/pkgconfig。下面看看gtk-sharp-2.0的pc文件的一部分,我们看它的第一行prefix是一个相对值,在拷贝到/usr/local/lib/pkgconfig之后,gtk-sharp.dll在/usr/local下仍然找不到,因此需要把它变成一个绝对路径prefix=/usr。

怎样在linux Mint 14上开发asp.net mvc3网站_第2张图片

然后我把我这边/usr/local/lib/pkgconfig目录下所有的pc文件截个图出来

等build通过后,在monodevelop目录下运行make run,这样就启动IDE了。

怎样在linux Mint 14上开发asp.net mvc3网站_第3张图片

我用gtksharp拖出了个简单的界面,编译,运行,调试,都可以的。神器阿~~~~


接下来再编译xsp的源码。我本打算用源里的那个xsp,但是编译出来的IDE总是报找不到xsp,这个我就没有深究,因为可以yy的原因实在太多,不想浪费时间调查这个。所以就决定自己编译xsp。没想到编译相当顺利并且快(1分钟左右在我机器上),出乎意料。xsp源码里自带了一个测试用的asp.net网站,然后我切换到目录/usr/local/lib/xsp/test目录下运行xsp4,服务器在端口9000上起来了。

怎样在linux Mint 14上开发asp.net mvc3网站_第4张图片

在浏览器中输入localhost:9000,很cool,asp.net网站在linux上运行了。但是有些asp.net web控件显示错误,例如menu,grid。因为这些控件的实现依赖gdi+,所以我从源里安装libgdiplus,也需要把它的pc文件拷贝到/usr/local/lib/pkgconfig下。这样,整个test网站显示都没问题了。


接下来在IDE中建asp.net mvc项目,简单起见,先从v2开始。这个过程没啥问题,xsp正常启动,网站能够浏览,目前能调试时动态修改代码但不能立即生效,问题不大。然后做v3,问题来了。第一就是项目的引用DLL System.Web.Helpers.dll和System.Web.WebPages.dll 就标红,提示找不到。System.Web.Helpers.dll确实在mono运行时里没有,然后我看了一下这个DLL的实现,认为它没啥大关系,所以就直接删掉了。System.Web.WebPages.dll在/usr/local/lib/mono/4.5下是有的,并且也在gac下注册了,并且我项目的targetFramework也是指定的4.5,它标红就有点想不通了,有知道答案的同学请通知一声。后来我也把它删掉了,但是必须把System.Web.WebPages.dll拷贝到项目的bin目录下,因为razor在解析页面的时候需要用到它,否则页面也展现不出来。这个后面会说。接下来的一个问题更头痛,xsp在mono 4.5下怎么也启动不起来。在v2时,因为目标framework默认是4,所以没问题。好在所有涉及到的代码都可以直接调试,发现xsp服务器在初始化asp.net运行时时Configuration没有重新初始化好,一读appSettings就报错。后来把target framework改成4就没问题了。终于,网站可以访问了,但是页面展现时报错,网页上的错误信息非常模糊,说Home/Index.cshtml找不到,我了个去,明明在那儿阿,挑战理解极限阿~~~继续调戏,注意是被调戏~~~原来web.config里有几个引用的assembly没找到,我删除了System.Web.Helpers.dll的引用。然后System.Web.WebPages.dll的版本不是1.0而是2.0。如果大家有什么问题欢迎交流。


更新

2013年7月6日

特意在标题中强调是Linux Mint 14。我发现在Linux Mint 14 apache2.2.22下,mod-mono-server按照官方说法配置后仍然无法正常启动,报的错误是参数无法解析。通过修改源码在apache的日志文件error.log中记录启动mod-mono-server的命令行参数,乍一看没什么问题:

[Thu Jul 04 21:41:54 2013] [warn] running '/usr/local/bin/mod-mono-server4 --filename /tmp/mod_mono_server_global --applications /:/var/www/test --nonstop --master (null) (null) (null) (null) (null) (null)'

后来我去看xsp的源代码,发现这样写可能不行,然后手工执行这条命令,mod-mono-server也一样启动不了。后来我试着修改源码

tristan@tristan-Satellite-L600 ~/workspace/csharp/xsp/xsp $ git status
# On branch master
# Changes not staged for commit:
#   (use "git add ..." to update what will be committed)
#   (use "git checkout -- ..." to discard changes in working directory)
#
#    modified:   src/Mono.WebServer.Apache/ConfigurationManager.cs
#    modified:   src/Mono.WebServer.Apache/main.cs
#    modified:   src/Mono.WebServer/ApplicationServer.cs
#    modified:   src/Mono.WebServer/Options/ConfigurationManager.Fields.cs
#    modified:   src/Mono.WebServer/Options/ConfigurationManager.Parsing.cs
#    modified:   src/Mono.WebServer/Options/Options.cs

这是我在xsp目录下的改动记录。主要是修改xsp解析传入参数的方式。有以下几点:

1. 把输入的参数由--filename /tmp/mod_mono_server_global --applications /:/var/www/test --nonstop --master变为--filename=/tmp/mod_mono_server_global --applications=/:/var/www/test --nonstop --master

2. 修改ConfigurationManager.Fields.cs和ConfigurationManager.cs中定义的配置选项的prototype属性,因为在从命令行参数到配置型的转换中,是通过prototype来判断该怎样处理某个命令行参数的。

3. 对于非BoolSetting,要将回调函数变成Func类型的,这会导致选择ActionOption。ActionOption和ActionOption之间的区别是前者的MaxValueCount为2,而后者是1。ActionOption计算配置项的bool值,它检测传入的TKey是否为null。

tristan@tristan-Satellite-L600 ~/workspace/csharp/xsp/xsp $ git diff src/Mono.WebServer/Options/ConfigurationManager.Parsing.cs
diff --git a/src/Mono.WebServer/Options/ConfigurationManager.Parsing.cs b/src/Mono.WebServer/Options/ConfigurationManager.Parsing.cs
index e64454e..3863ed8 100644
--- a/src/Mono.WebServer/Options/ConfigurationManager.Parsing.cs
+++ b/src/Mono.WebServer/Options/ConfigurationManager.Parsing.cs
@@ -46,7 +46,7 @@ namespace Mono.WebServer.Options {
                                } else {
                                        ISetting setting1 = setting; // Used in closure, must copy
                                        p.Add (setting.Prototype, setting.Description,
-                                              v =>
+                                              (n,v) =>
                                               { if (v != null) setting1.MaybeParseUpdate (SettingSource.CommandLine, v);
                                               });
                                }


怎样在linux Mint 14上开发asp.net mvc3网站_第5张图片

你可能感兴趣的:(mono)