I'm using the ASP.NET 3.5 SP1 System.Web.Routing with classic WebForms, as described in http://chriscavanagh.wordpress.com/2008/04/25/systemwebrouting-with-webforms-sample/
All works fine, I have custom SEO urls and even the postback works. But there is a case where the postback always fails and I get a:
Validation of viewstate MAC failed. If this application is hosted by a Web Farm or cluster, ensure that configuration specifies the same validationKey and validation algorithm. AutoGenerate cannot be used in a cluster.
Here is the scenario to reproduce the error:
- Create a standard webform mypage.aspx with a button
- Create a Route that maps "a/b/{id}" to "~/mypage.aspx"
- When you execute the site, you can navigate http://localhost:XXXX/a/b/something the page works. But when you press the button you get the error. The error doen't happen when the Route is just "a/{id}".
It seems to be related to the number of sub-paths in the url. If there are at least 2 sub-paths the viewstate validation fails.
You get the error even with EnableViewStateMac="false".
Any ideas? Is it a bug?
Thanks
I worked around this by having my view user control inherit from this class instead of ViewUserControl<T>
(it's kind of a patch for RenderView). It did the trick for me, hopefully it works for you too.
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) {}
}
}
I blogged about this some time ago.
I also found this bug in asp.net mvc beta. It can be very reproduced. After create asp.net mvc application using the default template, add a asp:button control to page home.aspx in design view, hit f5, the home page is displayed properly. click the button, this error will show up. After some debugging into the mvc source code, I found it is caused by the ViewUserControl in site.master page, just comment the <% Html.RenderPartial("LoginUserControl"); %>, then the click event can be handled properly.
I also found that setting like enableViewStateMac="false" enableEventValidation="false" viewStateEncryptionMode="Never" is not useful.
In the mvc source code the following section handle the ViewUserControl rendering
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);
}
private sealed class ViewUserControlContainerPage : ViewPage {
public ViewUserControlContainerPage(ViewUserControl userControl) {
Controls.Add(userControl);
}
}
the ViewUserControl always render in a newly created container page, this page will not pick your setting. In fact if step to this section, manually change the container.enableViewStateMac to false, does help to kill the error. So the only way to solve it is to ask Microsoft to change the mvc code.
This issue on Microsoft Connect:
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=393619
I had this same issue, I had some rogue
<form></form>
Tags, once I removed them from my page the error no longer came up.
Just try to clear cookies on your local machine. Had same issue and this helped.
Are you using safari as a browser? if so then this will probably be a problem with a large float. Remove that float and things will work fine.
来源:https://stackoverflow.com/questions/230014/postback-not-working-with-asp-net-routing-validation-of-viewstate-mac-failed