using PostSharp.Aspects; using PostSharp.Aspects.Advices; using PostSharp.Extensibility; using PostSharp.Reflection; using PostSharp.Serialization; using System.Web.UI; namespace PostSharp.Samples.SessionState { /// <summary> /// Aspect that, when applied to an instance field or property of a <see cref="Page" /> or <see cref="Control" />, /// causes this field or property to be persisted in the view state state. /// </summary> [PSerializable] [LinesOfCodeAvoided(3)] [MulticastAttributeUsage(TargetTypeAttributes = MulticastAttributes.Instance)] public sealed class ViewStateAttribute : LocationInterceptionAspect, IInstanceScopedAspect { private string name; // At run-time, will be set to a delegate giving access to the 'ViewState' protected method. [ImportMember("ViewState")] public Property<StateBag> ViewState; /// <summary> /// Creates an instance of the aspect for a specific instance of the <see cref="Control" /> or <see cref="Page" />. /// </summary> object IInstanceScopedAspect.CreateInstance(AdviceArgs adviceArgs) { return MemberwiseClone(); } void IInstanceScopedAspect.RuntimeInitializeInstance() { } /// <summary> /// Method invoked at build-time to validate that the aspect has been applied to a valid field or property. /// </summary> /// <param name="locationInfo">Field or property to which the aspect has been applied.</param> /// <returns> /// <c>true</c> if <paramref name="locationInfo" /> is a valid target for the current aspect, otherwise /// <c>false</c>. /// </returns> public override bool CompileTimeValidate(LocationInfo locationInfo) { if (!typeof(Control).IsAssignableFrom(locationInfo.DeclaringType)) { Message.Write(locationInfo, SeverityType.Error, "VS01", "Cannot apply [ViewState] to {0} because the declaring type is not a Control or Page.", locationInfo); return false; } return true; } /// <summary> /// Method invoked at build-time to initialize the current aspect. /// </summary> /// <param name="targetLocation">Field or property to which the aspect has been applied.</param> public override void CompileTimeInitialize(LocationInfo targetLocation, AspectInfo aspectInfo) { // Set the name of the page view. name = targetLocation.DeclaringType.FullName + "." + targetLocation.Name; } /// <summary> /// Method invoked when (instead of) the target field or property is retrieved. /// </summary> /// <param name="args">Context information.</param> public override void OnGetValue(LocationInterceptionArgs args) { var value = ViewState.Get()[name]; if (value != null) { args.Value = value; } } /// <summary> /// Method invoked when (instead of) the target field or property is set to a new value. /// </summary> /// <param name="args">Context information.</param> public override void OnSetValue(LocationInterceptionArgs args) { ViewState.Get()[name] = args.Value; } } }