Dec 25, 2013, 1:03 PM
Nice. Thank you for the update.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Configuration;
using Ext.Net;
using Ext.Net.Extension.Encryption;
namespace Ext.Net.Extension {
/// <summary>
/// Ext.Net Extension Methods
/// </summary>
public static partial class XExt {
#region Auto-Load/Manage Registered Controls
public readonly static string AS_EncryptionKey = ConfigurationManager.AppSettings["EncryptionKey"];
public enum PostRenderModes { None = 0, Render, ReRender, Update, UpdateContent, UpdateLayout };
/// <summary>
/// Registered a control to be auto-loaded by LoadRegisteredUserControls
/// </summary>
public static void RegisterUserControl( this System.Web.UI.Control Parent, string ucPath, string ctlID, ClientIDMode idmode = ClientIDMode.Predictable, PostRenderModes rendermode = PostRenderModes.None ) {
RegisterUserControl( Parent.Page, Parent, ucPath, ctlID, idmode, rendermode );
}
/// <summary>
/// Registered a control to be auto-loaded by LoadRegisteredUserControls
/// </summary>
public static void RegisterUserControl( this System.Web.UI.Control Parent, string ucPath, UserControl uc, ClientIDMode idmode = ClientIDMode.Predictable, PostRenderModes rendermode = PostRenderModes.None ) {
RegisterUserControl( Parent.Page, Parent, ucPath, uc.ClientID, idmode, rendermode );
}
/// <summary>
/// Registered a control to be auto-loaded by LoadRegisteredUserControls
/// </summary>
public static void RegisterUserControl( this Page Page, string ucPath, string ctlID, ClientIDMode idmode = ClientIDMode.Predictable, PostRenderModes rendermode = PostRenderModes.None ) {
RegisterUserControl( Page, null, ucPath, ctlID, idmode, rendermode );
}
/// <summary>
/// Registered a control to be auto-loaded by LoadRegisteredUserControls
/// </summary>
public static void RegisterUserControl( this Page Page, string ucPath, UserControl uc, ClientIDMode idmode = ClientIDMode.Predictable, PostRenderModes rendermode = PostRenderModes.None ) {
RegisterUserControl( Page, null, ucPath, uc.ClientID, idmode, rendermode );
}
private static void RegisterUserControl( Page Page, System.Web.UI.Control Parent, string ucPath, string ctlID, ClientIDMode idmode, PostRenderModes rendermode ) {
// Make sure EncryptionKey is set in web.config
if( string.IsNullOrEmpty( AS_EncryptionKey ) )
throw new ArgumentException( "To use this function, you must have set EncryptionKey in your appsettings of your web.config" );
// Skip Key Create if if we've already created the Key once in this Page life-cycle
var ruckey = UserControlAutoLoadKey;
if( string.IsNullOrEmpty( ruckey ) ) {
// Skip Key Create if the client has returned the key; we're still in the life-cycle of the same client page
ruckey = Page.Request.Form["RUCKey"];
if( string.IsNullOrEmpty( ruckey ) ) {
// Render the New Key Partial based on a new Unique Guid
ruckey = Guid.NewGuid().ToBase64();//ToString("N"); // alternate-way
// Add the key to the stream
( new Hidden() {
ID = "RUCKey",
Text = ruckey,
IDMode = IDMode.Static
} ).Render();
}
// Save the Key so it can be reused if another control is registered in this same Page life-cycle
UserControlAutoLoadKey = ruckey;
}
// Render the Encrypted Control information - ctl path, new ctlid, ctl parent id, idmode, and additional render instructions
( new Hidden() {
ID = "_RUC" + ctlID,
Text = Crypto.EncryptStringAES(
string.Concat( ucPath, ";", ctlID, ";", Parent == null ? "null" : Parent.ID, ";", idmode.ToString(), ";", rendermode.ToString() ),
AS_EncryptionKey + ruckey // combine the page key and the server key
),
IDMode = IDMode.Static
} ).Render();
}
/// <summary>
/// Add this to your aspx Page.Page_Load to ensure registered UserControls get readded to existing parent controls.
/// Make sure this function is called if X.IsAjaxRequest or IsPostback
///
/// If your Page contains UserControls that have dynamic run-time created controls, instead override RaisePostBackEvent in your Page as follows
/// protected override void RaisePostBackEvent( IPostBackEventHandler source, string eventArgument ) {
/// Page.LoadRegisteredUserControls(source);
/// base.RaisePostBackEvent( source, eventArgument );
/// }
/// </summary>
public static void LoadRegisteredUserControls( this Page Page ) {
// Unnecessary if in not in Postback
if( !X.IsAjaxRequest )
return;
// Only process if RUCKey exists
var Request = Page.Request;
var ruckey = Request.Form["RUCKey"];
if( string.IsNullOrEmpty( ruckey ) )
return;
ruckey = AS_EncryptionKey + ruckey;
// Construct & Load Registered User Control List
int len = Request.Form.Count;
if( len <= 0 )
return;
var keys = Request.Form.AllKeys;
for( int i = 0; i < len; i++ ) {
var ruc = keys[i];
if( ruc.StartsWith( "_RUC" ) ) {
var rucstr = Crypto.DecryptStringAES( Request.Form[i], ruckey );
var split = rucstr.Split( ';' );
if( split == null || split.Length != 5 )
throw new Exception( "Registered User Control Invalid: " + Request.Form.AllKeys[i] );
var ucPath = split[0];
var ctlName = split[1];//uc.ClientID
var parentid = split[2];//parent.ID
var idmode = split[3];
var rm = split[4];
var rendermode = (PostRenderModes)Enum.Parse( typeof( PostRenderModes ), rm );
var ctl = Page.LoadControl( ucPath );
ctl.ID = ctlName;
ctl.ClientIDMode = (ClientIDMode)Enum.Parse( typeof( ClientIDMode ), idmode );
if( parentid != "null" ) {
var pctl = X.GetCmp( parentid );//ctl.Page.FindControl( parentid );
if( pctl == null )
throw new Exception( "Could not find Parent Control ID: " + parentid );
pctl.Controls.Add( ctl );
} else
Page.Controls.Add( ctl );
switch( rendermode ) {
case PostRenderModes.None:
break;
case PostRenderModes.Render:
( (BaseControl)ctl ).Render();
break;
case PostRenderModes.ReRender:
( (AbstractComponent)ctl ).ReRender();
break;
case PostRenderModes.Update:
ctl.Update();
break;
case PostRenderModes.UpdateContent:
( (AbstractContainer)ctl ).UpdateContent();
break;
case PostRenderModes.UpdateLayout:
( (AbstractComponent)ctl ).UpdateLayout();
break;
}
}
}
}
/// <summary>
/// Remove a registered control to prevent it from being loaded again by LoadRegisteredUserControls
/// </summary>
public static void RemoveRegisteredControl( this UserControl uc ) {
// Remove the Registered Hidden control
X.AddScript( RemoveRegisteredControlClient( uc ) );
}
/// <summary>
/// Remove a registered control to prevent it from being loaded again by LoadRegisteredUserControls
/// </summary>
public static void RemoveRegisteredControl( string ctlID ) {
// Remove the Registered Hidden control
X.AddScript( RemoveRegisteredControlClient( ctlID ) );
}
/// <summary>
/// Remove a registered control to prevent it from being loaded again by LoadRegisteredUserControls; Doesn't actually do the work, Client Script rendered to attach to listener
/// </summary>
public static string RemoveRegisteredControlClient( string ctlid ) {
// Remove the Registered Hidden control
return string.Concat( "App._RUC", ctlid, ".destroy();" );//\n\rExt.net.ResourceMgr.destroyCmp('App._RUC", ctl.ClientID, "');" );
}
/// <summary>
/// Remove a registered control to prevent it from being loaded again by LoadRegisteredUserControls; Doesn't actually do the work, Client Script rendered to attach to listener
/// </summary>
public static string RemoveRegisteredControlClient( this UserControl ctl ) {
// Remove the Registered Hidden control
return string.Concat( "App._RUC", ctl.ClientID, ".destroy();" );//\n\rExt.net.ResourceMgr.destroyCmp('App._RUC", ctl.ClientID, "');" );
}
/// <summary>
/// Adds Destroy Listener to AbstractComponent to remove the Registered Control from being loaded again by LoadRegisteredUserControls
/// Usage example: UserControl with Window with CloseAction="Destroy" - Wnd1.RemoveRegisteredControlOnDestroy(ctl);
/// </summary>
public static void RemoveRegisteredControlOnDestroy( this AbstractComponent comp, UserControl ctl ) {
// Remove the Registered Hidden control on Destroy
comp.AddListener( "destroy", new JFunction( RemoveRegisteredControlClient( ctl ) ) );
}
/// <summary>
/// Remove registered child controls of Parent to prevent them from being loaded again by LoadRegisteredUserControls; Doesn't actually do the work, Client Script rendered to attach to listener
/// </summary>
public static void RemoveRegisteredControlsFromParent( this AbstractContainer Parent ) {
RemoveRegisteredControlsFromParent( Parent.Page, Parent.ID );
}
/// <summary>
/// Remove registered child controls of Parent to prevent them from being loaded again by LoadRegisteredUserControls; Doesn't actually do the work, Client Script rendered to attach to listener
/// </summary>
public static void RemoveRegisteredControlsFromParent( this Page Page, string parentID ) {
// Only process if RUCKey exists
var Request = Page.Request;
var ruckey = Request.Form["RUCKey"];
if( string.IsNullOrEmpty( ruckey ) )
return;
ruckey = AS_EncryptionKey + ruckey;
// Tranverse Registered User Control List and look for Parent ClientID
int len = Request.Form.Count;
if( len <= 0 )
return;
var keys = Request.Form.AllKeys;
for( int i = 0; i < len; i++ ) {
var ruc = keys[i];
if( ruc.StartsWith( "_RUC" ) ) {
var rucstr = Crypto.DecryptStringAES( Request.Form[i], ruckey );
var split = rucstr.Split( ';' );
if( split == null || split.Length != 5 )
throw new Exception( "Registered User Control Invalid: " + Request.Form.AllKeys[i] );
var parentid = split[2];
if( parentid == parentID ) {
var ctlName = split[1];
RemoveRegisteredControl( ctlName );
//Request.Form.Remove("_RUC" + ctlName );// !! need to save the removal to prevent again
}
}
}
}
#endregion
#region Add/Replace Direct Controls
public delegate void BindFn( System.Web.UI.Control ctr );
/// <summary>
/// Add a User Control during a Direct Event that needs to be Rendered to Page, like adding a Bin object like Window
/// To Replace the existing, use same CtlName; To add new each time, make ctlName unique
/// </summary>
public static UserControl AddDirectControl( this Page Page, string ucPath, string ctlName, BindFn bindFn = null, bool Register = false ) {
// Load the User Control
var uc = (UserControl)Page.LoadControl( ucPath );
uc.ClientIDMode = System.Web.UI.ClientIDMode.Predictable;
uc.ID = ctlName;
// Convert UserControl to UserControlLoader
var ucl = new UserControlLoader();
ucl.Items.Add( uc );
// Give a chance to bind before adding the control
if( bindFn != null )
uc.Init += delegate( object sender, EventArgs e ) {
bindFn( uc );
};
// Render the control
HttpContext Context = HttpContext.Current;
Context.SetDirectRendering( true );
ucl.Render();
Context.SetDirectRendering( false );
// Make the control available to the Page Control Tree so it can be found if required - must be performed after Render
Page.Controls.Add( uc );
if( Register && X.IsAjaxRequest )
RegisterUserControl( Page, ucPath, uc, ClientIDMode.Predictable );
return (UserControl)uc;
}
/// <summary>
/// Add a UserControl to Parent Container without destroying any contents in the Parent; especially significant in a DirectEvent/Method when add/replacing controls in the parent.
/// To Replace an existing UserControl, use same CtlName; To add continuous UserControls of the same type, ensure ctlName uniqueness
/// </summary>
/// <param name="Parent">Parent Container to add the new User Control to</param>
/// <param name="ucPath">Path to UserControl to load</param>
/// <param name="ctlName">Name of the UserControl - must be specified</param>
/// <param name="items">true to add new UserControl to Parent's items; false to ContentControls</param>
/// <param name="bindFn">Function to bind data to the UserControl before it's Load event</param>
/// <param name="Register">true to Register the Control for Auto-reloading by LoadRegisteredUserControls</param>
/// <param name="SkipRender">true to skip Rendering from occuring in the DirectEvent; use only if rendering the Parent manually</param>
/// <returns>the created UserControl</returns>
public static UserControl AddDirectControl( this AbstractContainer Parent, string ucPath, string ctlName, bool items = false, BindFn bindFn = null, bool Register = false, bool SkipRender = false ) {
// Load the User Control
var uc = (UserControl)Parent.Page.LoadControl( ucPath );
uc.ClientIDMode = ClientIDMode.Predictable;
uc.ID = ctlName;
bool isajax= X.IsAjaxRequest;
HttpContext Context = isajax ? HttpContext.Current : null;
if( items ) {
// Convert UserControl to UserControlLoader
UserControlLoader ucl = new UserControlLoader();
ucl.Items.Add( uc );
// Render each control if in an DirectEvent/Method request
if( isajax ) {
// Give a chance to bind before adding the control
if( bindFn != null )
uc.Init += delegate( object sender, EventArgs e ) {
bindFn( uc );
};
// Add the item to the Items of the Parent so it can be rendered to the correct parent
Context.SetDirectRendering( true );
Parent.Items.Add( ucl );
Context.SetDirectRendering( false );
// Render each component in the UserControl control
if(SkipRender==false)
foreach( var control in ucl.Components ) {
control.Render( Parent.ClientID, RenderMode.AddTo );
}
} else {
// Not in DirectEvent/Method, just add the control normally for rendering
Parent.Items.Add( ucl );
// Give a chance to bind data to the control before adding
if( bindFn != null )
bindFn( uc );
}
} else {
// Render each control if in an DirectEvent/Method request
if( isajax ) {
// Give a chance to bind before adding the control
if( bindFn != null )
uc.Init += delegate( object sender, EventArgs e ) {
bindFn( uc );
};
// Create a wrapping container around the UserControl control !! Required until support for UserControlLoader.Render supported
if( SkipRender == false ) {
var cont = new Container() { Border = false };
Context.SetDirectRendering( true );
cont.ContentControls.Add( uc );
Parent.Items.Add( cont );
Context.SetDirectRendering( false );
cont.Render();
} else {
// If Skipping render, we don't need a container
Context.SetDirectRendering( true );
Parent.ContentControls.Add( uc );
Context.SetDirectRendering( false );
}
} else {
// Not in DirectEvent/Method, just add the control normally for rendering
Parent.ContentControls.Add( uc );
// Give a chance to bind before adding the control
if( bindFn != null )
bindFn( uc );
}
}
// If Automatice UserControl loader turned on, create the Registered Hidden fields
if( Register )
RegisterUserControl( Parent, ucPath, uc, ClientIDMode.Predictable );
return uc;
}
/// <summary>
/// Add a UserControl to Parent Container but entirely refreshing the Parent.
/// </summary>
/// <param name="Parent">Parent Container to add the new User Control to</param>
/// <param name="ucPath">Path to UserControl to load</param>
/// <param name="ctlName">Name of the UserControl - must be specified</param>
/// <param name="items">true to add new UserControl to Parent's items; false to ContentControls</param>
/// <param name="bindFn">Function to bind data to the UserControl before it's Load event</param>
/// <param name="Register">true to Register the Control for Auto-reloading by LoadRegisteredUserControls</param>
/// <returns>the created UserControl</returns>
public static UserControl AddDirectControlRefreshParent( this AbstractContainer Parent, string ucPath, string ctlName, bool items = false, BindFn bindFn = null, bool Register = false ) {
var uc = AddDirectControl( Parent, ucPath, ctlName, items, bindFn, Register, true ); // skip user control render because Parent Refresh will render
RefreshParent( Parent );
return uc;
}
/// <summary>
/// ReRender the entire Parent Container - This will destroy and replace all children and the entire frame of the parent and its controls
/// Before calling RefreshParent, make sure you call RemoveRegisteredControlsFromParent if you registered User controls to this parent and AddDirectControl with SkipRender=true if adding this way
/// </summary>
public static void RefreshParent( this AbstractContainer Parent ) {
if( X.IsAjaxRequest )
Parent.ReRender();
}
/// <summary>
/// ReRender only the Child Items of the Parent Container Only (e.g. Panel will not rerender buttons, topbars, bottombars, frames, etc)
/// Before calling RefreshParent, make sure you call RemoveRegisteredControlsFromParent if you registered User controls to this parent and AddDirectControl with SkipRender=true if adding this way
/// Be aware, you may need to destroy children manually on the client if more existed in the original render than do in the Refresh
/// </summary>
public static void RefreshChildren( this Panel Parent ) {
if( !X.IsAjaxRequest )
return;
// ReRender Items
var childitems = Parent.Items;
for( int i = 0, len = childitems.Count; i < len;i++ )
childitems[i].Render();
}
/// <summary>
/// Remove a registered control to prevent it from being loaded again by LoadRegisteredUserControls; Doesn't actually do the work, Client Script rendered to attach to listener
/// </summary>
public static string RemoveControlClient( string ctlID ) {
// Remove the Registered Hidden control
return string.Concat( "App.", ctlID, ".destroy();" );
}
public static UserControl ReplaceDirectControl( this AbstractContainer Parent, string ucPath, string ctlName, bool items = false, BindFn bindFn = null, bool Register = false ) {
X.AddScript( RemoveControlClient( Parent.ClientID ) );
return AddDirectControl( Parent, ucPath, ctlName, items, bindFn, Register );
}
public static UserControl ReplaceDirectControl( this AbstractContainer Parent, string ctlIDToReplace, string ucPath, string ctlName, bool items = false, BindFn bindFn = null, bool Register = false ) {
X.AddScript( RemoveControlClient( ctlIDToReplace ) );
return AddDirectControl( Parent, ucPath, ctlName, items, bindFn, Register );
}
/// <summary>
/// Remove a registered control to prevent it from being loaded again by LoadRegisteredUserControls
/// </summary>
public static void RemoveControl( string ctlID ) {
// Remove control
X.AddScript( RemoveControlClient( ctlID ) );
}
public static string GetUserControlAutoLoadKey( this HttpContext Context ) {
return (string)Context.Items["UserControlAutoLoadKey"];
}
public static string UserControlAutoLoadKey {
get {
return (string)HttpContext.Current.Items["UserControlAutoLoadKey"];
}
set {
HttpContext.Current.Items["UserControlAutoLoadKey"] = value;
}
}
public static bool GetDirectRendering( this HttpContext Context ) {
var o = Context.Items["DirectRendering"];
return o != null ? (bool)o : false;
}
public static void SetDirectRendering( this HttpContext Context, bool value ) {
Context.Items["DirectRendering"] = value;
}
public static bool DirectRendering {
get {
return HttpContext.Current.GetDirectRendering();
}
set {
HttpContext.Current.SetDirectRendering(value);
}
}
public static bool GetIsAjaxRequestNotRendering( this HttpContext Context ) {
return ( X.IsAjaxRequest && !Context.GetDirectRendering() );
}
public static bool IsAjaxRequestNotRendering {
get {
return ( X.IsAjaxRequest && !DirectRendering );
}
}
#endregion
#region Additional Functions
/// <summary>
/// http://stackoverflow.com/questions/1032376/guid-to-base64-for-url
/// </summary>
public static string ToBase64( this Guid guid ) {
var enc = Convert.ToBase64String( guid.ToByteArray() ).Replace( '/', '-' ).Replace( '+', '_' ).Replace( "=", "" );
int len = enc.Length;
if( len > 0 && enc[len - 1] == '=' ) {
len--;
if( len > 0 && enc[len - 1] == '=' )
len--;
return enc.Substring( 0, len );
}
return enc;
}
public static Guid GuidFromBase64( this string base64 ) {
base64 = base64.Replace( '-', '/' ).Replace( '_', '+' ) + "==";
return new Guid( Convert.FromBase64String( base64 ) );
}
#endregion
}
public class XPage : Page {
/// <summary>
/// Ensures that RegisteredUserControls are loaded after dynamic user controls are added and before ResourceManager.RaisePostBackEvent
/// </summary>
protected override void RaisePostBackEvent( IPostBackEventHandler source, string eventArgument ) {
// If Page Implents RaisePostback, only process for ResourceManager
if( ( source is ResourceManager ) )
Page.LoadRegisteredUserControls();
base.RaisePostBackEvent( source, eventArgument );
}
public bool DirectRendering {
get { return Context.GetDirectRendering(); }
set { Context.SetDirectRendering( value ); }
}
public bool IsAjaxRequestNotRendering {
get {
return ( X.IsAjaxRequest && !Context.GetDirectRendering() );
}
}
}
public class XUserControl : UserControlLoader {
public bool DirectRendering {
get { return Context.GetDirectRendering(); }
set { Context.SetDirectRendering( value ); }
}
public bool IsAjaxRequestNotRendering {
get {
return ( Ext.Net.X.IsAjaxRequest && !Context.GetDirectRendering() );
}
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace Ext.Net.Extension.Encryption {
/// <summary>
/// http://stackoverflow.com/questions/202011/encrypt-decrypt-string-in-net
/// </summary>
public class Crypto {
private static byte[] _salt = Encoding.ASCII.GetBytes( "o6806642kbM7c5" );
/// <summary>
/// Encrypt the given string using AES. The string can be decrypted using
/// DecryptStringAES(). The sharedSecret parameters must match.
/// </summary>
/// <param name="plainText">The text to encrypt.</param>
/// <param name="sharedSecret">A password used to generate a key for encryption.</param>
public static string EncryptStringAES( string plainText, string sharedSecret ) {
if( string.IsNullOrEmpty( plainText ) )
throw new ArgumentNullException( "plainText" );
if( string.IsNullOrEmpty( sharedSecret ) )
throw new ArgumentNullException( "sharedSecret" );
string outStr = null; // Encrypted string to return
RijndaelManaged aesAlg = null; // RijndaelManaged object used to encrypt the data.
try {
// generate the key from the shared secret and the salt
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes( sharedSecret, _salt );
// Create a RijndaelManaged object
aesAlg = new RijndaelManaged();
aesAlg.Key = key.GetBytes( aesAlg.KeySize / 8 );
// Create a decryptor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor( aesAlg.Key, aesAlg.IV );
// Create the streams used for encryption.
using( MemoryStream msEncrypt = new MemoryStream() ) {
// prepend the IV
msEncrypt.Write( BitConverter.GetBytes( aesAlg.IV.Length ), 0, sizeof( int ) );
msEncrypt.Write( aesAlg.IV, 0, aesAlg.IV.Length );
using( CryptoStream csEncrypt = new CryptoStream( msEncrypt, encryptor, CryptoStreamMode.Write ) ) {
using( StreamWriter swEncrypt = new StreamWriter( csEncrypt ) ) {
//Write all data to the stream.
swEncrypt.Write( plainText );
}
}
outStr = Convert.ToBase64String( msEncrypt.ToArray() );
}
}
finally {
// Clear the RijndaelManaged object.
if( aesAlg != null )
aesAlg.Clear();
}
// Return the encrypted bytes from the memory stream.
return outStr;
}
/// <summary>
/// Decrypt the given string. Assumes the string was encrypted using
/// EncryptStringAES(), using an identical sharedSecret.
/// </summary>
/// <param name="cipherText">The text to decrypt.</param>
/// <param name="sharedSecret">A password used to generate a key for decryption.</param>
public static string DecryptStringAES( string cipherText, string sharedSecret ) {
if( string.IsNullOrEmpty( cipherText ) )
throw new ArgumentNullException( "cipherText" );
if( string.IsNullOrEmpty( sharedSecret ) )
throw new ArgumentNullException( "sharedSecret" );
// Declare the RijndaelManaged object
// used to decrypt the data.
RijndaelManaged aesAlg = null;
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
try {
// generate the key from the shared secret and the salt
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes( sharedSecret, _salt );
// Create the streams used for decryption.
byte[] bytes = Convert.FromBase64String( cipherText );
using( MemoryStream msDecrypt = new MemoryStream( bytes ) ) {
// Create a RijndaelManaged object
// with the specified key and IV.
aesAlg = new RijndaelManaged();
aesAlg.Key = key.GetBytes( aesAlg.KeySize / 8 );
// Get the initialization vector from the encrypted stream
aesAlg.IV = ReadByteArray( msDecrypt );
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor( aesAlg.Key, aesAlg.IV );
using( CryptoStream csDecrypt = new CryptoStream( msDecrypt, decryptor, CryptoStreamMode.Read ) ) {
using( StreamReader srDecrypt = new StreamReader( csDecrypt ) )
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
finally {
// Clear the RijndaelManaged object.
if( aesAlg != null )
aesAlg.Clear();
}
return plaintext;
}
private static byte[] ReadByteArray( Stream s ) {
byte[] rawLength = new byte[sizeof( int )];
if( s.Read( rawLength, 0, rawLength.Length ) != rawLength.Length ) {
throw new SystemException( "Stream did not contain properly formatted byte array" );
}
byte[] buffer = new byte[BitConverter.ToInt32( rawLength, 0 )];
if( s.Read( buffer, 0, buffer.Length ) != buffer.Length ) {
throw new SystemException( "Did not read byte array properly" );
}
return buffer;
}
}
}
GenericNamedEvents.csusing System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.UI;
namespace Ext.Net.Extension {
/// <summary>
/// Multiple Global Named Events can be subscribed for and triggered
/// Lazy Singleton model proposed here: http://csharpindepth.com/Articles/General/Singleton.aspx
/// </summary>
public static class GlobalNamedEvents {
public static Dictionary<string, SortedDictionary<int, NamedEvent>> Get( HttpContext Context ) {
var o = Context.Items["GlobalNamedEvents"];
if( o == null )
Context.Items["GlobalNamedEvents"] = o = new Dictionary<string, SortedDictionary<int, NamedEvent>>();
return ( Dictionary<string, SortedDictionary<int, NamedEvent>>)o;
}
public class NamedEvent {
public string eventname;
public int order = 1000;
public string id;
public EventHandler evt;
public bool invoked = false;
}
/// <summary>
/// Subscribe/Wire event to eventname - one per id
/// </summary>
/// <param name="eventname">name of event to trigger</param>
/// <param name="action">EventHandler to subscribe to this trigger</param>
public static void Subscribe( HttpContext Context, NamedEvent namedevt ) {
// Check if the named event already exists
var Events = Get( Context );
SortedDictionary<int, NamedEvent> evt=null;
if( !Events.TryGetValue( namedevt.eventname, out evt ) ) {
// eventname not found, so create with first namedevent
Events.Add( namedevt.eventname, new SortedDictionary<int, NamedEvent>() { { namedevt.order, namedevt } } );
return;
}
// The item was already found, but we need to check if the id already appears
foreach( var nevt in evt ) {
if( nevt.Value.id == namedevt.id )
return;
}
// Existing type was not found, so add the item
evt.Add( namedevt.order, namedevt );
}
/// <summary>
/// Trigger all GenericEvents associated with the eventname
/// </summary>
/// <param name="eventname">name of event to trigger</param>
/// <param name="sender">caller</param>
/// <param name="args">arguments</param>
public static void Trigger( HttpContext Context, string eventname, object sender = null, EventArgs args = null ) {
var Events = Get( Context );
var evt = Events[eventname];// will exception if eventname has not been subscribed
// Invoke each subscriber - not important to lock since it should invoke only namedevents available at time of the trigger
foreach( var nevt in evt ) {
var callevt = nevt.Value;
if( !callevt.invoked ) {
callevt.invoked = true; // prevent calling again
callevt.evt.Invoke( sender, args );
}
}
}
}
}
javascript support functions./* Execute Function by Name */
function executeFunctionByName(functionName) {
var args=Array.prototype.slice.call(arguments,2);
var namespaces=functionName.split('.');
var func=namespaces.pop(),e;
for(var i=0;i<namespaces.length;i++)
e=window[namespaces[i]];
return e[func].apply(window,args);
}
/* Execute Function by Name End */
/* Html5 & Redirect History */
function isHtml5() {
return !!document.createElement('canvas').getContext;
}
/* Indicates if browser supports pushState */
function hasPushState() {
return !!history.pushState?true:false;
}
/* Calls psFn if pushState supported; nonpsFn if not. Allows you to call support two models depending on browser pushState Support */
function usePushState(psFn,nopsFn) {
if(hasPushState()) psFn(); else { if(nopsFn) nopsFn(); else psFn(); }
}
/* Add new url to browser address bar if pushstate is supported by browser. If popStateFn & popStateFnArgs passed, it will call the callback onPopState with the arguments (on browser back/fwd buttons).
Also replaces document form action so that url on postback changes Request.Url with new url */
function replaceUrl(url,popStateFn,popStateFnArgs) {
url = url.toString();
if(document.forms&&document.forms[0]) document.forms[0].action=url;
if(hasPushState()) {
var state={};state.fromurl = url;
if(popStateFn) state.popStateFn=popStateFn;
if(popStateFnArgs) state.popStateFnArgs=popStateFnArgs;
history.pushState(state,document.title,url);
}
}
var popped, initialURL;
if(hasPushState()) {
popped=false; initialURL=location.href;
window.onpopstate=function(evt) {
// Ignore inital popstate that some browsers fire on page load
var initialPop=!popped&&location.href==initialURL;
popped=true;
if(initialPop) return;
if(document.forms&&document.forms[0]) document.forms[0].action=location.href;
if(evt.state&&evt.state.popStateFn) executeFunctionByName(evt.state.popStateFn, evt.state.popStateFnArgs);
};
}
/* Html5 & History End */
ViewC.RemoveRegisteredControlsFromParent();
// Add controls to ViewC
ViewC.AddDirectControl( "~/Test.ascx", TestCtl, true, null, false, true ); // skip user control render because RefreshParent will render
ViewC.RefreshParent();
// Subscribe in Page_Init of each UserControl
protected void Page_Init( object sender, EventArgs e ) {
GlobalNamedEvents.Subscribe( Context,
new GlobalNamedEvents.NamedEvent() { eventname = "ResultsViewRefresh", order = 100, id = this.ClientID, evt = RefreshResults}
);
}
// EventHandler to call when ResultsViewRefresh Triggered
public void RefreshResults( object sender, EventArgs args ) {
PopulateSelected( (CLookupValues)Context.Items["CValues"] ); // Example: This would refresh the ResultsView
PopulateSaveButton(); // Example: This would update a Button in this UserControl
SelP.RefreshParent(); // Refresh The Parent Container
}
To trigger the Global Named Event using a DirectMethod in any UserControl [DirectMethod( IDMode = DirectMethodProxyIDMode.None, ShowMask = true )]
public void RefreshResults() {
GlobalNamedEvents.Trigger( Context, "ResultsViewRefresh", this, null );
}
Please note that the above example only looks to register a single subscriber to run RefreshResults. If however, more than one UserControl subscribed to the same Global Event Name to its own EventHandler, this trigger will call each UserControl's EventHandler that Subscribed by property order. One trigger can technically update hundreds of controls that render their own required section without having to refresh the page or know anything about the others. Each UserControl must maintain its own state (which can be initialized in the Page_Load or inside the EventHandler). Also note that EventHandlers are invoked in the Page Life-cycle at the time of the Trigger call (which should be inside a DirectMethod or Event as shown in the example which ensures it occurs after all UserControls have had their Load events completed). You can trigger the event from different DirectEvents/Methods, but Trigger will prevent invoking the EventHandler twice for the same control. var Selector = {
refresh: function (url) {
usePushState(
/* if html5 history.pushState is available, use DirectMethod */
function() {
replaceUrl(url, 'Selector.onPopState'); /* replace browser address with url - call onPopState on back/fwd */
App.direct.RefreshResults(url); /* call DirectMethod */
},
/* if history.pushState is not available, use redirection */
function() {
Ext.net.Mask.show({ 'msg': 'One moment, refreshing...' });
document.location = url; /* redirect to revised url */
}
);
}.
onPopState: function() {
App.direct.RefreshResults(location.href);
}
};
Now just call Selector.refresh() from a listener handler for a button or something.