我正在使用 ASP.NET 3.5 SP1 System.Web.Routing 和经典WebForms,如 http://chriscavanagh.wordpress.com/2008/04/25/systemwebrouting-with-webforms-sample/中所述
一切正常,我有自定义的SEO网址,甚至回发都可以工作。但是在某些情况下,回发总是失败,我得到:
视图状态 MAC 验证失败。如果此应用程序由 Web 场或群集承载,请确保配置指定相同的验证密钥和验证算法。自动生成不能在群集中使用。
以下是重现错误的方案:
- 使用按钮创建标准 Web 表单我的页面.aspx
- 创建一个将"a/b/{id}"映射到"~/mypage.aspx"的路由
- 当您执行站点时,您可以导航 http://localhost:XXXX/a/b/页面工作的内容。但是当您按下按钮时,会出现错误。当路由只是"a/{id}"时,不会发生错误。
这似乎与 url 中的子路径数量有关。如果至少有 2 个子路径,则视图状态验证将失败。
即使使用 EnableViewStateMac="false",您也会收到错误。
有什么想法吗?这是一个错误吗?
谢谢
我通过让我的视图用户控件继承从这个类而不是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) {}
}
}
我前段时间在博客上写过这个。
我也在 mvc 测试版 asp.net 发现了这个错误。它可以非常复制。使用默认模板创建 asp.net mvc 应用程序后,将 asp:button 控件添加到页面主页.aspx在设计视图中,按 f5,主页正确显示。单击按钮,将显示此错误。在对 mvc 源代码进行一些调试后,我发现它是由 site.master 页中的 ViewUserControl 引起的,只需注释 <% Html.RenderPartial("LoginUserControl");%>,则可以正确处理单击事件。
我还发现像enableViewStateMac="false"这样的设置enableEventValidation="false"viewStateEncryptionMode="Never"是没有用的。
在 mvc 源代码中,以下部分处理 ViewUserControl 呈现
public virtual void RenderView(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);
}
私有密封类 查看用户控件容器页面 : 查看页 {
public ViewUserControlContainerPage(ViewUserControl userControl) {
Controls.Add(userControl);
}
}
ViewUserControl 始终在新创建的容器页面中呈现,此页面不会选择您的设置。事实上,如果转到本节,手动将容器.enableViewStateMac 更改为 false,确实有助于消除错误。所以解决它的唯一方法是要求Microsoft更改 mvc 代码。
Microsoft Connect上的此问题:
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=393619
我有同样的问题,我有一些流氓
<form></form>
标签,一旦我从页面中删除它们,错误就不再出现。
只需尝试清除本地计算机上的cookie即可。有同样的问题,这有帮助。
您是否使用 safari 作为浏览器? 如果是这样,那么这可能是大型浮点数的问题。删除该浮动,一切将正常工作。