array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 (转自老赵Jeffrey Zhao)The status code returned from the server was: 12031”。 - 爱码网
“Sys.WebForms.PageRequestManagerServerErrorException: An unknown eror occurred while processing the request on the server. 
今天收到邮件,被问及为什么 UpdatePanel如果结合了UrlRewrite就会出现问题。一开始我不以为然,由于我也曾经在UrlRewrite时使用过 UpdatePanel,没有出现过问题。但是收到对方打包的代码后,发现这个问题的确重现了,如果直接访问目标页面就不会有任何问题。因为当时在公司, 没有仔细地去研出错的原因。在回家的路上,脑子里一遍一遍地模拟着UpdatePanel的实现过程,却没有察觉到有任何不妥。最后还是忍不住,坐在公交 车上的时候就打开笔记本,仔细的寻找问题所在。公交车实在晃得厉害,还好最终在我呕吐之前找到了问题,刚才的思考还是棋差一着。

 

重现问题:

  现在我将重现那个问题。在原来的代码中使用了NBear的UrlRewriteModule,为了简单起见,我使用了最普通的UrlRewrite的做法来得到相同的效果,尽量避免有些朋友(包括我)因为不熟悉NBear而妨碍文章内容的理解。

  首先,新建一个ASP.NET AJAX Enabled Web Site。创建一个文件~/SubFolder/Target.aspx,内容如下:

~/SubFolder/Target.aspx
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Target Page</title>
</head>
<body>
<form />
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>

 

  然后再创建一个Global.asax,提供Application_BeginRequest方法,在其中实现Url Rewrite,如下:

Global.asax中Application_BeginRequest方法
void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext context = (sender as HttpApplication).Context;
if (context.Request.Path.Contains("Source.aspx"))
{
context.RewritePath("SubFolder/Target.aspx", false);
}
}

 

  这样,当我们访问~/Source.aspx文件时,则会被Rewrite至~/SubFolder/Target.aspx,打开页面,一切正常:

(转自老赵Jeffrey Zhao)The status code returned from the server was: 12031”。

  点击Refresh按钮之后,时间被更新 了。然后当我们再点击按钮之后,错误发生了: “Sys.WebForms.PageRequestManagerServerErrorException: An unknown eror occurred while processing the request on the server. The status code returned from the server was: 12031”。

 

分析问题:

  发生这个问题的原因是因为Url Rewrite更新了Form提交的地址,而UpdatePanel又将这地址的改变反映到了页面上。

  在第一次打开页面时,我们可以看到页面的源文件中<form />元素的action已经不是我们访问的Source.aspx,而是Url Rewrite后的目标文件:

form元素的action为目标页面
...
<form name="form1" method="post" action="SubFolder/Target.aspx" >
...
</form>
...

 

  还好我们使用了Partial Rendering,只要“目标”是正确的,UpdatePanel依旧能够正确地发送和获取数据,然后更新页面。因此,在点击Refresh按钮之后, 页面被正确更新了。可是,我们form元素的action也变了,使用Web Development Helper和IE Dev Toolbar便一目了然:

(转自老赵Jeffrey Zhao)The status code returned from the server was: 12031”。

(转自老赵Jeffrey Zhao)The status code returned from the server was: 12031”。

  由于我们在进行异步PostBack时,直 接访问了~/SubFolder/Target.aspx,因此在生成的Form对象其action值为Target.aspx。于是乎, UpdatePanel兢兢业业地将客户端form元素的action也进行了修改。这样就让我们再次提交时访问了一个不存在的页面,错误就再所难免了。

 

解决问题:

  既然发现了问题所在,那么解决起来自然也会 得心应手。我们只要在响应Sys.Application的load事件即可,它会在页面第一次加载时,以及每次Partial Rendering之后被触发,我们在这时候修改页面中form元素的action属性即可,如下:

相应Sys.Application的load事件
Sys.Application.add_load(function()
{
var form = Sys.WebForms.PageRequestManager.getInstance()._form;
form._initialAction = form.action = window.location.href;
});

  至于为什么应该这样获得页面中的form元素,_initialAction又是什么,以及为什么要设置它,就要牵涉到UpdatePanel的实现方式,在这里就不多作解释了。只要页面中放置了这么一小段代码,这个问题就被解决了。

 

深入问题:

  造成这个问题的原因,其实就是因为在Url Rewrite之后,form元素的action并非客户端请求的地址,而是Url Rewrite的目标地址。如果我们没有使用Partial Rendering,而是使用了最传统的PostBack,虽然不会造成页面功能的破坏,但是在PostBack之后,用户就会发现地址栏的内容变了,直 接变成了目标地址。这可不是我们希望看到的结果,既然Rewrite了,就把它Rewrite到底。当然,我们依然可以使用上面提到的办法,使用 JavaScript来修改form元素的action,但是这个做法实在不够“美观大方”,而且用户从HTML源文件中也可以看到我们Url Rewrite的目标地址,不是吗?

  如果我们能够在服务器端设置Form的 action就好了,可惜System.Web.UI.HtmlControls.HtmlForm类不允许我们这么做。不过还好,我们用的是 ASP.NET,我们用的是面向对象的编程模型。于是我们“继承”System.Web.UI.HtmlControls.HtmlForm,实现一个自 己的Form控件:

继承HtmlForm类实现自己的From
namespace ActionlessForm {
public class Form : System.Web.UI.HtmlControls.HtmlForm
{
protected override void RenderAttributes(HtmlTextWriter writer)
{
writer.WriteAttribute("name", this.Name);
base.Attributes.Remove("name");
writer.WriteAttribute("method", this.Method);
base.Attributes.Remove("method");
this.Attributes.Render(writer);
base.Attributes.Remove("action");
if (base.ID != null)
writer.WriteAttribute("id", base.ClientID);
}
}
}

 

  然后我们就可以在页面中使用它了。当然,在这之前,我们需要在页面(或Web.config)里注册它:

使用我们自己实现的Form
<%@ Register TagPrefix="skm" Namespace="ActionlessForm" 
Assembly="ActionlessForm" %>
...
<skm:Form >
...
</skm:Form>
...

 

  至此,我们已经不需要在页面里编写一段“巧妙”的JavaScript了,Url Rewrite之后form元素的action问题被解决了。


相关文章: