362 lines
9.6 KiB
C#
362 lines
9.6 KiB
C#
|
//
|
||
|
// System.Web.UI.HtmlControls.HtmlForm.cs
|
||
|
//
|
||
|
// Author:
|
||
|
// Dick Porter <dick@ximian.com>
|
||
|
//
|
||
|
// Copyright (C) 2005-2010 Novell, Inc (http://www.novell.com)
|
||
|
//
|
||
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||
|
// a copy of this software and associated documentation files (the
|
||
|
// "Software"), to deal in the Software without restriction, including
|
||
|
// without limitation the rights to use, copy, modify, merge, publish,
|
||
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
||
|
// permit persons to whom the Software is furnished to do so, subject to
|
||
|
// the following conditions:
|
||
|
//
|
||
|
// The above copyright notice and this permission notice shall be
|
||
|
// included in all copies or substantial portions of the Software.
|
||
|
//
|
||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
//
|
||
|
|
||
|
using System.ComponentModel;
|
||
|
using System.Collections.Specialized;
|
||
|
using System.Security.Permissions;
|
||
|
using System.Web.Util;
|
||
|
using System.Web.UI.WebControls;
|
||
|
using System.Web.Configuration;
|
||
|
using System.Web.SessionState;
|
||
|
|
||
|
namespace System.Web.UI.HtmlControls
|
||
|
{
|
||
|
// CAS
|
||
|
[AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
|
||
|
[AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
|
||
|
public class HtmlForm : HtmlContainerControl
|
||
|
{
|
||
|
bool inited;
|
||
|
string _defaultfocus;
|
||
|
string _defaultbutton;
|
||
|
bool submitdisabledcontrols = false;
|
||
|
bool? isUplevel;
|
||
|
|
||
|
public HtmlForm () : base ("form")
|
||
|
{
|
||
|
}
|
||
|
|
||
|
// LAMESPEC: This is undocumented on MSDN, but apparently it does exist on MS.NET.
|
||
|
// See https://bugzilla.novell.com/show_bug.cgi?id=442104
|
||
|
public string Action {
|
||
|
get {
|
||
|
string action = Attributes ["action"];
|
||
|
if (String.IsNullOrEmpty (action))
|
||
|
return String.Empty;
|
||
|
|
||
|
return action;
|
||
|
}
|
||
|
|
||
|
set {
|
||
|
if (String.IsNullOrEmpty (value))
|
||
|
Attributes ["action"] = null;
|
||
|
else
|
||
|
Attributes ["action"] = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[DefaultValue ("")]
|
||
|
public string DefaultButton {
|
||
|
get {
|
||
|
return _defaultbutton ?? String.Empty;
|
||
|
}
|
||
|
set {
|
||
|
_defaultbutton = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[DefaultValue ("")]
|
||
|
public string DefaultFocus {
|
||
|
get {
|
||
|
return _defaultfocus ?? String.Empty;
|
||
|
}
|
||
|
set {
|
||
|
_defaultfocus = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[DefaultValue ("")]
|
||
|
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
|
||
|
public string Enctype {
|
||
|
get {
|
||
|
string enc = Attributes["enctype"];
|
||
|
|
||
|
if (enc == null) {
|
||
|
return (String.Empty);
|
||
|
}
|
||
|
|
||
|
return (enc);
|
||
|
}
|
||
|
set {
|
||
|
if (value == null) {
|
||
|
Attributes.Remove ("enctype");
|
||
|
} else {
|
||
|
Attributes["enctype"] = value;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[DefaultValue ("")]
|
||
|
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
|
||
|
public string Method {
|
||
|
get {
|
||
|
string method = Attributes["method"];
|
||
|
|
||
|
if ((method == null) || (method.Length == 0)) {
|
||
|
return ("post");
|
||
|
}
|
||
|
|
||
|
return (method);
|
||
|
}
|
||
|
set {
|
||
|
if (value == null) {
|
||
|
Attributes.Remove ("method");
|
||
|
} else {
|
||
|
Attributes["method"] = value;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[DefaultValue ("")]
|
||
|
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
|
||
|
public virtual string Name {
|
||
|
get {
|
||
|
return UniqueID;
|
||
|
}
|
||
|
set {
|
||
|
/* why am i here? I do nothing. */
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[DefaultValue (false)]
|
||
|
public virtual bool SubmitDisabledControls {
|
||
|
get {
|
||
|
return submitdisabledcontrols;
|
||
|
}
|
||
|
set {
|
||
|
submitdisabledcontrols = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[DefaultValue ("")]
|
||
|
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
|
||
|
public string Target {
|
||
|
get {
|
||
|
string target = Attributes["target"];
|
||
|
|
||
|
if (target == null) {
|
||
|
return (String.Empty);
|
||
|
}
|
||
|
|
||
|
return (target);
|
||
|
}
|
||
|
set {
|
||
|
if (value == null) {
|
||
|
Attributes.Remove ("target");
|
||
|
} else {
|
||
|
Attributes["target"] = value;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override string UniqueID {
|
||
|
get {
|
||
|
Control container = NamingContainer;
|
||
|
if (container == Page)
|
||
|
return ID;
|
||
|
return "aspnetForm";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[MonoTODO ("why override?")]
|
||
|
protected override ControlCollection CreateControlCollection ()
|
||
|
{
|
||
|
return base.CreateControlCollection ();
|
||
|
}
|
||
|
|
||
|
protected internal override void OnInit (EventArgs e)
|
||
|
{
|
||
|
inited = true;
|
||
|
Page page = Page;
|
||
|
if (page != null) {
|
||
|
page.RegisterViewStateHandler ();
|
||
|
page.RegisterForm (this);
|
||
|
}
|
||
|
|
||
|
base.OnInit (e);
|
||
|
}
|
||
|
|
||
|
internal bool DetermineRenderUplevel ()
|
||
|
{
|
||
|
if (isUplevel != null)
|
||
|
return (bool) isUplevel;
|
||
|
|
||
|
isUplevel = UplevelHelper.IsUplevel (
|
||
|
System.Web.Configuration.HttpCapabilitiesBase.GetUserAgentForDetection (HttpContext.Current.Request));
|
||
|
return (bool) isUplevel;
|
||
|
}
|
||
|
|
||
|
protected internal override void OnPreRender (EventArgs e)
|
||
|
{
|
||
|
base.OnPreRender(e);
|
||
|
}
|
||
|
|
||
|
protected override void RenderAttributes (HtmlTextWriter w)
|
||
|
{
|
||
|
/* Need to always render: method, action and id
|
||
|
*/
|
||
|
|
||
|
string action;
|
||
|
string customAction = Attributes ["action"];
|
||
|
Page page = Page;
|
||
|
HttpRequest req = page != null ? page.RequestInternal : null;
|
||
|
if (String.IsNullOrEmpty (customAction)) {
|
||
|
string file_path = req != null ? req.ClientFilePath : null;
|
||
|
string current_path = req != null ? req.CurrentExecutionFilePath : null;
|
||
|
|
||
|
if (file_path == null)
|
||
|
action = Action;
|
||
|
else if (file_path == current_path) {
|
||
|
// Just the filename will do
|
||
|
action = UrlUtils.GetFile (file_path);
|
||
|
} else {
|
||
|
// Fun. We need to make cookieless sessions work, so no
|
||
|
// absolute paths here.
|
||
|
bool cookieless;
|
||
|
SessionStateSection sec = WebConfigurationManager.GetSection ("system.web/sessionState") as SessionStateSection;
|
||
|
cookieless = sec != null ? sec.Cookieless == HttpCookieMode.UseUri: false;
|
||
|
string appVPath = HttpRuntime.AppDomainAppVirtualPath;
|
||
|
int appVPathLen = appVPath.Length;
|
||
|
|
||
|
if (appVPathLen > 1) {
|
||
|
if (cookieless) {
|
||
|
if (StrUtils.StartsWith (file_path, appVPath, true))
|
||
|
file_path = file_path.Substring (appVPathLen + 1);
|
||
|
} else if (StrUtils.StartsWith (current_path, appVPath, true))
|
||
|
current_path = current_path.Substring (appVPathLen + 1);
|
||
|
}
|
||
|
|
||
|
if (cookieless) {
|
||
|
Uri current_uri = new Uri ("http://host" + current_path);
|
||
|
Uri fp_uri = new Uri ("http://host" + file_path);
|
||
|
action = fp_uri.MakeRelative (current_uri);
|
||
|
} else
|
||
|
action = current_path;
|
||
|
}
|
||
|
} else
|
||
|
action = customAction;
|
||
|
if (req != null)
|
||
|
action += req.QueryStringRaw;
|
||
|
if (req != null) {
|
||
|
XhtmlConformanceSection xhtml = WebConfigurationManager.GetSection ("system.web/xhtmlConformance") as XhtmlConformanceSection;
|
||
|
if (xhtml == null || xhtml.Mode != XhtmlConformanceMode.Strict)
|
||
|
if (RenderingCompatibilityLessThan40)
|
||
|
// LAMESPEC: MSDN says the 'name' attribute is rendered only in
|
||
|
// Legacy mode, this is not true.
|
||
|
w.WriteAttribute ("name", Name);
|
||
|
}
|
||
|
|
||
|
w.WriteAttribute ("method", Method);
|
||
|
if (String.IsNullOrEmpty (customAction))
|
||
|
w.WriteAttribute ("action", action, true);
|
||
|
|
||
|
/*
|
||
|
* This is a hack that guarantees the ID is set properly for HtmlControl to
|
||
|
* render it later on. As ugly as it is, we use it here because of the way
|
||
|
* the ID, ClientID and UniqueID properties work internally in our Control
|
||
|
* code.
|
||
|
*
|
||
|
* Fixes bug #82596
|
||
|
*/
|
||
|
if (ID == null) {
|
||
|
#pragma warning disable 219
|
||
|
string client = ClientID;
|
||
|
#pragma warning restore 219
|
||
|
}
|
||
|
|
||
|
string submit = page != null ? page.GetSubmitStatements () : null;
|
||
|
if (!String.IsNullOrEmpty (submit)) {
|
||
|
Attributes.Remove ("onsubmit");
|
||
|
w.WriteAttribute ("onsubmit", submit);
|
||
|
}
|
||
|
|
||
|
/* enctype and target should not be written if
|
||
|
* they are empty
|
||
|
*/
|
||
|
string enctype = Enctype;
|
||
|
if (!String.IsNullOrEmpty (enctype))
|
||
|
w.WriteAttribute ("enctype", enctype);
|
||
|
|
||
|
string target = Target;
|
||
|
if (!String.IsNullOrEmpty (target))
|
||
|
w.WriteAttribute ("target", target);
|
||
|
|
||
|
string defaultbutton = DefaultButton;
|
||
|
if (!String.IsNullOrEmpty (defaultbutton)) {
|
||
|
Control c = FindControl (defaultbutton);
|
||
|
|
||
|
if (c == null || !(c is IButtonControl))
|
||
|
throw new InvalidOperationException(String.Format ("The DefaultButton of '{0}' must be the ID of a control of type IButtonControl.",
|
||
|
ID));
|
||
|
|
||
|
if (page != null && DetermineRenderUplevel ()) {
|
||
|
w.WriteAttribute (
|
||
|
"onkeypress",
|
||
|
"javascript:return " + page.WebFormScriptReference + ".WebForm_FireDefaultButton(event, '" + c.ClientID + "')");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Now remove them from the hash so the base
|
||
|
* RenderAttributes can do all the rest
|
||
|
*/
|
||
|
Attributes.Remove ("method");
|
||
|
Attributes.Remove ("enctype");
|
||
|
Attributes.Remove ("target");
|
||
|
|
||
|
base.RenderAttributes (w);
|
||
|
}
|
||
|
|
||
|
protected internal override void RenderChildren (HtmlTextWriter w)
|
||
|
{
|
||
|
Page page = Page;
|
||
|
|
||
|
if (!inited && page != null) {
|
||
|
page.RegisterViewStateHandler ();
|
||
|
page.RegisterForm (this);
|
||
|
}
|
||
|
if (page != null)
|
||
|
page.OnFormRender (w, ClientID);
|
||
|
base.RenderChildren (w);
|
||
|
if (page != null)
|
||
|
page.OnFormPostRender (w, ClientID);
|
||
|
}
|
||
|
|
||
|
/* According to corcompare */
|
||
|
[MonoTODO ("why override?")]
|
||
|
public override void RenderControl (HtmlTextWriter w)
|
||
|
{
|
||
|
base.RenderControl (w);
|
||
|
}
|
||
|
|
||
|
protected internal override void Render (HtmlTextWriter w)
|
||
|
{
|
||
|
base.Render (w);
|
||
|
}
|
||
|
}
|
||
|
}
|