htmlcontrolconverter.cs

来自「AJAX开发工具包」· CS 代码 · 共 155 行

CS
155
字号
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

namespace AjaxPro
{
	/// <summary>
	/// Provides methods to serialize and deserialize an object that is inherited from HtmlControl.
	/// </summary>
	public class HtmlControlConverter : IJavaScriptConverter
	{
		public HtmlControlConverter() : base()
		{
		}

		public override object Deserialize(IJavaScriptObject o, Type t)
		{
			if(!typeof(HtmlControl).IsAssignableFrom(t) || !(o is JavaScriptString))
				throw new NotSupportedException();

			return HtmlControlFromString(o.ToString(), t);
		}

		public override string Serialize(object o)
		{
			if(!(o is Control))
				throw new NotSupportedException();

			return HtmlControlToString((HtmlControl)o);
		}

		public override Type[] SerializableTypes
		{
			get
			{
				return new Type[]
				{
					typeof(HtmlControl),
					typeof(HtmlAnchor),
					typeof(HtmlButton),
					typeof(HtmlImage),
					typeof(HtmlInputButton),
					typeof(HtmlInputCheckBox),
					typeof(HtmlInputRadioButton),
					typeof(HtmlInputText),
					typeof(HtmlSelect),
					typeof(HtmlTableCell),
					typeof(HtmlTable),
					typeof(HtmlTableRow),
					typeof(HtmlTextArea)
				};
			}
		}

		public override Type[] DeserializableTypes
		{
			get
			{
				return this.SerializableTypes;
			}
		}

		#region Internal Methods

		internal static string CorrectAttributes(string input)
		{
			string s = @"selected=""selected""";
			Regex r = new Regex(s, RegexOptions.Singleline | RegexOptions.IgnoreCase);
			input =  r.Replace(input, @"selected=""true""");

			s = @"multiple=""multiple""";
			r = new Regex(s, RegexOptions.Singleline | RegexOptions.IgnoreCase);
			input =  r.Replace(input, @"multiple=""true""");

			s = @"disabled=""disabled""";
			r = new Regex(s, RegexOptions.Singleline | RegexOptions.IgnoreCase);
			input =  r.Replace(input, @"disabled=""true""");

			return input;
		}

		internal static string HtmlControlToString(HtmlControl control)
		{
			StringWriter writer = new StringWriter(new StringBuilder());
			
			control.RenderControl(new HtmlTextWriter(writer));

			return JavaScriptSerializer.SerializeString(writer.ToString());    
		}

		internal static HtmlControl HtmlControlFromString(string html, Type type)
		{
			if(!typeof(HtmlControl).IsAssignableFrom(type))
				throw new InvalidCastException("The target type is not a HtmlControlType");

			html = AddRunAtServer(html, (Activator.CreateInstance(type) as HtmlControl).TagName);

			if(type.IsAssignableFrom(typeof(HtmlSelect)))
				html = CorrectAttributes(html);

			Control o = HtmlControlConverterHelper.Parse(html);;
			
			if(o.GetType() == type)
				return (o as HtmlControl);
			else
			{
				foreach(Control con in o.Controls)
				{
					if(con.GetType() == type)
					{
						return (con as HtmlControl);
					}
				}
			}

			return null;
		}

		internal static string AddRunAtServer(string input, string tagName)
		{
			// <select[^>]*?(?<InsertPos>\s*)>
			string pattern = "<" + Regex.Escape(tagName) + @"[^>]*?(?<InsertPos>\s*)/?>";
			Regex regEx = new Regex(pattern, RegexOptions.Singleline | RegexOptions.IgnoreCase);
			Match match = regEx.Match(input);

			if (match.Success)
			{
				Group group = match.Groups["InsertPos"];
				return input.Insert(group.Index + group.Length, " runat=\"server\"");
			}
			else
				return input;
		}

		#endregion
	}

	internal class HtmlControlConverterHelper : TemplateControl
	{
		internal static Control Parse(string controlString)
		{
			HtmlControlConverterHelper control = new HtmlControlConverterHelper();
#if(NET20)
			control.AppRelativeVirtualPath = "~";
#endif

			return control.ParseControl(controlString);
		}
	}
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?