MagicAjax、.NET、mono、Linux
由于项目的需要,最近研究了一下MagicAjax,加之本人是Linux的Fans,所以便在Linux下用mono开始MagicAjax的实验,结果发现了许多的问题。
今晚有事先说到这,明天继续。
今天继续说MagicAjax。
首先我下载了MagicAjax-0.3.0解压其中的Example在我的测试目录中,用xsp起动测试,在Linux下通过firefox访问,报错如下:
正常显示是正常显示了,可是看着怎么页面好像还是在刷新阿(由于是本地的服务器,刷新太快看不出来),所以我又另外写了一个测试页面,代码如下:
这时候的第一感觉是难道MagicAjax不支持firefox?马上查看文档,发现firfox1.0之后的版本都是支持的。
既然在Linux下不行,咱们也不能在一棵树上吊死阿,换到Windows下,将我的测试页部署到IIS,打开IE(对没错,是IE,因为我当时的想法是firefox不支持,IE总该支持吧),Ajax功能终于可以正常使用了。接下来就是在Windows下用firefox来试试,这回也能正常使用了!!!郁闷阿!!!我当时的想法是难道MagicAjax不支持mono吗?马上换到我心爱的Linux下,打开firefox访问部署在Windows下IIS中的测试页,原本以为这一回一定能够成功的,可是事实又一次的让我失望了。天阿,不会是MagicAjax和Linux有仇吧,怎么在Linux下就不能用呢...
没法子,只能去研究它的源码了,终于,工夫不负有心人,让我找到了这个:
HttpBrowserCapabilities caps = HttpContext.Current.Request.Browser;
switch (caps.Browser.ToLower(System.Globalization.CultureInfo.InvariantCulture))
case "firefox":
_isBrowserSupported = caps.MajorVersion >= 1;
break;
作出判断的,现在把我的测试页改为:
对了,还有一个问题,我既然添加了对mozilla的支持,那当然也要用mozilla测试一下拉,在Linux下起动mozilla,测试,通过...
今晚有事先说到这,明天继续。
今天继续说MagicAjax。
首先我下载了MagicAjax-0.3.0解压其中的Example在我的测试目录中,用xsp起动测试,在Linux下通过firefox访问,报错如下:
System.NullReferenceException: Object reference not set to an instance of an object
at MagicAjax.Util.GetPrivateField (System.Object instance, System.Type type, System.String fieldName) [0x00000]
at MagicAjax.AjaxCallHelper.GetPageHiddenDictionary (System.Web.UI.Page page, System.String fieldName) [0x00000]
at MagicAjax.AjaxCallHelper.HandleClientScriptBlocks (System.Web.UI.Page page, Boolean reflectToClient) [0x00000]
at MagicAjax.AjaxCallHelper.Page_PreRender (System.Object sender, System.EventArgs e) [0x00000]
at (wrapper delegate-invoke) System.MulticastDelegate:invoke_void_object_EventArgs (object,System.EventArgs)
at System.Web.UI.Control.OnPreRender (System.EventArgs e) [0x00000]
at System.Web.UI.Control.PreRenderRecursiveInternal () [0x00000]
at System.Web.UI.Page.InternalProcessRequest () [0x00000]
at System.Web.UI.Page.ProcessRequest (System.Web.HttpContext context) [0x00000]
后来在网上找到一篇文章说MagicAjax-0.3.0不支持mono,所以又下载了MagicAjax-0.2.2,更新MagicAjax.dll,在次用firefox访问测试页,这回可以正常显示了。at MagicAjax.Util.GetPrivateField (System.Object instance, System.Type type, System.String fieldName) [0x00000]
at MagicAjax.AjaxCallHelper.GetPageHiddenDictionary (System.Web.UI.Page page, System.String fieldName) [0x00000]
at MagicAjax.AjaxCallHelper.HandleClientScriptBlocks (System.Web.UI.Page page, Boolean reflectToClient) [0x00000]
at MagicAjax.AjaxCallHelper.Page_PreRender (System.Object sender, System.EventArgs e) [0x00000]
at (wrapper delegate-invoke) System.MulticastDelegate:invoke_void_object_EventArgs (object,System.EventArgs)
at System.Web.UI.Control.OnPreRender (System.EventArgs e) [0x00000]
at System.Web.UI.Control.PreRenderRecursiveInternal () [0x00000]
at System.Web.UI.Page.InternalProcessRequest () [0x00000]
at System.Web.UI.Page.ProcessRequest (System.Web.HttpContext context) [0x00000]
正常显示是正常显示了,可是看着怎么页面好像还是在刷新阿(由于是本地的服务器,刷新太快看不出来),所以我又另外写了一个测试页面,代码如下:
<%@ Page language="c#" %>
<%@ Register TagPrefix="ajax" Namespace="MagicAjax.UI.Controls" Assembly="MagicAjax" %>
<html>
<head>
<title>ASP.NET MagicAjax examples</title>
<style type="text/css">
body { font-size: small; font-family: verdana }
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
PostBack:
<br />
<asp:Button ID="Button1" OnClick="Button1_Click" runat="server" Text="Button" />
<br />
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label><br />
<hr />
Ajax:
<br />
<ajax:AjaxPanel ID="AjaxPanel1" runat="Server">
<asp:Button ID="Button2" runat="server" Text="Button" OnClick="Button2_Click" />
<br />
<asp:Label ID="Label2" runat="server" Text="Label"></asp:Label>
</ajax:AjaxPanel>
</div>
</form>
</body>
</html>
<script language="C#" runat="server">
protected void Button1_Click(object sender, EventArgs e)
{
//PostBack的部份
Label1.Text = DateTime.Now.ToString() + MagicAjax.MagicAjaxContext.Current.IsAjaxCallForPage(this).ToString();
}
protected void Button2_Click(object sender, EventArgs e)
{
//MagicAjax的部份
Label2.Text = DateTime.Now.ToString() + MagicAjax.MagicAjaxContext.Current.IsAjaxCallForPage(this).ToString();
}
</script>
这里我使用了MagicAjax.MagicAjaxContext.Current.IsAjaxCallForPage(this)来判定Ajax是否已起用,结果让我很失望,两个按钮返回的都是false。<%@ Register TagPrefix="ajax" Namespace="MagicAjax.UI.Controls" Assembly="MagicAjax" %>
<html>
<head>
<title>ASP.NET MagicAjax examples</title>
<style type="text/css">
body { font-size: small; font-family: verdana }
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
PostBack:
<br />
<asp:Button ID="Button1" OnClick="Button1_Click" runat="server" Text="Button" />
<br />
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label><br />
<hr />
Ajax:
<br />
<ajax:AjaxPanel ID="AjaxPanel1" runat="Server">
<asp:Button ID="Button2" runat="server" Text="Button" OnClick="Button2_Click" />
<br />
<asp:Label ID="Label2" runat="server" Text="Label"></asp:Label>
</ajax:AjaxPanel>
</div>
</form>
</body>
</html>
<script language="C#" runat="server">
protected void Button1_Click(object sender, EventArgs e)
{
//PostBack的部份
Label1.Text = DateTime.Now.ToString() + MagicAjax.MagicAjaxContext.Current.IsAjaxCallForPage(this).ToString();
}
protected void Button2_Click(object sender, EventArgs e)
{
//MagicAjax的部份
Label2.Text = DateTime.Now.ToString() + MagicAjax.MagicAjaxContext.Current.IsAjaxCallForPage(this).ToString();
}
</script>
这时候的第一感觉是难道MagicAjax不支持firefox?马上查看文档,发现firfox1.0之后的版本都是支持的。
既然在Linux下不行,咱们也不能在一棵树上吊死阿,换到Windows下,将我的测试页部署到IIS,打开IE(对没错,是IE,因为我当时的想法是firefox不支持,IE总该支持吧),Ajax功能终于可以正常使用了。接下来就是在Windows下用firefox来试试,这回也能正常使用了!!!郁闷阿!!!我当时的想法是难道MagicAjax不支持mono吗?马上换到我心爱的Linux下,打开firefox访问部署在Windows下IIS中的测试页,原本以为这一回一定能够成功的,可是事实又一次的让我失望了。天阿,不会是MagicAjax和Linux有仇吧,怎么在Linux下就不能用呢...
没法子,只能去研究它的源码了,终于,工夫不负有心人,让我找到了这个:
internal MagicAjaxContext()
{
// Load configuration from web.config
#if !NET_2_0 || !MEDIUM_TRUST
_configuration = (MagicAjaxConfiguration)ConfigurationSettings.GetConfig("magicAjax");
#endif
if (_configuration == null)
{
_configuration = new MagicAjaxConfiguration(null);
}
//store initial settings on first call (per request)
if (HttpContext.Current != null)
{
HttpBrowserCapabilities caps = HttpContext.Current.Request.Browser;
if (caps.Browser != null && caps.EcmaScriptVersion.Major >= 1)
{
switch (caps.Browser.ToLower(System.Globalization.CultureInfo.InvariantCulture))
{
case "ie":
_isBrowserSupported = caps.MajorVersion > 5 || (caps.MajorVersion == 5 && caps.MinorVersion >= 5);
break;
case "gecko":
_isBrowserSupported = caps.Type.ToLower(System.Globalization.CultureInfo.InvariantCulture).StartsWith("firefox") && caps.MajorVersion >= 1;
break;
case "firefox":
_isBrowserSupported = caps.MajorVersion >= 1;
break;
case "netscape":
_isBrowserSupported = caps.MajorVersion >= 5;
break;
case "opera":
_isBrowserSupported = caps.MajorVersion >= 8;
break;
//TODO: add support for Safari
}
}
}
}
这是一段位于MagicAjaxContext.cs的代码,MagicAjax正是通过它来判断客户端的浏览器是否能被支持的,它就是通过{
// Load configuration from web.config
#if !NET_2_0 || !MEDIUM_TRUST
_configuration = (MagicAjaxConfiguration)ConfigurationSettings.GetConfig("magicAjax");
#endif
if (_configuration == null)
{
_configuration = new MagicAjaxConfiguration(null);
}
//store initial settings on first call (per request)
if (HttpContext.Current != null)
{
HttpBrowserCapabilities caps = HttpContext.Current.Request.Browser;
if (caps.Browser != null && caps.EcmaScriptVersion.Major >= 1)
{
switch (caps.Browser.ToLower(System.Globalization.CultureInfo.InvariantCulture))
{
case "ie":
_isBrowserSupported = caps.MajorVersion > 5 || (caps.MajorVersion == 5 && caps.MinorVersion >= 5);
break;
case "gecko":
_isBrowserSupported = caps.Type.ToLower(System.Globalization.CultureInfo.InvariantCulture).StartsWith("firefox") && caps.MajorVersion >= 1;
break;
case "firefox":
_isBrowserSupported = caps.MajorVersion >= 1;
break;
case "netscape":
_isBrowserSupported = caps.MajorVersion >= 5;
break;
case "opera":
_isBrowserSupported = caps.MajorVersion >= 8;
break;
//TODO: add support for Safari
}
}
}
}
HttpBrowserCapabilities caps = HttpContext.Current.Request.Browser;
switch (caps.Browser.ToLower(System.Globalization.CultureInfo.InvariantCulture))
case "firefox":
_isBrowserSupported = caps.MajorVersion >= 1;
break;
作出判断的,现在把我的测试页改为:
<%@ Page language="c#" %>
<%@ Register TagPrefix="ajax" Namespace="MagicAjax.UI.Controls" Assembly="MagicAjax" %>
<html>
<head>
<title>ASP.NET MagicAjax examples</title>
<style type="text/css">
body { font-size: small; font-family: verdana }
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
PostBack:
<br />
<asp:Button ID="Button1" OnClick="Button1_Click" runat="server" Text="Button" />
<br />
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label><br />
<hr />
Ajax:
<br />
<ajax:AjaxPanel ID="AjaxPanel1" runat="Server">
<asp:Button ID="Button2" runat="server" Text="Button" OnClick="Button2_Click" />
<br />
<asp:Label ID="Label2" runat="server" Text="Label"></asp:Label>
</ajax:AjaxPanel>
</div>
</form>
</body>
</html>
<script language="C#" runat="server">
protected void Button1_Click(object sender, EventArgs e)
{
//PostBack的部份
Label1.Text = DateTime.Now.ToString() + MagicAjax.MagicAjaxContext.Current.IsAjaxCallForPage(this).ToString();
}
protected void Button2_Click(object sender, EventArgs e)
{
//MagicAjax的部份
HttpBrowserCapabilities caps = HttpContext.Current.Request.Browser;
Label2.Text = DateTime.Now.ToString() + MagicAjax.MagicAjaxContext.Current.IsAjaxCallForPage(this).ToString() + caps.Browser.ToLower(System.Globalization.CultureInfo.InvariantCulture) + caps.MajorVersion;
}
</script>
在次在Linux下用firefox访问测试页,终于找到问题的原因了,原来在Linux下的firefox被认作了mozilla,主版本号也为1,所以在MagicAjaxContext.cs中添加相应的对mozilla的处理如下:<%@ Register TagPrefix="ajax" Namespace="MagicAjax.UI.Controls" Assembly="MagicAjax" %>
<html>
<head>
<title>ASP.NET MagicAjax examples</title>
<style type="text/css">
body { font-size: small; font-family: verdana }
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
PostBack:
<br />
<asp:Button ID="Button1" OnClick="Button1_Click" runat="server" Text="Button" />
<br />
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label><br />
<hr />
Ajax:
<br />
<ajax:AjaxPanel ID="AjaxPanel1" runat="Server">
<asp:Button ID="Button2" runat="server" Text="Button" OnClick="Button2_Click" />
<br />
<asp:Label ID="Label2" runat="server" Text="Label"></asp:Label>
</ajax:AjaxPanel>
</div>
</form>
</body>
</html>
<script language="C#" runat="server">
protected void Button1_Click(object sender, EventArgs e)
{
//PostBack的部份
Label1.Text = DateTime.Now.ToString() + MagicAjax.MagicAjaxContext.Current.IsAjaxCallForPage(this).ToString();
}
protected void Button2_Click(object sender, EventArgs e)
{
//MagicAjax的部份
HttpBrowserCapabilities caps = HttpContext.Current.Request.Browser;
Label2.Text = DateTime.Now.ToString() + MagicAjax.MagicAjaxContext.Current.IsAjaxCallForPage(this).ToString() + caps.Browser.ToLower(System.Globalization.CultureInfo.InvariantCulture) + caps.MajorVersion;
}
</script>
internal MagicAjaxContext()
{
// Load configuration from web.config
#if !NET_2_0 || !MEDIUM_TRUST
_configuration = (MagicAjaxConfiguration)ConfigurationSettings.GetConfig("magicAjax");
#endif
if (_configuration == null)
{
_configuration = new MagicAjaxConfiguration(null);
}
//store initial settings on first call (per request)
if (HttpContext.Current != null)
{
HttpBrowserCapabilities caps = HttpContext.Current.Request.Browser;
if (caps.Browser != null && caps.EcmaScriptVersion.Major >= 1)
{
switch (caps.Browser.ToLower(System.Globalization.CultureInfo.InvariantCulture))
{
case "ie":
_isBrowserSupported = caps.MajorVersion > 5 || (caps.MajorVersion == 5 && caps.MinorVersion >= 5);
break;
case "gecko":
_isBrowserSupported = caps.Type.ToLower(System.Globalization.CultureInfo.InvariantCulture).StartsWith("firefox") && caps.MajorVersion >= 1;
break;
case "firefox":
_isBrowserSupported = caps.MajorVersion >= 1;
break;
case "mozilla":
_isBrowserSupported = caps.MajorVersion >= 1;
break;
case "netscape":
_isBrowserSupported = caps.MajorVersion >= 5;
break;
case "opera":
_isBrowserSupported = caps.MajorVersion >= 8;
break;
//TODO: add support for Safari
}
}
}
}
编译,测试,终于成功了,同样的,在Linux下修改MagicAjax-0.2.2的源码,编译,用xsp起动,测试,终于也成功了。而且在测试的过程中我还发现了一个有趣的现象,在Windows下的firefox访问Linux下的测试页时,firefox也是被认作了mozilla:){
// Load configuration from web.config
#if !NET_2_0 || !MEDIUM_TRUST
_configuration = (MagicAjaxConfiguration)ConfigurationSettings.GetConfig("magicAjax");
#endif
if (_configuration == null)
{
_configuration = new MagicAjaxConfiguration(null);
}
//store initial settings on first call (per request)
if (HttpContext.Current != null)
{
HttpBrowserCapabilities caps = HttpContext.Current.Request.Browser;
if (caps.Browser != null && caps.EcmaScriptVersion.Major >= 1)
{
switch (caps.Browser.ToLower(System.Globalization.CultureInfo.InvariantCulture))
{
case "ie":
_isBrowserSupported = caps.MajorVersion > 5 || (caps.MajorVersion == 5 && caps.MinorVersion >= 5);
break;
case "gecko":
_isBrowserSupported = caps.Type.ToLower(System.Globalization.CultureInfo.InvariantCulture).StartsWith("firefox") && caps.MajorVersion >= 1;
break;
case "firefox":
_isBrowserSupported = caps.MajorVersion >= 1;
break;
case "mozilla":
_isBrowserSupported = caps.MajorVersion >= 1;
break;
case "netscape":
_isBrowserSupported = caps.MajorVersion >= 5;
break;
case "opera":
_isBrowserSupported = caps.MajorVersion >= 8;
break;
//TODO: add support for Safari
}
}
}
}
对了,还有一个问题,我既然添加了对mozilla的支持,那当然也要用mozilla测试一下拉,在Linux下起动mozilla,测试,通过...