D:/Projects/Anthem/Anthem/Manager.cs

00001 using System;
00002 using System.Collections;
00003 using System.Collections.Specialized;
00004 using System.Configuration;
00005 using System.Data;
00006 using System.IO;
00007 using System.Globalization;
00008 using System.Reflection;
00009 using System.Runtime.Serialization;
00010 using System.Text;
00011 using System.Text.RegularExpressions;
00012 using System.Web;
00013 using System.Web.UI;
00014 using System.Web.UI.HtmlControls;
00015 using ASP = System.Web.UI.WebControls;
00016 
00017 #if V2
00018 using System.Web.Configuration;
00019 #if !DEBUG
00020 [assembly: WebResource("Anthem.Anthem.js", "text/javascript")]
00021 #endif
00022 #endif
00023 
00024 namespace Anthem
00025 {
00030     public class Manager
00031     {
00032         #region Public Static Properties
00033 
00037         public static string CallBackID
00038         {
00039             get
00040             {
00041                 return HttpContext.Current.Request.Form["Anthem_CallBackID"];
00042             }
00043         }
00044 
00048         public static string CallBackMethod
00049         {
00050             get
00051             {
00052                 return HttpContext.Current.Request.Form["Anthem_CallBackMethod"];
00053             }
00054         }
00055 
00060         public static string CallBackType
00061         {
00062             get
00063             {
00064                 return HttpContext.Current.Request.Form["Anthem_CallBackType"];
00065             }
00066         }
00067 
00068         private static bool _includePageScripts = false;
00074         public static bool IncludePageScripts
00075         {
00076             get
00077             {
00078                 if (!_includePageScripts)
00079                 {
00080                     string appSetting = string.Empty;
00081 #if V2
00082                     appSetting = WebConfigurationManager.AppSettings["Anthem.IncludePageScripts"];
00083 #else
00084                     appSetting = ConfigurationSettings.AppSettings["Anthem.IncludePageScripts"];
00085 #endif
00086                     if (null != appSetting && string.Empty != appSetting)
00087                         _includePageScripts = bool.Parse(appSetting);
00088                 }
00089                 return _includePageScripts;
00090             }
00091             set { _includePageScripts = value; }
00092         }
00093 
00097         public static bool IsCallBack
00098         {
00099             get
00100             {
00101                 HttpContext context = HttpContext.Current;
00102                 if (context != null)
00103                 {
00104                     string callback = context.Request.Params["Anthem_CallBack"];
00105                     if (callback != null)
00106                     {
00107                         // If Anthem_CallBack appears multiple times, Params will return
00108                         // all values joined with a comma. For example "true,true". We
00109                         // are only interested in the first value.
00110                         if (callback.IndexOf(",") != -1) callback = callback.Split(',')[0];
00111                         return string.Compare(callback, "true", true) == 0;
00112                     }
00113                 }
00114                 return false;
00115             }
00116         }
00117 
00118         #endregion
00119 
00120         #region Public Static Methods
00121 
00130         public static void AddScriptAttribute(ASP.WebControl control, string attributeName, string script)
00131         {
00132             bool enableCallBack = !(control is ICallBackControl)
00133                 || ((ICallBackControl)control).EnableCallBack;
00134 
00135             if (enableCallBack)
00136             {
00137                 string newValue = script;
00138                 string oldValue = control.Attributes[attributeName];
00139                 if (oldValue != null && !oldValue.Equals(newValue))
00140                 {
00141                     newValue = GetStringEndingWithSemicolon(oldValue) + script;
00142                 }
00143                 control.Attributes[attributeName] = newValue;
00144             }
00145         }
00146 
00152         public static void AddScriptAttribute(ASP.WebControl control, ASP.ListItem item, string attributeName, string script)
00153         {
00154             bool enableCallBack = !(control is ICallBackControl)
00155                 || ((ICallBackControl)control).EnableCallBack;
00156 
00157             if (enableCallBack)
00158             {
00159                 string newValue = script;
00160                 string oldValue = item.Attributes[attributeName];
00161                 if (oldValue != null && !oldValue.Equals(newValue))
00162                 {
00163                     newValue = GetStringEndingWithSemicolon(oldValue) + script;
00164                 }
00165                 item.Attributes[attributeName] = newValue;
00166             }
00167         }
00168 
00180         public static void AddScriptForClientSideEval(string script)
00181         {
00182             GetManager()._clientSideEvalScripts.Add(script);
00183         }
00184 
00189         public static string GetCallbackEventReference(ICallBackControl control, bool causesValidation, string validationGroup)
00190         {
00191             return GetCallbackEventReference(control, string.Empty, causesValidation, validationGroup, string.Empty);
00192         }
00193 
00198         public static string GetCallbackEventReference(ICallBackControl control, string argument, bool causesValidation, string validationGroup)
00199         {
00200             return GetCallbackEventReference(control, argument, causesValidation, validationGroup, string.Empty);
00201         }
00202 
00207         public static string GetCallbackEventReference(ICallBackControl control, bool causesValidation, string validationGroup, string imageDuringCallback)
00208         {
00209             return GetCallbackEventReference(control, string.Empty, causesValidation, validationGroup, imageDuringCallback);
00210         }
00211 
00216         public static string GetCallbackEventReference(ICallBackControl control, string argument, bool causesValidation, string validationGroup, string imageDuringCallback)
00217         {
00218             return string.Format(
00219                 "javascript:Anthem_FireCallBackEvent(this,event,'{0}','{1}',{2},'{3}','{4}','{5}',{6},{7},{8},{9},true,true);",
00220                 ((Control)control).UniqueID,
00221                 argument,
00222                 causesValidation ? "true" : "false",
00223                 validationGroup,
00224                 imageDuringCallback,
00225                 control.TextDuringCallBack,
00226                 control.EnabledDuringCallBack ? "true" : "false",
00227                 (control.PreCallBackFunction == null || control.PreCallBackFunction.Length == 0) ? "null" : control.PreCallBackFunction,
00228                 (control.PostCallBackFunction == null || control.PostCallBackFunction.Length == 0) ? "null" : control.PostCallBackFunction,
00229                 (control.CallBackCancelledFunction == null || control.CallBackCancelledFunction.Length == 0) ? "null" : control.CallBackCancelledFunction
00230             );
00231         }
00232 
00234         public static bool GetControlVisible(Control control, StateBag viewstate, bool designMode)
00235         {
00236             if (null == viewstate["AnthemVisible"] || (bool)viewstate["AnthemVisible"])
00237             {
00238                 if (null != control.Parent && !designMode)
00239                     return control.Parent.Visible;
00240                 return true;
00241             }
00242             return false;
00243         }
00244 
00246         public static Manager GetManager()
00247         {
00248             Manager manager = HttpContext.Current.Items[GetAnthemManagerKey()] as Manager;
00249             if (manager == null)
00250                 throw new ApplicationException("This page was never registered with Anthem.Manager!");
00251             return manager;
00252         }
00253 
00255         public static string GetStringEndingWithSemicolon(string value)
00256         {
00257             if (value != null)
00258             {
00259                 int length = value.Length;
00260                 if (length > 0 && value[length - 1] != ';')
00261                 {
00262                     return value + ";";
00263                 }
00264             }
00265             return value;
00266         }
00267 
00269         public static void Register(Page page)
00270         {
00271             Register(page, page);
00272         }
00273 
00275         public static void Register(Control control)
00276         {
00277             Register(control.Page, control);
00278         }
00279 
00280 #if V2
00305         public static void RegisterClientScriptBlock(Type type, String key, String script)
00306         {
00307             RegisterClientScriptBlock(type, key, script, false);
00308         }
00309 
00337         public static void RegisterClientScriptBlock(Type type, String key, String script, Boolean addScriptTags)
00338         {
00339             Page page = HttpContext.Current.Handler as Page;
00340             if (page != null)
00341             {
00342                 page.ClientScript.RegisterClientScriptBlock(type, key, script, addScriptTags);
00343             }
00344             RegisterPageScriptBlock(key, script);
00345         }
00346 #else
00369         public static void RegisterClientScriptBlock(String key, String script)
00370         {
00371             Page page = HttpContext.Current.Handler as Page;
00372             if (page != null)
00373             {
00374                 page.RegisterClientScriptBlock(key, script);
00375             }
00376             RegisterPageScriptBlock(key, script);
00377         }
00378 #endif
00379 
00395         public static void RegisterClientScriptInclude(String key, String url)
00396         {
00397 #if V2
00398             RegisterClientScriptInclude(typeof(Page), key, url);
00399 #else
00400             Page page = HttpContext.Current.Handler as Page;
00401             if (page != null)
00402             {
00403                 string script = string.Format("<script src=\"{0}\" type=\"text/javascript\"></script>", url);
00404                 page.RegisterClientScriptBlock(key, script);
00405             }
00406             RegisterPageScriptBlock(key, "src=" + url);
00407 
00408 #endif
00409         }
00410 
00411 #if V2
00431         public static void RegisterClientScriptInclude(Type type, String key, String url)
00432         {
00433             Page page = HttpContext.Current.Handler as Page;
00434             if (page != null)
00435             {
00436                 page.ClientScript.RegisterClientScriptInclude(type, key, url);
00437             }
00438             RegisterPageScriptBlock(key, "src=" + url);
00439         }
00440 #endif
00441 #if V2
00455         public static void RegisterClientScriptResource(Type type, String resourceName)
00456         {
00457             Page page = HttpContext.Current.Handler as Page;
00458             if (page != null)
00459             {
00460                 page.ClientScript.RegisterClientScriptResource(type, resourceName);
00461             }
00462             RegisterPageScriptBlock(resourceName, "src=" + page.ClientScript.GetWebResourceUrl(type, resourceName));
00463         }
00464 #endif
00465 
00485         public static void RegisterPageScriptBlock(string key, string script)
00486         {
00487             GetManager()._pageScripts[key] = script;
00488         }
00489 
00490 #if V2
00515         public static void RegisterStartupScript(Type type, String key, String script)
00516         {
00517             RegisterStartupScript(type, key, script, false);
00518         }
00519 
00547         public static void RegisterStartupScript(Type type, String key, String script, Boolean addScriptTags)
00548         {
00549             Page page = HttpContext.Current.Handler as Page;
00550             if (page != null)
00551             {
00552                 page.ClientScript.RegisterStartupScript(type, key, script, addScriptTags);
00553             }
00554             RegisterPageScriptBlock(key, script);
00555         }
00556 #else
00579         public static void RegisterStartupScript(String key, String script)
00580         {
00581             Page page = HttpContext.Current.Handler as Page;
00582             if (page != null)
00583             {
00584                 page.RegisterStartupScript(key, script);
00585             }
00586             RegisterPageScriptBlock(key, script);
00587         }
00588 #endif
00589 
00591         public static void SetControlVisible(StateBag viewState, bool value)
00592         {
00593             viewState["AnthemVisible"] = value;
00594         }
00595 
00607         public static void WriteBeginControlMarker(HtmlTextWriter writer, string parentTagName, Control control)
00608         {
00609             writer.Write("<{0} id=\"{1}\">", parentTagName, "Anthem_" + control.ClientID + "__");
00610             IUpdatableControl updatableControl = control as IUpdatableControl;
00611             if (updatableControl != null && updatableControl.UpdateAfterCallBack && IsCallBack)
00612             {
00613                 writer.Write(_beginControlMarker);
00614                 writer.Write(GetUniqueIDWithDollars(control));
00615                 writer.Write("-->");
00616             }
00617         }
00618 
00627         public static void WriteEndControlMarker(HtmlTextWriter writer, string parentTagName, Control control)
00628         {
00629             IUpdatableControl updatableControl = control as IUpdatableControl;
00630             if (updatableControl != null && updatableControl.UpdateAfterCallBack && IsCallBack)
00631             {
00632                 writer.Write(_endControlMarker);
00633                 writer.Write(GetUniqueIDWithDollars(control));
00634                 writer.Write("-->");
00635             }
00636             writer.Write("</{0}>", parentTagName);
00637         }
00638 
00640         public static void WriteResult(HttpResponse resp, object val, string error)
00641         {
00642             StringBuilder sb = new StringBuilder();
00643             try
00644             {
00645                 WriteValueAndError(sb, val, error, null, null, null, null, null);
00646             }
00647             catch (Exception ex)
00648             {
00649                 // If an exception was thrown while formatting the
00650                 // result value, we need to discard whatever was
00651                 // written and start over with nothing but the error
00652                 // message.
00653                 sb.Length = 0;
00654                 WriteValueAndError(sb, null, ex.Message, null, null, null, null, null);
00655             }
00656             resp.Write(sb.ToString());
00657         }
00658 
00663         public static void WriteValue(StringBuilder sb, object val)
00664         {
00665             if (val == null || val == System.DBNull.Value)
00666             {
00667                 sb.Append("null");
00668             }
00669             else if (val is string || val is Guid)
00670             {
00671                 WriteString(sb, val.ToString());
00672             }
00673             else if (val is bool)
00674             {
00675                 sb.Append(val.ToString().ToLower());
00676             }
00677             else if (val is double ||
00678                 val is float ||
00679                 val is long ||
00680                 val is int ||
00681                 val is short ||
00682                 val is byte ||
00683                 val is decimal)
00684             {
00685                 sb.AppendFormat(CultureInfo.InvariantCulture.NumberFormat, "{0}", val);
00686             }
00687             else if (val.GetType().IsEnum)
00688             {
00689                 sb.Append((int)val);
00690             }
00691             else if (val is DateTime)
00692             {
00693                 sb.Append("new Date(\"");
00694                 sb.Append(((DateTime)val).ToString("MMMM, d yyyy HH:mm:ss", new CultureInfo("en-US", false).DateTimeFormat));
00695                 sb.Append("\")");
00696             }
00697             else if (val is DataSet)
00698             {
00699                 WriteDataSet(sb, val as DataSet);
00700             }
00701             else if (val is DataTable)
00702             {
00703                 WriteDataTable(sb, val as DataTable);
00704             }
00705             else if (val is DataRow)
00706             {
00707                 WriteDataRow(sb, val as DataRow);
00708             }
00709             else if (val is Hashtable)
00710             {
00711                 WriteHashtable(sb, val as Hashtable);
00712             }
00713             else if (val is IEnumerable)
00714             {
00715                 WriteEnumerable(sb, val as IEnumerable);
00716             }
00717             else
00718             {
00719                 WriteObject(sb, val);
00720             }
00721         }
00722 
00723         #endregion
00724 
00725         #region Private Static Methods
00726 
00727         private static void AddManager(Page page)
00728         {
00729             Manager manager = HttpContext.Current.Items[GetAnthemManagerKey()] as Manager;
00730             if (manager == null)
00731             {
00732                 manager = new Manager();
00733                 page.PreRender += new EventHandler(manager.OnPreRender);
00734                 page.Error += new EventHandler(manager.OnError);
00735                 page.Unload += new EventHandler(manager.OnUnload);
00736                 manager._targets[GetAnthemManagerKey()] = manager;
00737                 HttpContext.Current.Items[GetAnthemManagerKey()] = manager;
00738             }
00739             manager.RegisterPageScript(page);
00740         }
00741 
00742         private static object[] ConvertParameters(MethodInfo methodInfo, HttpRequest req)
00743         {
00744             object[] parameters = new object[methodInfo.GetParameters().Length];
00745             int i = 0;
00746             foreach (ParameterInfo paramInfo in methodInfo.GetParameters())
00747             {
00748                 object param = null;
00749                 string paramValue = req.Form["Anthem_CallBackArgument" + i];
00750                 if (paramValue != null)
00751                 {
00752                     if (paramInfo.ParameterType.IsArray)
00753                     {
00754                         Type type = paramInfo.ParameterType.GetElementType();
00755                         string[] values = req.Form.GetValues("Anthem_CallBackArgument" + i);
00756                         Array array = Array.CreateInstance(type, values.Length);
00757                         for (int index = 0; index < values.Length; index++)
00758                         {
00759                             array.SetValue(Convert.ChangeType(values[index], type), index);
00760                         }
00761                         param = array;
00762                     }
00763                     else
00764                     {
00765                         param = Convert.ChangeType(paramValue, paramInfo.ParameterType);
00766                     }
00767                 }
00768                 parameters[i] = param;
00769                 ++i;
00770             }
00771             return parameters;
00772         }
00773 
00774         private static HtmlForm FindForm(Control parent)
00775         {
00776             foreach (Control child in parent.Controls)
00777             {
00778                 HtmlForm form = child as HtmlForm;
00779                 if (form != null && form.Visible)
00780                 {
00781                     return form;
00782                 }
00783                 if (child.HasControls())
00784                 {
00785                     HtmlForm htmlForm = FindForm(child);
00786                     if (htmlForm != null)
00787                     {
00788                         return htmlForm;
00789                     }
00790                 }
00791             }
00792             return null;
00793         }
00794 
00795         private static MethodInfo FindTargetMethod(object target, string methodName)
00796         {
00797             Type type = target.GetType();
00798             MethodInfo methodInfo = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
00799             if (methodInfo != null)
00800             {
00801                 object[] methodAttributes = methodInfo.GetCustomAttributes(typeof(Anthem.MethodAttribute), true);
00802                 if (methodAttributes.Length > 0)
00803                 {
00804                     return methodInfo;
00805                 }
00806             }
00807             return null;
00808         }
00809 
00810         private static string GetAnthemManagerKey()
00811         {
00812             Page page = HttpContext.Current.Handler as Page;
00813             if (page == null)
00814             {
00815                 return "Anthem.Manager.Handler";
00816             }
00817             else
00818             {
00819                 return "Anthem.Manager." + page.ToString();
00820             }
00821         }
00822 
00823         private static string GetFormID(Control control)
00824         {
00825             HtmlForm form = FindForm(control.Page);
00826             if (form != null)
00827             {
00828                 return form.ClientID;
00829             }
00830             return null;
00831         }
00832 
00833         private static string GetPageURL(HttpContext context)
00834         {
00835             string url = null;
00836             string currentExecutionFilePath = context.Request.CurrentExecutionFilePath;
00837             string filePath = context.Request.FilePath;
00838             if (string.Compare(currentExecutionFilePath, filePath, true) == 0)
00839             {
00840                 url = currentExecutionFilePath;
00841             }
00842             else
00843             {
00844                 Uri from = new Uri("file://foo" + filePath);
00845                 Uri to = new Uri("file://foo" + currentExecutionFilePath);
00846 #if V2
00847                 url = from.MakeRelativeUri(to).ToString();
00848 #else
00849                 url = from.MakeRelative(to);
00850 #endif
00851             }
00852             return url;
00853         }
00854 
00855         internal static string GetUniqueIDWithDollars(Control control)
00856         {
00857             string uniqueIdWithDollars = control.UniqueID;
00858             if (uniqueIdWithDollars == null)
00859             {
00860                 return null;
00861             }
00862             if (uniqueIdWithDollars.IndexOf(':') >= 0)
00863             {
00864                 return uniqueIdWithDollars.Replace(':', '$');
00865             }
00866             return uniqueIdWithDollars;
00867         }
00868  
00869         private static object InvokeMethod(object target, MethodInfo methodInfo, object[] parameters)
00870         {
00871             object val = null;
00872             try
00873             {
00874                 val = methodInfo.Invoke(target, parameters);
00875             }
00876             catch (TargetInvocationException ex)
00877             {
00878                 // TargetInvocationExceptions should have the actual
00879                 // exception the method threw in its InnerException
00880                 // property.
00881                 if (ex.InnerException != null)
00882                 {
00883                     throw ex.InnerException;
00884                 }
00885                 else
00886                 {
00887                     throw ex;
00888                 }
00889             }
00890             return val;
00891         }
00892 
00893         private static void Register(Page page, Control control)
00894         {
00895             AddManager(page);
00896             Manager manager = GetManager();
00897             if (!object.ReferenceEquals(page, control))
00898                 manager.AddTarget(control);
00899         }
00900 
00901         private static void WriteDataRow(StringBuilder sb, DataRow row)
00902         {
00903             sb.Append("{");
00904             foreach (DataColumn column in row.Table.Columns)
00905             {
00906                 sb.AppendFormat("\"{0}\":", column.ColumnName);
00907                 WriteValue(sb, row[column]);
00908                 sb.Append(",");
00909             }
00910             // Remove the trailing comma.
00911             if (row.Table.Columns.Count > 0)
00912             {
00913                 --sb.Length;
00914             }
00915             sb.Append("}");
00916         }
00917 
00918         private static void WriteDataSet(StringBuilder sb, DataSet ds)
00919         {
00920             sb.Append("{\"Tables\":{");
00921             foreach (DataTable table in ds.Tables)
00922             {
00923                 sb.AppendFormat("\"{0}\":", table.TableName);
00924                 WriteDataTable(sb, table);
00925                 sb.Append(",");
00926             }
00927             // Remove the trailing comma.
00928             if (ds.Tables.Count > 0)
00929             {
00930                 --sb.Length;
00931             }
00932             sb.Append("}}");
00933         }
00934 
00935         private static void WriteDataTable(StringBuilder sb, DataTable table)
00936         {
00937             sb.Append("{\"Rows\":[");
00938             foreach (DataRow row in table.Rows)
00939             {
00940                 WriteDataRow(sb, row);
00941                 sb.Append(",");
00942             }
00943             // Remove the trailing comma.
00944             if (table.Rows.Count > 0)
00945             {
00946                 --sb.Length;
00947             }
00948             sb.Append("]}");
00949         }
00950 
00951         private static void WriteEnumerable(StringBuilder sb, IEnumerable e)
00952         {
00953             bool hasItems = false;
00954             sb.Append("[");
00955             foreach (object val in e)
00956             {
00957                 WriteValue(sb, val);
00958                 sb.Append(",");
00959                 hasItems = true;
00960             }
00961             // Remove the trailing comma.
00962             if (hasItems)
00963             {
00964                 --sb.Length;
00965             }
00966             sb.Append("]");
00967         }
00968 
00969         private static void WriteHashtable(StringBuilder sb, Hashtable e)
00970         {
00971             bool hasItems = false;
00972             sb.Append("{");
00973             foreach (string key in e.Keys)
00974             {
00975                 sb.AppendFormat("\"{0}\":", key.ToLower());
00976                 WriteValue(sb, e[key]);
00977                 sb.Append(",");
00978                 hasItems = true;
00979             }
00980             // Remove the trailing comma.
00981             if (hasItems)
00982             {
00983                 --sb.Length;
00984             }
00985             sb.Append("}");
00986         }
00987 
00988         private static void WriteObject(StringBuilder sb, object o)
00989         {
00990             MemberInfo[] members = o.GetType().GetMembers(BindingFlags.Instance | BindingFlags.Public);
00991             sb.Append("{");
00992             bool hasMembers = false;
00993             foreach (MemberInfo member in members)
00994             {
00995                 bool hasValue = false;
00996                 object val = null;
00997                 if ((member.MemberType & MemberTypes.Field) == MemberTypes.Field)
00998                 {
00999                     FieldInfo field = (FieldInfo)member;
01000                     val = field.GetValue(o);
01001                     hasValue = true;
01002                 }
01003                 else if ((member.MemberType & MemberTypes.Property) == MemberTypes.Property)
01004                 {
01005                     PropertyInfo property = (PropertyInfo)member;
01006                     if (property.CanRead && property.GetIndexParameters().Length == 0)
01007                     {
01008                         val = property.GetValue(o, null);
01009                         hasValue = true;
01010                     }
01011                 }
01012                 if (hasValue)
01013                 {
01014                     sb.Append("\"");
01015                     sb.Append(member.Name);
01016                     sb.Append("\":");
01017                     WriteValue(sb, val);
01018                     sb.Append(",");
01019                     hasMembers = true;
01020                 }
01021             }
01022             if (hasMembers)
01023             {
01024                 --sb.Length;
01025             }
01026             sb.Append("}");
01027         }
01028 
01029         private static void WriteString(StringBuilder sb, string s)
01030         {
01031             sb.Append("\"");
01032             foreach (char c in s)
01033             {
01034                 switch (c)
01035                 {
01036                     case '\"':
01037                         sb.Append("\\\"");
01038                         break;
01039                     case '\\':
01040                         sb.Append("\\\\");
01041                         break;
01042                     case '\b':
01043                         sb.Append("\\b");
01044                         break;
01045                     case '\f':
01046                         sb.Append("\\f");
01047                         break;
01048                     case '\n':
01049                         sb.Append("\\n");
01050                         break;
01051                     case '\r':
01052                         sb.Append("\\r");
01053                         break;
01054                     case '\t':
01055                         sb.Append("\\t");
01056                         break;
01057                     default:
01058                         int i = (int)c;
01059                         if (i < 32 || i > 127)
01060                         {
01061                             sb.AppendFormat("\\u{0:X04}", i);
01062                         }
01063                         else
01064                         {
01065                             sb.Append(c);
01066                         }
01067                         break;
01068                 }
01069             }
01070             sb.Append("\"");
01071         }
01072 
01073         private static void WriteValueAndError(
01074             StringBuilder sb, 
01075             object val, 
01076             string error, 
01077             string viewState, 
01078             string viewStateEncrypted,
01079             string eventValidation,
01080             Hashtable controls,
01081             string[] scripts)
01082         {
01083             sb.Append("{\"value\":");
01084             WriteValue(sb, val);
01085             sb.Append(",\"error\":");
01086             WriteValue(sb, error);
01087             if (viewState != null)
01088             {
01089                 sb.Append(",\"viewState\":");
01090                 WriteValue(sb, viewState);
01091             }
01092             if (viewStateEncrypted != null)
01093             {
01094                 sb.Append(",\"viewStateEncrypted\":");
01095                 WriteValue(sb, viewStateEncrypted);
01096             }
01097             if (eventValidation != null)
01098             {
01099                 sb.Append(",\"eventValidation\":");
01100                 WriteValue(sb, eventValidation);
01101             }
01102             if (controls != null && controls.Count > 0)
01103             {
01104                 sb.Append(",\"controls\":{");
01105                 foreach (DictionaryEntry control in controls)
01106                 {
01107                     sb.Append("\"" + control.Key + "\":");
01108                     WriteValue(sb, control.Value);
01109                     sb.Append(",");
01110                 }
01111                 --sb.Length;
01112                 sb.Append("}");
01113             }
01114             if (scripts != null && scripts.Length > 0)
01115             {
01116                 sb.Append(",\"pagescript\":[");
01117                 foreach (string script in scripts)
01118                 {
01119                     WriteValue(sb, script);
01120                     sb.Append(",");
01121                 }
01122                 --sb.Length;
01123                 sb.Append("]");
01124             }
01125             if (GetManager()._clientSideEvalScripts.Count > 0)
01126             {
01127                 sb.Append(",\"script\":[");
01128                 foreach (string script in GetManager()._clientSideEvalScripts)
01129                 {
01130                     WriteValue(sb, script);
01131                     sb.Append(",");
01132                 }
01133                 --sb.Length;
01134                 sb.Append("]");
01135             }
01136             sb.Append("}");
01137         }
01138 
01139         #endregion
01140 
01141         #region Public Methods
01142 
01150         [Anthem.Method]
01151         public void FireEvent() {}
01152 
01153         #region Support for container controls
01154 
01174         public static void AddCallBacks(
01175             Control control, 
01176             bool enabledDuringCallBack, 
01177             string textDuringCallBack,
01178             string preCallBackFunction, 
01179             string postCallBackFunction, 
01180             string callBackCancelledFunction)
01181         {
01182             foreach (Control child in GetAllChildControls(control))
01183             {
01184 #if V2
01185                 if (child is ASP.GridView)
01186                 {
01187                     AddCallBacks(
01188                         child,
01189                         enabledDuringCallBack,
01190                         textDuringCallBack,
01191                         preCallBackFunction,
01192                         postCallBackFunction,
01193                         callBackCancelledFunction
01194                     );
01195                 }
01196 
01197                 else if (child is ASP.DetailsView)
01198                 {
01199                     AddCallBacks(
01200                         child,
01201                         enabledDuringCallBack,
01202                         textDuringCallBack,
01203                         preCallBackFunction,
01204                         postCallBackFunction,
01205                         callBackCancelledFunction
01206                     );
01207                 }
01208 
01209                 else if (child is ASP.FormView)
01210                 {
01211                     AddCallBacks(
01212                         child,
01213                         enabledDuringCallBack,
01214                         textDuringCallBack,
01215                         preCallBackFunction,
01216                         postCallBackFunction,
01217                         callBackCancelledFunction
01218                     );
01219                 }
01220 
01221                 else if (child is ASP.IButtonControl && child is ASP.WebControl)
01222                 {
01223                     if (child.Parent is ASP.DataControlFieldCell && ((ASP.DataControlFieldCell)child.Parent).ContainingField is ASP.CommandField)
01224                     {
01225                         AddEventHandler(
01226                             control,
01227                             (ASP.WebControl)child,
01228                             "onclick",
01229                             ((ASP.IButtonControl)child).CommandName,
01230                             ((ASP.IButtonControl)child).CommandArgument,
01231                             ((ASP.IButtonControl)child).CausesValidation,
01232                             ((ASP.IButtonControl)child).ValidationGroup,
01233                             textDuringCallBack,
01234                             enabledDuringCallBack,
01235                             preCallBackFunction,
01236                             postCallBackFunction,
01237                             callBackCancelledFunction
01238                         );
01239                     }
01240                     else
01241                     {
01242                         AddEventHandler(
01243                             child,
01244                             (ASP.WebControl)child,
01245                             "onclick",
01246                             ((ASP.IButtonControl)child).CommandName,
01247                             ((ASP.IButtonControl)child).CommandArgument,
01248                             ((ASP.IButtonControl)child).CausesValidation,
01249                             ((ASP.IButtonControl)child).ValidationGroup,
01250                             textDuringCallBack,
01251                             enabledDuringCallBack,
01252                             preCallBackFunction,
01253                             postCallBackFunction,
01254                             callBackCancelledFunction
01255                         );
01256                     }
01257                 }
01258 #else
01259                 if (child is ASP.Button)
01260                     AddEventHandler(
01261                         child,
01262                         (ASP.WebControl)child,
01263                         "onclick",
01264                         ((ASP.Button)child).CommandName,
01265                         ((ASP.Button)child).CommandArgument,
01266                         ((ASP.Button)child).CausesValidation,
01267                         string.Empty,
01268                         textDuringCallBack,
01269                         enabledDuringCallBack,
01270                         preCallBackFunction,
01271                         postCallBackFunction,
01272                         callBackCancelledFunction);
01273 
01274                 else if (child is ASP.ImageButton)
01275                     AddEventHandler(
01276                         child,
01277                         (ASP.WebControl)child,
01278                         "onclick",
01279                         ((ASP.ImageButton)child).CommandName,
01280                         ((ASP.ImageButton)child).CommandArgument,
01281                         ((ASP.ImageButton)child).CausesValidation,
01282                         string.Empty,
01283                         textDuringCallBack,
01284                         enabledDuringCallBack,
01285                         preCallBackFunction,
01286                         postCallBackFunction,
01287                         callBackCancelledFunction);
01288 
01289                 else if (child is ASP.LinkButton)
01290                     AddEventHandler(
01291                         child,
01292                         (ASP.WebControl)child,
01293                         "onclick",
01294                         ((ASP.LinkButton)child).CommandName,
01295                         ((ASP.LinkButton)child).CommandArgument,
01296                         ((ASP.LinkButton)child).CausesValidation,
01297                         string.Empty,
01298                         textDuringCallBack,
01299                         enabledDuringCallBack,
01300                         preCallBackFunction,
01301                         postCallBackFunction,
01302                         callBackCancelledFunction);
01303 #endif
01304                 else if (child is ASP.CheckBox)
01305                 {
01306                     if (((ASP.CheckBox)child).AutoPostBack)
01307                     {
01308                         AddEventHandler(
01309                             child,
01310                             (ASP.WebControl)child,
01311                             "onclick",
01312                             string.Empty,
01313                             string.Empty,
01314 #if V2
01315                             ((ASP.CheckBox)child).CausesValidation,
01316                             ((ASP.CheckBox)child).ValidationGroup,
01317 #else
01318                             false,
01319                             string.Empty,
01320 #endif
01321                             textDuringCallBack,
01322                             enabledDuringCallBack,
01323                             preCallBackFunction,
01324                             postCallBackFunction,
01325                             callBackCancelledFunction
01326                         );
01327                         ((ASP.CheckBox)child).AutoPostBack = false;
01328                     }
01329                 }
01330 
01331                 else if (child is ASP.CheckBoxList)
01332                 {
01333                     if (((ASP.CheckBoxList)child).AutoPostBack)
01334                     {
01335                         AddScriptAttribute(
01336                             (ASP.WebControl)child,
01337                             "onclick",
01338                             string.Format("AnthemListControl_OnClick(event,{0},'{1}','{2}',{3},{4},{5},{6},true,true)",
01339 #if V2
01340                                 ((ASP.CheckBoxList)child).CausesValidation ? "true" : "false",
01341                                 ((ASP.CheckBoxList)child).ValidationGroup,
01342 #else
01343                                 "false",
01344                                 string.Empty,
01345 #endif
01346                                 textDuringCallBack,
01347                                 enabledDuringCallBack ? "true" : "false",
01348                                 IsNullOrEmpty(preCallBackFunction) ? "null" : preCallBackFunction,
01349                                 IsNullOrEmpty(postCallBackFunction) ? "null" : postCallBackFunction,
01350                                 IsNullOrEmpty(callBackCancelledFunction) ? "null" : callBackCancelledFunction
01351                             )
01352                         );
01353                         ASP.CheckBox controlToRepeat = (ASP.CheckBox)((ASP.CheckBoxList)child).Controls[0];
01354                         controlToRepeat.AutoPostBack = false;
01355                     }
01356                 }
01357 
01358                 else if (child is ASP.DataGrid)
01359                     AddCallBacks(
01360                         child,
01361                         enabledDuringCallBack,
01362                         textDuringCallBack,
01363                         preCallBackFunction,
01364                         postCallBackFunction,
01365                         callBackCancelledFunction
01366                     );
01367 
01368                 else if (child is ASP.DropDownList)
01369                 {
01370                     if (((ASP.DropDownList)child).AutoPostBack)
01371                     {
01372                         AddEventHandler(
01373                             child,
01374                             (ASP.WebControl)child,
01375                             "onchange",
01376                             string.Empty,
01377                             string.Empty,
01378 #if V2
01379                             ((ASP.DropDownList)child).CausesValidation,
01380                             ((ASP.DropDownList)child).ValidationGroup,
01381 #else
01382                             false,
01383                             string.Empty,
01384 #endif
01385                             textDuringCallBack,
01386                             enabledDuringCallBack,
01387                             preCallBackFunction,
01388                             postCallBackFunction,
01389                             callBackCancelledFunction
01390                         );
01391                         ((ASP.DropDownList)child).AutoPostBack = false;
01392                     }
01393                 }
01394 
01395                 else if (child is ASP.ListBox)
01396                 {
01397                     if (((ASP.ListBox)child).AutoPostBack)
01398                     {
01399                         AddEventHandler(
01400                             child,
01401                             (ASP.WebControl)child,
01402                             "onchange",
01403                             string.Empty,
01404                             string.Empty,
01405 #if V2
01406                             ((ASP.ListBox)child).CausesValidation,
01407                             ((ASP.ListBox)child).ValidationGroup,
01408 #else
01409                             false,
01410                             string.Empty,
01411 #endif
01412                             textDuringCallBack,
01413                             enabledDuringCallBack,
01414                             preCallBackFunction,
01415                             postCallBackFunction,
01416                             callBackCancelledFunction
01417                         );
01418                         ((ASP.ListBox)child).AutoPostBack = false;
01419                     }
01420                 }
01421 
01422                 else if (child is ASP.Panel)
01423                     AddCallBacks(
01424                         child,
01425                         enabledDuringCallBack,
01426                         textDuringCallBack,
01427                         preCallBackFunction,
01428                         postCallBackFunction,
01429                         callBackCancelledFunction
01430                     );
01431 
01432                 else if (child is ASP.RadioButtonList)
01433                 {
01434                     if (((ASP.RadioButtonList)child).AutoPostBack)
01435                     {
01436                         AddScriptAttribute(
01437                             (ASP.WebControl)child,
01438                             "onclick",
01439                             string.Format("AnthemListControl_OnClick(event,{0},'{1}','{2}',{3},{4},{5},{6},true,true)",
01440 #if V2
01441                                 ((ASP.RadioButtonList)child).CausesValidation ? "true" : "false",
01442                                 ((ASP.RadioButtonList)child).ValidationGroup,
01443 #else
01444                                 "false",
01445                                 string.Empty,
01446 #endif
01447                                 textDuringCallBack,
01448                                 enabledDuringCallBack ? "true" : "false",
01449                                 IsNullOrEmpty(preCallBackFunction) ? "null" : preCallBackFunction,
01450                                 IsNullOrEmpty(postCallBackFunction) ? "null" : postCallBackFunction,
01451                                 IsNullOrEmpty(callBackCancelledFunction) ? "null" : callBackCancelledFunction
01452                             )
01453                         );
01454                         ((ASP.RadioButtonList)child).AutoPostBack = false;
01455                     }
01456                 }
01457 
01458                 else if (child is ASP.Repeater)
01459                     AddCallBacks(
01460                         child,
01461                         enabledDuringCallBack,
01462                         textDuringCallBack,
01463                         preCallBackFunction,
01464                         postCallBackFunction,
01465                         callBackCancelledFunction
01466                     );
01467 
01468                 else if (child is ASP.TextBox)
01469                 {
01470                     if (((ASP.TextBox)child).AutoPostBack)
01471                     {
01472                         AddEventHandler(
01473                             child,
01474                             (ASP.WebControl)child,
01475                             "onchange",
01476                             string.Empty,
01477                             string.Empty,
01478 #if V2
01479                             ((ASP.TextBox)child).CausesValidation,
01480                             ((ASP.TextBox)child).ValidationGroup,
01481 #else
01482                             false,
01483                             string.Empty,
01484 #endif
01485                             textDuringCallBack,
01486                             enabledDuringCallBack,
01487                             preCallBackFunction,
01488                             postCallBackFunction,
01489                             callBackCancelledFunction
01490                         );
01491                         ((ASP.TextBox)child).AutoPostBack = false;
01492                     }
01493                 }
01494             }
01495         }
01496 
01504         private static ArrayList GetAllChildControls(Control control)
01505         {
01506             ArrayList controls = new ArrayList();
01507             foreach (Control child in control.Controls)
01508             {
01509                 if (!(child is IUpdatableControl) && !(child is LiteralControl))
01510                 {
01511                     controls.Add(child);
01512 #if V2
01513                     if (!(child is ASP.DataGrid
01514                         || child is ASP.GridView
01515                         || child is ASP.DetailsView
01516                         || child is ASP.FormView
01517                         || child is ASP.Panel
01518                         || child is ASP.Repeater))
01519                         controls.AddRange(GetAllChildControls(child));
01520 #else
01521                     if (!(child is ASP.DataGrid
01522                         || child is ASP.Panel
01523                         || child is ASP.Repeater
01524                         || child is ASP.CheckBoxList
01525                         || child is ASP.RadioButtonList))
01526                         controls.AddRange(GetAllChildControls(child));
01527 #endif
01528                 }
01529             }
01530             return controls;
01531         }
01532 
01539         private static void AddEventHandler(
01540             Control parent, 
01541             ASP.WebControl control,
01542             string eventName,
01543             string commandName, 
01544             string commandArgument, 
01545             bool causesValidation, 
01546             string validationGroup,
01547             string textDuringCallBack,
01548             bool enabledDuringCallBack,
01549             string preCallBackFunction,
01550             string postCallBackFunction,
01551             string callBackCancelledFunction)
01552         {
01553 #if V2
01554             if (!IsNullOrEmpty(commandName) || !IsNullOrEmpty(commandArgument))
01555             {
01556                 parent.Page.ClientScript.RegisterForEventValidation(parent.UniqueID,
01557                     string.Format("{0}${1}", commandName, commandArgument));
01558             }
01559 #endif
01560             AddScriptAttribute(
01561                 control,
01562                 eventName,
01563                 string.Format(
01564                     "javascript:Anthem_FireCallBackEvent(this,event,'{0}','{1}',{2},'{3}','','{4}',{5},{6},{7},{8},true,true);return false;",
01565                     parent.UniqueID,
01566                     IsNullOrEmpty(commandName) && IsNullOrEmpty(commandArgument) ? "" : commandName + "$" + commandArgument,
01567                     causesValidation ? "true" : "false",
01568 #if V2
01569                     validationGroup,
01570 #else
01571                     string.Empty,
01572 #endif
01573                     textDuringCallBack,
01574                     enabledDuringCallBack ? "true" : "false",
01575                     IsNullOrEmpty(preCallBackFunction)  ? "null" : preCallBackFunction,
01576                     IsNullOrEmpty(postCallBackFunction) ? "null" : postCallBackFunction,
01577                     IsNullOrEmpty(callBackCancelledFunction) ? "null" : callBackCancelledFunction
01578                 )
01579             );
01580         }
01581 
01582         private static bool IsNullOrEmpty(string s)
01583         {
01584             return ((s == null) || (s.Length == 0));
01585         }
01586 
01587         #endregion
01588 
01589         #endregion
01590 
01591         #region Private Methods
01592 
01593         private Hashtable _targets;
01594         private ArrayList _clientSideEvalScripts;
01595         private NameValueCollection _pageScripts;
01596         private object _value;
01597         private string _error;
01598         private bool _updatePage;
01599         private bool _updateValidationScripts;
01600 
01601         private Manager()
01602         {
01603             _targets = new Hashtable();
01604             _clientSideEvalScripts = new ArrayList();
01605             _includePageScripts = false;
01606             _pageScripts = new NameValueCollection();
01607         }
01608 
01609         private void AddTarget(Control control)
01610         {
01611             _targets[control.ClientID] = control;
01612         }
01613 
01614         private bool CheckIfRedirectedToLoginPage()
01615         {
01616             HttpContext context = HttpContext.Current;
01617             HttpRequest req = context.Request;
01618             string returnURL = req.QueryString["ReturnURL"];
01619             if (returnURL != null && returnURL.Length > 0)
01620             {
01621                 returnURL = context.Server.UrlDecode(returnURL);
01622                 if (returnURL.EndsWith("?Anthem_CallBack=true") ||
01623                     returnURL.EndsWith("&Anthem_CallBack=true"))
01624                 {
01625                     HttpResponse resp = context.Response;
01626                     WriteResult(resp, null, "LOGIN");
01627                     resp.End();
01628                     return true;
01629                 }
01630             }
01631             return false;
01632         }
01633 
01634         private void ConfigureResponse(HttpResponse resp)
01635         {
01636             string contentEncoding = null;
01637             string contentType = null;
01638 #if V2
01639             contentEncoding = WebConfigurationManager.AppSettings["Anthem.ResponseEncoding"];
01640             contentType = WebConfigurationManager.AppSettings["Anthem.ResponseType"];
01641 #else
01642             contentEncoding = ConfigurationSettings.AppSettings["Anthem.ResponseEncoding"];
01643             contentType = ConfigurationSettings.AppSettings["Anthem.ResponseType"];
01644 #endif
01645             if (contentEncoding != null)
01646                 resp.ContentEncoding = Encoding.GetEncoding(contentEncoding);
01647             if (contentType != null)
01648                 resp.ContentType = contentType;
01649             resp.Cache.SetCacheability(HttpCacheability.NoCache);
01650         }
01651 
01652         const string _beginControlMarker = "<!--START:";
01653         const string _endControlMarker = "<!--END:";
01663         private Hashtable GetControls(string html)
01664         {
01665             Hashtable controls = new Hashtable();
01666 
01667             // Find the first begin marker.
01668             int i = html.IndexOf(_beginControlMarker);
01669             // Keep looping while we've got markers.
01670             while (i != -1)
01671             {
01672                 i += _beginControlMarker.Length;
01673                 // Find the end of the begin marker.
01674                 int j = html.IndexOf("-->", i);
01675                 if (j == -1)
01676                 {
01677                     break;
01678                 }
01679                 else
01680                 {
01681                     // The string between i and j should be the ClientID.
01682                     string id = html.Substring(i, j - i);
01683 
01684                     // Point past the end of the begin marker.
01685                     i = j + 3;
01686                     string endMarker = _endControlMarker + id + "-->";
01687                     // Find the end marker for the current control.
01688                     j = html.IndexOf(endMarker, i);
01689                     if (j == -1)
01690                     {
01691                         break;
01692                     }
01693                     else
01694                     {
01695                         // The string between i and j is now the HTML.
01696                         string control = html.Substring(i, j - i);
01697                         controls[id] = control;
01698                         // Point past the end of the end marker.
01699                         i = j + endMarker.Length;
01700                     }
01701                 }
01702                 // Find the next begin marker.
01703                 i = html.IndexOf(_beginControlMarker, i);
01704             }
01705             return controls;
01706         }
01707 
01708         private string GetHiddenInputValue(string html, string marker)
01709         {
01710             string value = null;
01711             int i = html.IndexOf(marker);
01712             if (i != -1)
01713             {
01714                 value = html.Substring(i + marker.Length);
01715                 value = value.Substring(0, value.IndexOf('\"'));
01716             }
01717             return value;
01718         }
01719 
01720         // Returns a list of all embedded scripts in the page
01721         private static Regex scriptEmbeddedRegex = new Regex(@"<script.*?>(?<script>.*?)</script>", 
01722             RegexOptions.Singleline | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Compiled);
01723         private static Regex scriptTagsRegex = new Regex(@"<script(?<attributes>.*?)(>|/>)",
01724             RegexOptions.Singleline | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Compiled);
01725         private static Regex scriptTypeRegex = new Regex(@"type\s*=\s*['""]text/javascript['""]",
01726             RegexOptions.Singleline | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Compiled);
01727         private static Regex scriptSrcRegex = new Regex(@"src\s*=\s*['""](?<src>.+?)['""]",
01728             RegexOptions.Singleline | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Compiled);
01729         private string[] GetScripts(string html)
01730         {
01731             ArrayList scripts = new ArrayList();
01732 
01733             // Add all of the scripts that were manually registered.
01734             for (int index = 0; index < _pageScripts.Count; index++)
01735             {
01736                 string script = _pageScripts[index];
01737                 // Strip off any <script> tags
01738                 if (scriptEmbeddedRegex.IsMatch(script))
01739                 {
01740                     foreach (Match scriptMatch in scriptEmbeddedRegex.Matches(script))
01741                     {
01742                         string innerScript = scriptMatch.Groups["script"].ToString();
01743                         if (innerScript != string.Empty)
01744                         {
01745                             scripts.Add(innerScript);
01746                         }
01747                     }
01748                 }
01749                 else
01750                 {
01751                     scripts.Add(script);
01752                 }
01753             }
01754 
01755             // Load the script libraries in case they are used by the embedded scripts
01756             if (_includePageScripts)
01757             {
01758                 foreach (Match attributesMatch in scriptTagsRegex.Matches(html))
01759                 {
01760                     string attributes = attributesMatch.Groups["attributes"].ToString().Trim();
01761                     if (scriptTypeRegex.Match(attributes).Success)
01762                     {
01763                         foreach (Match srcMatch in scriptSrcRegex.Matches(attributes))
01764                         {
01765                             string src = srcMatch.Groups["src"].ToString();
01766                             if (src != string.Empty)
01767                                 scripts.Add("src=" + src);
01768                         }
01769                     }
01770                 }
01771             }
01772 
01773             // Now load the embedded scripts
01774             if (this._updateValidationScripts || _includePageScripts)
01775             {
01776                 // These scripts will reset page validation. Page_Validators is an array
01777                 // of validators to be invoked. WebForm_OnSubmit (ASP.NET 2.0) and 
01778                 // ValidatorOnSubmit (ASP.NET 1.1) are called by the form's onsubmit
01779                 // event handler by postback (non-callback) controls that cause
01780                 // validation. Resetting these will ensure that no javascript errors
01781                 // occur if validators have been removed from the page. If there are 
01782                 // still validators on the page, then the actual array and function will
01783                 // override these values.
01784 #if V2
01785                 scripts.Add(@"
//<![CDATA[
var Page_Validators = new Array();
function WebForm_OnSubmit() {
    return true;
}
//]]>");
01786 #else
01787                 scripts.Add(@"
//<![CDATA[
var Page_Validators = new Array();
var Page_ValidationSummaries = new Array();
function ValidatorOnSubmit() {
    return true;
}
//]]>");
01788 #endif
01789                 // This loop will look for any scripts that were injected into the
01790                 // page. If they are found, then they are added to the page.
01791                 foreach (Match scriptMatch in scriptEmbeddedRegex.Matches(html))
01792                 {
01793                     string script = scriptMatch.Groups["script"].ToString();
01794                     if (script != string.Empty)
01795                     {
01796                         if (_includePageScripts && script.IndexOf("Anthem.Manager.GetScripts: false") == -1)
01797                             scripts.Add(script);
01798 
01799                         // This sequence of regular expressions match all of the client
01800                         // side validation scripts that may be added by the validation
01801                         // controls for both ASP.NET 1.1 and 2.0.
01802                         else if (Regex.IsMatch(script, "var Page_ValidationSummaries", RegexOptions.IgnoreCase))
01803                             scripts.Add(script);
01804                         else if (Regex.IsMatch(script, "var Page_Validators", RegexOptions.IgnoreCase))
01805                             scripts.Add(script);
01806                         else if (Regex.IsMatch(script, "var Page_ValidationActive", RegexOptions.IgnoreCase))
01807                             scripts.Add(script);
01808                         else if (Regex.IsMatch(script, "function WebForm_OnSubmit", RegexOptions.IgnoreCase))
01809                             scripts.Add(script);
01810                         else if (Regex.IsMatch(script, "\\.evaluationfunction =", RegexOptions.IgnoreCase))
01811                             scripts.Add(script);
01812 
01813                         // If validators with client side validation were added to the 
01814                         // page during the callback and if there are postback controls 
01815                         // on the page that cause validation, then we need to add an
01816                         // onsubmit event handler to the form that enforces the client
01817                         // side validation. This is how postback (non-callback) controls
01818                         // cause validation to occur.
01819                         //
01820                         // This next script is executed during callback response processing 
01821                         // on the client. It will attach the ASP.NET validation function
01822                         // to the onsubmit event of the form.
01823 #if V2
01824                         if (Regex.IsMatch(script, "function WebForm_OnSubmit", RegexOptions.IgnoreCase))
01825                         {
01826                             scripts.Add(@"
//<![CDATA[
var form = Anthem_GetForm();
if (typeof(form) != ""undefined"" && form != null) {
  Anthem_AddEvent(form, ""onsubmit"", ""return WebForm_OnSubmit();"");
}
//]]>");
01827                         }
01828 #else
01829                         if (Regex.IsMatch(script, "function ValidatorOnSubmit", RegexOptions.IgnoreCase))
01830                         {
01831                             scripts.Add(@"
//<![CDATA[
var form = Anthem_GetForm();
if (typeof(form) != ""undefined"" && form != null) {
    Anthem_AddEvent(form, ""onsubmit"", ""if (!ValidatorOnSubmit()) return false;"");
}
//]]>");
01832                         }
01833 #endif
01834                     }
01835                 }
01836             }
01837 
01838             return (string[]) scripts.ToArray(typeof(string));
01839         }
01840 
01841         const string _beginViewState = "<input type=\"hidden\" name=\"__VIEWSTATE\" value=\"";
01842         private string GetViewState(string html)
01843         {
01844 #if V2
01845             return GetHiddenInputValue(html, _beginViewState2);
01846 #else
01847             return GetHiddenInputValue(html, _beginViewState);
01848 #endif
01849         }
01850 
01851 #if V2
01852         const string _beginViewState2 = "<input type=\"hidden\" name=\"__VIEWSTATE\" id=\"__VIEWSTATE\" value=\"";
01853         const string _beginViewStateEncrypted = "<input type=\"hidden\" name=\"__VIEWSTATEENCRYPTED\" id=\"__VIEWSTATEENCRYPTED\" value=\"";
01854         const string _beginEventValidation = "<input type=\"hidden\" name=\"__EVENTVALIDATION\" id=\"__EVENTVALIDATION\" value=\"";
01855         private string GetViewStateEncrypted(string html)
01856         {
01857             return GetHiddenInputValue(html, _beginViewStateEncrypted);
01858         }
01859 
01860         private string GetEventValidation(string html)
01861         {
01862             return GetHiddenInputValue(html, _beginEventValidation);
01863         }
01864 #endif
01865 
01866         private void OnError(object source, EventArgs e)
01867         {
01868             if (IsCallBack)
01869             {
01870                 _error = HttpContext.Current.Error.ToString();
01871                 HttpContext.Current.ClearError();
01872                 WriteResult(HttpContext.Current.Response, null, _error);
01873             }
01874         }
01875 
01876         private void OnPreRender(object source, EventArgs e)
01877         {
01878             HttpContext context = HttpContext.Current;
01879             HttpRequest req = context.Request;
01880             HttpResponse resp = context.Response;
01881             Page page = source as Page;
01882 
01883             if (!CheckIfRedirectedToLoginPage() && IsCallBack)
01884             {
01885                 object targetObject = null;
01886                 string methodName = null;
01887                 bool invokeMethod = true;
01888 
01889                 if (req.Form["Anthem_PageMethod"] != null)
01890                 {
01891                     targetObject = page;
01892                     methodName = req.Form["Anthem_PageMethod"];
01893                 }
01894 #if V2
01895                 else if (req.Form["Anthem_MasterPageMethod"] != null)
01896                 {
01897                     if (page != null)
01898                     {
01899                         // TODO: Since master pages can nest, we might need to do a search for the method up
01900                         // to the root master page.
01901                         targetObject = page.Master;
01902                         methodName = req.Form["Anthem_MasterPageMethod"];
01903                     }
01904                 }
01905 #endif
01906                 else if (req.Form["Anthem_ControlID"] != null && req.Form["Anthem_ControlMethod"] != null)
01907                 {
01908                     targetObject = _targets[req.Form["Anthem_ControlID"]];
01909                     methodName = req.Form["Anthem_ControlMethod"];
01910                 }
01911                 else
01912                 {
01913                     invokeMethod = false;
01914                 }
01915 
01916                 object val = null;
01917                 string error = null;
01918 
01919                 if (invokeMethod)
01920                 {
01921                     if (targetObject == null)
01922                     {
01923                         error = "CONTROLNOTFOUND";
01924                     }
01925                     else
01926                     {
01927                         if (methodName != null && methodName.Length > 0)
01928                         {
01929                             MethodInfo methodInfo = FindTargetMethod(targetObject, methodName);
01930                             if (methodInfo == null)
01931                             {
01932                                 error = "METHODNOTFOUND";
01933                             }
01934                             else
01935                             {
01936                                 try
01937                                 {
01938                                     object[] parameters = ConvertParameters(methodInfo, req);
01939                                     val = InvokeMethod(targetObject, methodInfo, parameters);
01940                                 }
01941                                 catch (MethodAccessException ex)
01942                                 {
01943                                     if (!methodInfo.IsPublic)
01944                                         error = string.Format("Anthem.Manager does not have permission to invoke method \"{0}\" in the current trust level. Please try making the method Public.", methodName);
01945                                     else
01946                                         error = ex.Message;
01947                                 }
01948                                 catch (Exception ex)
01949                                 {
01950                                     error = ex.Message;
01951                                 }
01952                             }
01953                         }
01954                     }
01955                 }
01956 
01957                 ConfigureResponse(resp);
01958                 resp.Filter = new CallBackFilter(this, resp.Filter);
01959                 _value = val;
01960                 _error = error;
01961                 _updatePage = string.Compare(req["Anthem_UpdatePage"], "true", true) == 0;
01962                 _updateValidationScripts = false;
01963 
01964                 if (_updatePage)
01965                 {
01966                     // If there are any validators on the page, then include the validation
01967                     // scripts in the callback response in case any validators were added to
01968                     // the page during the callback processing.
01969                     _updateValidationScripts = ValidationScriptsRequired(page);
01970                     if (_updateValidationScripts)
01971                     {
01972 #if V2
01973                         this._pageScripts.Add(GetAnthemManagerKey()+"WebForm.js", "src=" + page.ClientScript.GetWebResourceUrl(typeof(Page), "WebForms.js"));
01974                         this._pageScripts.Add(GetAnthemManagerKey()+"WebUIValidation.js", "src=" + page.ClientScript.GetWebResourceUrl(typeof(ASP.BaseValidator), "WebUIValidation.js"));
01975 #else
01976                         string path = string.Empty;
01977                         IDictionary dictionary = (IDictionary)HttpContext.Current.GetConfig("system.web/webControls");
01978                         if (dictionary != null)
01979                         {
01980                             path = (string)dictionary["clientScriptsLocation"];
01981                         }
01982                         if (path != null && path.IndexOf("{0}") >= 0)
01983                         {
01984                             string version = Environment.Version.ToString();
01985                             path = string.Format(path, "system_web", version.Substring(0, version.LastIndexOf('.')).Replace('.', '_'));
01986                         }
01987                         this._pageScripts.Add(GetAnthemManagerKey()+"WebUIValidation.js", "src=" + path + "WebUIValidation.js");
01988 #endif
01989                     }
01990                 }
01991             }
01992         }
01993 
01994         private bool ValidationScriptsRequired(Page page)
01995         {
01996 #if V2
01997             if (page != null && page.Validators.Count > 0 && page.Request.Browser.W3CDomVersion.Major >= 1)
01998             {
01999                 foreach (ASP.BaseValidator validator in page.Validators)
02000                 {
02001                     if (validator.EnableClientScript)
02002                     {
02003                         if (page.Request.Browser.EcmaScriptVersion.CompareTo(new Version(1, 2)) >= 0)
02004                             return true;
02005                     }
02006                 }
02007             }
02008             return false;
02009 #else
02010             if (page != null && page.Validators.Count > 0 && page.Request.Browser.MSDomVersion.Major >= 4)
02011             {
02012                 foreach (ASP.BaseValidator validator in page.Validators)
02013                 {
02014                     if (validator.EnableClientScript)
02015                     {
02016                         if (page.Request.Browser.EcmaScriptVersion.CompareTo(new Version(1,2)) >= 0)
02017                             return true;
02018                     }
02019                 }
02020             }
02021             return false;
02022 #endif
02023         }
02024 
02032         private void OnUnload(object sender, EventArgs e)
02033         {
02034             HttpResponse response = HttpContext.Current.Response;
02035 
02036             if (Manager.IsCallBack && response.StatusCode == 302)
02037             {
02038                 string href = response.RedirectLocation.Replace("\\", "\\\\").Replace("'", "\\'");
02039                 response.RedirectLocation = string.Empty;
02040                 response.Clear();
02041                 response.StatusCode = 200;
02042                 StringBuilder sb = new StringBuilder();
02043                 Manager.AddScriptForClientSideEval("window.location='" + href + "';");
02044                 Manager.WriteValueAndError(sb, null, null, null, null, null, null, null);
02045                 response.Write(sb.ToString());
02046                 response.End();
02047             }
02048         }
02049 
02050         private void RegisterPageScript(Page page)
02051         {
02052             string formID = GetFormID(page);
02053 
02054             string pageScript = @"<script type=""text/javascript"">
//<![CDATA[
var Anthem_FormID = """ + formID + @""";
//]]>
</script>";
02055 
02056 #if V2
02057             if (!String.IsNullOrEmpty(formID))
02058                 page.ClientScript.RegisterClientScriptBlock(typeof(Manager), "pageScript", pageScript);
02059 #else
02060             page.RegisterClientScriptBlock(typeof(Manager).FullName, pageScript);
02061 #endif
02062 
02063 #if V2
02064 #if DEBUG
02065             Stream stream = typeof(Anthem.Manager).Assembly.GetManifestResourceStream("Anthem.Anthem.js");
02066             StreamReader sr = new StreamReader(stream);
02067             page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Anthem.js", 
02068                 @"<script type=""text/javascript"">
//<![CDATA[
" + sr.ReadToEnd() + @"
//]]>
</script>");
02069 #else
02070             page.ClientScript.RegisterClientScriptResource(typeof(Anthem.Manager), "Anthem.Anthem.js");
02071 #endif
02072 #else
02073             string baseUri = ConfigurationSettings.AppSettings["Anthem.BaseUri"];
02074             if (baseUri != null && baseUri.Length > 0)
02075             {
02076                 if (baseUri.StartsWith("~"))
02077                     baseUri = page.ResolveUrl(baseUri);
02078                 string scriptUri = System.IO.Path.Combine(baseUri, "Anthem.js");
02079                 page.RegisterClientScriptBlock("Anthem.js", string.Format("<script type='text/javascript' src='{0}'></script>", scriptUri));
02080             }
02081             else
02082             {
02083                 Stream stream = typeof(Anthem.Manager).Assembly.GetManifestResourceStream("Anthem.Anthem.js");
02084                 StreamReader sr = new StreamReader(stream);
02085                 page.RegisterClientScriptBlock("Anthem.js",
02086                     @"<script type=""text/javascript"">
//<![CDATA[
" + sr.ReadToEnd() + @"
//]]>
</script>");
02087             }
02088 #endif
02089         }
02090 
02091         internal void WriteResult(Stream stream, MemoryStream htmlBuffer)
02092         {
02093             string viewState = null;
02094             string viewStateEncrypted = null;
02095             string eventValidation = null;
02096             Hashtable controls = null;
02097             string[] scripts = null;
02098             if (_updatePage)
02099             {
02100                 string html = HttpContext.Current.Response.ContentEncoding.GetString(htmlBuffer.GetBuffer());
02101                 viewState = GetViewState(html);
02102 #if V2
02103                 viewStateEncrypted = GetViewStateEncrypted(html);
02104                 eventValidation = GetEventValidation(html);
02105 #endif
02106                 controls = GetControls(html);
02107                 foreach (object o in _targets.Values)
02108                 {
02109                     Control c = o as Control;
02110                     if (c != null && !c.Visible)
02111                     {
02112                         if (c.ID != null && controls.ContainsKey(c.ID))
02113                             controls[c.ID] = "";
02114                     }
02115                 }
02116 
02117                 scripts = GetScripts(html);
02118             }
02119             StringBuilder sb = new StringBuilder();
02120             try
02121             {
02122                 WriteValueAndError(sb, _value, _error, viewState, viewStateEncrypted, eventValidation, controls, scripts);
02123             }
02124             catch (Exception ex)
02125             {
02126                 // If an exception was thrown while formatting the
02127                 // result value, we need to discard whatever was
02128                 // written and start over with nothing but the error
02129                 // message.
02130                 sb.Length = 0;
02131                 WriteValueAndError(sb, null, ex.Message, null, null, null, null, null);
02132             }
02133 
02134             // If an IOFrame was used to make this callback, then wrap the response in a <textarea> element
02135             // so the iframe will not mess with the text of the JSON object.
02136             string response = sb.ToString();
02137             if (string.Compare(HttpContext.Current.Request["Anthem_IOFrame"], "true", true) == 0)
02138             {
02139                 response = "<textarea id=\"response\">" + response + "</textarea>";
02140             }
02141 
02142             byte[] buffer = HttpContext.Current.Response.ContentEncoding.GetBytes(response);
02143             stream.Write(buffer, 0, buffer.Length);
02144         }
02145 
02146         #endregion
02147     }
02148 
02149     #region Internal Class CallBackFilter
02150 
02151     internal class CallBackFilter : Stream
02152     {
02153         private Anthem.Manager _manager;
02154         private Stream _next;
02155         private MemoryStream _buffer;
02156 
02157         internal CallBackFilter(Anthem.Manager manager, Stream next)
02158         {
02159             _manager = manager;
02160             _next = next;
02161             _buffer = new MemoryStream();
02162         }
02163 
02164         public override bool CanRead
02165         {
02166             get { return false; }
02167         }
02168 
02169         public override bool CanSeek
02170         {
02171             get { return false; }
02172         }
02173 
02174         public override bool CanWrite
02175         {
02176             get { return true; }
02177         }
02178 
02179         public override long Length
02180         {
02181             get { return 0; }
02182         }
02183 
02184         public override long Position
02185         {
02186             get { return 0; }
02187             set { }
02188         }
02189 
02190         public override void Close()
02191         {
02192             _manager.WriteResult(_next, _buffer);
02193             base.Close();
02194         }
02195 
02196         public override void Flush()
02197         {
02198         }
02199 
02200         public override long Seek(long offset, SeekOrigin origin)
02201         {
02202             return 0;
02203         }
02204 
02205         public override void SetLength(long value)
02206         {
02207         }
02208 
02209         public override int Read(byte[] buffer, int offset, int count)
02210         {
02211             return 0;
02212         }
02213 
02214         public override void Write(byte[] buffer, int offset, int count)
02215         {
02216             _buffer.Write(buffer, offset, count);
02217         }
02218     }
02219     #endregion
02220 }
02221 

Generated on Wed Mar 14 23:50:39 2007 for Anthem by  doxygen 1.5.1-p1