阿不

潜水

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  212 随笔 :: 0 文章 :: 3070 评论 :: 75 引用

在即将发布的Kooboo CMS 2.1.0.0中,将会升级到ASP.NET MVC 2。需要将所有的Module也同步升级到MVC2,在升级过程中发现MVC2一旦进入View输出阶段后,Response.Clear将会不起作用(Controller执行阶段,这个方法仍然正常工作),这将会影响Kooboo  CMS Module的正常运行。

在确定是MVC 2引起的问题后,于是就从Response.Clear这个方法着手,它的代码逻辑如下:

public void Clear()
{
    if (this.UsingHttpWriter)
    {
        this._httpWriter.ClearBuffers();
    }
    IIS7WorkerRequest wr = this._wr as IIS7WorkerRequest;
    if (wr != null)
    {
        this.ClearNativeResponse(true, false, wr);
    }
}
从这段代码,我们可以发现,ClearBuffer的条件是UsingHttpWriter这个属性的值为True,下面是UsingHttpWriter属性的原型定义:
private bool UsingHttpWriter
{
    get
    {
        return ((this._httpWriter != null) && (this._writer == this._httpWriter));
    }
}

在这里判断,_httpWriter和_writer变量是否相同。于是我就只能从运行时的调试来看看这两个变量的值分别是什么,下面的截图分别是_httpWriter,_writer,UsingHttpWriter运行时的值:

Capture

 

在这里我们会发现UsingHttpWriter的值为fase,并且_writer的对象类型为System.Web.Mvc.ViewPage.SwitchWriter,此时我们就可以断定Response.Clear起作用的原因就是由SwitchWriter这个类为引起的。找到这个类,我们会发现它在ViewPage.RenderView(ViewContext viewContext)方法中被使用:

public virtual void RenderView(ViewContext viewContext)
{
    this.ViewContext = viewContext;
    this.InitHelpers();
    bool flag = false;
    SwitchWriter output = viewContext.HttpContext.Response.Output as SwitchWriter;
    if (output == null)
    {
        output = new SwitchWriter();
        flag = true;
    }
    using (output.Scope(viewContext.Writer))
    {
        if (flag)
        {
            int num = _nextId;
            try
            {
                _nextId = 0;
                viewContext.HttpContext.Server.Execute(HttpHandlerUtil.WrapForServerExecute(this), output, true);
                return;
            }
            finally
            {
                _nextId = num;
            }
        }
        this.ProcessRequest(HttpContext.Current);
    }
}

而对应的方法在MVC 1.0中,它的实现是这样的:

public virtual void RenderView(ViewContext viewContext)
{
    this.ViewContext = viewContext;
    this.InitHelpers();
    this.ID = Guid.NewGuid().ToString();
    this.ProcessRequest(HttpContext.Current);
}

于是我们就找到解决这个问题的办法了,我们只要在我们项目的ViewPage中,重新RenderView(ViewContext viewContext)这个方法, 让它回到原来的实现就可以解决这个问题了。

这个问题解决了,但是另一个问题我现在仍在思考当中,为什么在MVC2中,要增加SwitchWriter这个类呢?我仔细了看了好几遍这个类的实现,只是对TextWriter的简单包装而已,并没有增加其它额外的功能。我目前实在还是想不明白为什么要这样做?

posted on 2010-03-30 18:58 阿不 阅读(...) 评论(...) 编辑 收藏