5

我正在使用带有经典 WebForms 的 ASP.NET 3.5 SP1 System.Web.Routing,如http://chriscavanagh.wordpress.com/2008/04/25/systemwebrouting-with-webforms-sample/中所述

一切正常,我有自定义的 SEO 网址,甚至回发也可以。但是有一种情况,回发总是失败,我得到:

视图状态 MAC 验证失败。如果此应用程序由 Web Farm 或集群托管,请确保配置指定相同的 validationKey 和验证算法。AutoGenerate 不能在集群中使用。

这是重现错误的场景:

  1. 使用按钮创建标准 webform mypage.aspx
  2. 创建一个将“a/b/{id}”映射到“~/mypage.aspx”的路由
  3. 当您执行该站点时,您可以浏览http://localhost:XXXX/a/b/页面工作的东西。但是当您按下按钮时,您会收到错误消息。当 Route 只是“a/{id}”时,不会发生错误。

它似乎与url中的子路径数有关。如果至少有 2 个子路径,则视图状态验证失败。

即使 EnableViewStateMac="false" 也会出现错误。

有任何想法吗?它是一个错误吗?

谢谢

4

6 回答 6

8

我通过让我的视图用户控件继承自此类而不是ViewUserControl<T>(它是 RenderView 的一种补丁)来解决此问题。它对我有用,希望它也对你有用。

public class ViewUserControlWithoutViewState<T> : ViewUserControl<T> where T : class {
    protected override void LoadViewState(object savedState) {}

    protected override object SaveControlState() {
        return null;
    }

    protected override void LoadControlState(object savedState) {}

    protected override object SaveViewState() {
        return null;
    }

    /// <summary>
    /// extracted from System.Web.Mvc.ViewUserControl
    /// </summary>
    /// <param name="viewContext"></param>
    public override void RenderView(ViewContext viewContext) {
        viewContext.HttpContext.Response.Cache.SetExpires(DateTime.Now);
        var containerPage = new ViewUserControlContainerPage(this);
        ID = Guid.NewGuid().ToString();
        RenderViewAndRestoreContentType(containerPage, viewContext);
    }

    /// <summary>
    /// extracted from System.Web.Mvc.ViewUserControl
    /// </summary>
    /// <param name="containerPage"></param>
    /// <param name="viewContext"></param>
    public static void RenderViewAndRestoreContentType(ViewPage containerPage, ViewContext viewContext) {
        string contentType = viewContext.HttpContext.Response.ContentType;
        containerPage.RenderView(viewContext);
        viewContext.HttpContext.Response.ContentType = contentType;
    }

    /// <summary>
    /// Extracted from System.Web.Mvc.ViewUserControl+ViewUserControlContainerPage
    /// </summary>
    private sealed class ViewUserControlContainerPage : ViewPage {
        // Methods
        public ViewUserControlContainerPage(ViewUserControl userControl) {
            Controls.Add(userControl);
            EnableViewState = false;
        }

        protected override object LoadPageStateFromPersistenceMedium() {
            return null;
        }

        protected override void SavePageStateToPersistenceMedium(object state) {}
    }
}

前段时间我在博客上写过这个。

于 2009-02-17T16:22:03.463 回答
1

Microsoft Connect 上的此问题:

http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=393619

于 2009-02-17T16:18:32.803 回答
1

我还在 asp.net mvc beta 中发现了这个错误。它可以非常重现。使用默认模板创建asp.net mvc应用程序后,在设计视图的home.aspx页面中添加一个asp:button控件,按f5,主页正常显示。单击按钮,将显示此错误。对mvc源码进行了一些调试,发现是site.master页面中的ViewUserControl引起的,只需注释掉<%Html.RenderPartial("LoginUserControl"); %>,那么点击事件就可以正常处理了。

我还发现像 enableViewStateMac="false" enableEventValidation="false" viewStateEncryptionMode="Never" 这样的设置没有用。

在 mvc 源代码中,以下部分处理 ViewUserControl 渲染

公共虚拟无效渲染视图(ViewContext viewContext){

// TODO: Remove this hack. Without it, the browser appears to always load cached output
viewContext.HttpContext.Response.Cache.SetExpires(DateTime.Now);
**ViewUserControlContainerPage containerPage = new ViewUserControlContainerPage(this);**
// Tracing requires Page IDs to be unique.
ID = Guid.NewGuid().ToString();
containerPage.RenderView(viewContext);

}

私有密封类 ViewUserControlContainerPage : ViewPage {

public ViewUserControlContainerPage(ViewUserControl userControl) {
    Controls.Add(userControl);
}

}

ViewUserControl 始终呈现在新创建的容器页面中,此页面不会选择您的设置。事实上,如果进入本节,手动将 container.enableViewStateMac 更改为 false,确实有助于消除错误。所以解决它的唯一方法是要求微软更改 mvc 代码。

于 2009-01-09T22:02:39.420 回答
0

我有同样的问题,我有一些流氓

<form></form>

标签,一旦我将它们从我的页面中删除,错误就不再出现了。

于 2008-11-21T03:44:27.183 回答
0

只需尝试清除本地计算机上的 cookie。有同样的问题,这有帮助。

于 2010-04-27T13:33:17.407 回答
-3

您是否将 Safari 用作浏览器?如果是这样,那么这可能是大浮动的问题。去掉那个浮子,一切都会好起来的。

于 2008-10-23T14:47:58.013 回答