好的,乔恩,首先是视图状态问题:
我没有检查自 2.0 以来是否有任何内部代码更改,但这是我几年前处理摆脱视图状态的方式。实际上,该隐藏字段在 HtmlForm 中是硬编码的,因此您应该派生新的字段并自行进行调用并进入其渲染。请注意,如果您坚持使用普通的旧输入控件,您也可以将 __eventtarget 和 __eventtarget 排除在外(我想您会想要这样做,因为它也有助于在客户端上不需要 JS):
protected override void RenderChildren(System.Web.UI.HtmlTextWriter writer)
{
System.Web.UI.Page page = this.Page;
if (page != null)
{
onFormRender.Invoke(page, null);
writer.Write("<div><input type=\"hidden\" name=\"__eventtarget\" id=\"__eventtarget\" value=\"\" /><input type=\"hidden\" name=\"__eventargument\" id=\"__eventargument\" value=\"\" /></div>");
}
ICollection controls = (this.Controls as ICollection);
renderChildrenInternal.Invoke(this, new object[] {writer, controls});
if (page != null)
onFormPostRender.Invoke(page, null);
}
所以你得到那 3 个静态 MethodInfo 并把它们叫出来,跳过那个 viewstate 部分;)
static MethodInfo onFormRender;
static MethodInfo renderChildrenInternal;
static MethodInfo onFormPostRender;
这是您表单的类型构造函数:
static Form()
{
Type aspNetPageType = typeof(System.Web.UI.Page);
onFormRender = aspNetPageType.GetMethod("OnFormRender", BindingFlags.Instance | BindingFlags.NonPublic);
renderChildrenInternal = typeof(System.Web.UI.Control).GetMethod("RenderChildrenInternal", BindingFlags.Instance | BindingFlags.NonPublic);
onFormPostRender = aspNetPageType.GetMethod("OnFormPostRender", BindingFlags.Instance | BindingFlags.NonPublic);
}
如果我的问题是正确的,那么您也不想使用 POST 作为表单的操作,因此您可以这样做:
protected override void RenderAttributes(System.Web.UI.HtmlTextWriter writer)
{
writer.WriteAttribute("method", "get");
base.Attributes.Remove("method");
// the rest of it...
}
我想这差不多。让我知道事情的后续。
编辑:我忘记了页面视图状态方法:
因此,您的自定义表单:HtmlForm 获得了全新的抽象(或没有)页面:System.Web.UI.Page:P
protected override sealed object SaveViewState()
{
return null;
}
protected override sealed void SavePageStateToPersistenceMedium(object state)
{
}
protected override sealed void LoadViewState(object savedState)
{
}
protected override sealed object LoadPageStateFromPersistenceMedium()
{
return null;
}
在这种情况下,我会密封方法,因为您无法密封页面(即使它不是抽象的,Scott Guthrie 也会将其包装成另一个:P),但您可以密封您的表单。