好的 Jon,首先讲解viewstate问题:
我没有检查过自2.0版本以来是否有任何内部代码更改,但这是我几年前处理viewstate的方法。实际上,该隐藏字段是在HtmlForm中硬编码的,因此您应该派生出您的新字段,并进入其渲染,自己进行调用。请注意,如果您坚持使用纯旧的输入控件(我猜您想这样做,因为它还可以帮助不需要客户端JS),您也可以将__eventtarget和__eventtarget排除在外:
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");
}
我想这就是全部了。让我知道进展如何。
编辑:我忘记了页面视图状态方法:
因此,您的自定义表单: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),但您可以封装您的表单。