rework of result navigation support: sprnet-1040, sprnet-1052, sprnet-958, sprnet-567
added navigation demo to WebQuickStart
This commit is contained in:
@@ -19,7 +19,7 @@ Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "Spring.WebQuickStart.2005",
|
||||
Release.AspNetCompiler.ForceOverwrite = "true"
|
||||
Release.AspNetCompiler.FixedNames = "false"
|
||||
Release.AspNetCompiler.Debug = "False"
|
||||
VWDPort = "81"
|
||||
VWDPort = "4724"
|
||||
DefaultWebSiteLanguage = "Visual C#"
|
||||
EndProjectSection
|
||||
EndProject
|
||||
|
||||
@@ -68,6 +68,10 @@
|
||||
compose advanced validation rules that leverage validation groups, conditional validation,
|
||||
validator composition, as well as how to create and use your custom validators.
|
||||
</p>
|
||||
<h3><a href="Navigation/Default.aspx">Navigation Flow</a></h3>
|
||||
<p>
|
||||
Demoes configurable navigation flow capabilities.
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<%@ Page Language="C#" EnableViewState="true" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="Navigation_Default" %>
|
||||
<%@ Register TagPrefix="spring" Namespace="Spring.Web.UI.Controls" Assembly="Spring.Web" %>
|
||||
|
||||
<asp:Content runat="server" ContentPlaceHolderId="content">
|
||||
<p>
|
||||
Just like in the previous example, you should put a breakpoint
|
||||
on the Debug.Write(Employee) statement in the event handler for the Save button,
|
||||
so you can see how Employee object was populated by the framework.
|
||||
</p>
|
||||
<spring:DataBindingPanel runat="server">
|
||||
<table cellpadding="3" cellspacing="3" border="0">
|
||||
<spring:Panel VisibleIf="Context.Request['fromInvalidInput'] != null" runat="server">
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
You need to enter a value greater than 21 to pass.
|
||||
</td>
|
||||
</tr>
|
||||
</spring:Panel>
|
||||
<tr>
|
||||
<td>Your age:</td>
|
||||
<td>
|
||||
<asp:TextBox ID="txtAge" runat="server" BindingTarget="Age" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><asp:Button ID="btnReset" runat="server" Text="Reset" OnClick="btnReset_Click" /></td>
|
||||
<td><asp:Button ID="btnContinue" runat="server" Text="Continue" OnClick="btnContinue_Click" /></td>
|
||||
</tr>
|
||||
</table>
|
||||
</spring:DataBindingPanel>
|
||||
</asp:Content>
|
||||
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// Notice that your web page has to extend Spring.Web.UI.Page class
|
||||
/// in order to enable data binding and many other features.
|
||||
/// </summary>
|
||||
public partial class Navigation_Default : Spring.Web.UI.Page
|
||||
{
|
||||
public int Age;
|
||||
|
||||
protected override void FrameworkInitialize()
|
||||
{
|
||||
this.MasterPageFile = "Master.master";
|
||||
base.FrameworkInitialize();
|
||||
}
|
||||
|
||||
protected void Page_Load( object sender, EventArgs e )
|
||||
{ }
|
||||
|
||||
|
||||
protected void btnContinue_Click( object sender, EventArgs e )
|
||||
{
|
||||
if (Age > 21)
|
||||
{
|
||||
SetResult( "ok" );
|
||||
}
|
||||
else
|
||||
{
|
||||
Args["input"] = txtAge.Text;
|
||||
SetResult( "invalid_input" );
|
||||
}
|
||||
}
|
||||
|
||||
protected void btnReset_Click( object sender, EventArgs e )
|
||||
{
|
||||
SetResult( "start" );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<%@ Page Language="C#" EnableViewState="true" AutoEventWireup="true" CodeFile="InvalidInput.aspx.cs" Inherits="Navigation_InvalidInput" %>
|
||||
<%@ Register TagPrefix="spring" Namespace="Spring.Web.UI.Controls" Assembly="Spring.Web" %>
|
||||
|
||||
<asp:Content runat="server" contentPlaceHolderId="content">
|
||||
<p>
|
||||
The value you entered is invalid
|
||||
</p>
|
||||
<spring:DataBindingPanel runat="server">
|
||||
<table cellpadding="3" cellspacing="3" border="0">
|
||||
<tr>
|
||||
<td>Age you entered:</td>
|
||||
<td>
|
||||
<asp:Label ID="lblInput" runat="server" EnableViewState="false" BindingSource="Text" BindingTarget="Context.Items['input']" BindingDirection="TargetToSource" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td><asp:Button ID="btnBack" runat="server" Text="Back" OnClick="btnBack_Click" /></td>
|
||||
</tr>
|
||||
</table>
|
||||
</spring:DataBindingPanel>
|
||||
</asp:Content>
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
/// <summary>
|
||||
/// Notice that your web page has to extend Spring.Web.UI.Page class
|
||||
/// in order to enable data binding and many other features.
|
||||
/// </summary>
|
||||
public partial class Navigation_InvalidInput : Spring.Web.UI.Page
|
||||
{
|
||||
protected void Page_Load(object sender, EventArgs e)
|
||||
{
|
||||
string input = (string) this.Context.Items["input"];
|
||||
}
|
||||
|
||||
|
||||
protected void btnBack_Click(object sender, EventArgs e)
|
||||
{
|
||||
SetResult("start");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<%@ Master Language="C#" AutoEventWireup="true" CodeFile="Master.master.cs" Inherits="Navigation_Master" %>
|
||||
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head runat="server">
|
||||
<title>Prefix!</title>
|
||||
<asp:ContentPlaceHolder id="head" runat="server">
|
||||
</asp:ContentPlaceHolder>
|
||||
</head>
|
||||
<body>
|
||||
<h2><a href="../Default.aspx">Welcome to Spring.NET Web Framework Quick Start Guide</a></h2>
|
||||
<form id="form1" runat="server">
|
||||
<div>
|
||||
<h2>Navigation example</h2>
|
||||
<asp:ContentPlaceHolder id="content" runat="server">
|
||||
</asp:ContentPlaceHolder>
|
||||
</div>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Web;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
|
||||
public partial class Navigation_Master : Spring.Web.UI.MasterPage
|
||||
{
|
||||
protected void Page_Load( object sender, EventArgs e )
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Ok.aspx.cs" Inherits="Navigation_Ok" %>
|
||||
|
||||
<asp:Content runat="server" contentPlaceHolderId="content">
|
||||
<p>
|
||||
Passcode you entered was ok
|
||||
</p>
|
||||
<spring:DataBindingPanel runat="server">
|
||||
<table cellpadding="3" cellspacing="3" border="0">
|
||||
<tr>
|
||||
<td>The passcode is correct:</td>
|
||||
<td>
|
||||
<asp:Label ID="lblInput" runat="server" BindingSource="Text" BindingTarget="Request['age']" BindingDirection="TargetToSource" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td><asp:Button ID="btnRestart" runat="server" Text="Back" OnClick="btnRestart_Click" /></td>
|
||||
</tr>
|
||||
</table>
|
||||
</spring:DataBindingPanel>
|
||||
</asp:Content>
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Web;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
|
||||
public partial class Navigation_Ok : Spring.Web.UI.Page
|
||||
{
|
||||
protected void Page_Load( object sender, EventArgs e )
|
||||
{
|
||||
}
|
||||
|
||||
protected void btnRestart_Click(object sender, EventArgs e)
|
||||
{
|
||||
SetResult("start");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<spring>
|
||||
<context>
|
||||
<resource uri="config://spring/objects"/>
|
||||
</context>
|
||||
<objects xmlns="http://www.springframework.net">
|
||||
|
||||
<object type="Master.master">
|
||||
<property name="Results">
|
||||
<dictionary>
|
||||
<entry key="start" value="redirect:Default.aspx" />
|
||||
</dictionary>
|
||||
</property>
|
||||
</object>
|
||||
|
||||
<object name="standardPage" abstract="true">
|
||||
<property name="MasterPageFile" value="Master.master" />
|
||||
</object>
|
||||
|
||||
<!-- use the filename of your Page for the 'type' attribute to configure DI for a Page -->
|
||||
<object type="Default.aspx" parent="standardPage">
|
||||
<property name="Title" value="Navigation Flow Sample - Start Page"/>
|
||||
<property name="Results">
|
||||
<dictionary>
|
||||
<entry key="ok" value="redirect:Ok.aspx?age=%{Age}" />
|
||||
<entry key="invalid_input" value="transfer:InvalidInput.aspx?input=%{Args['input']}" />
|
||||
</dictionary>
|
||||
</property>
|
||||
</object>
|
||||
|
||||
<object type="InvalidInput.aspx" parent="standardPage">
|
||||
<property name="Title" value="Navigation Flow Sample - Invalid Input Page"/>
|
||||
<property name="Results">
|
||||
<dictionary>
|
||||
<!-- altough Master.master defines a 'start' result, you can always override it -->
|
||||
<entry key="start" value="redirect:Default.aspx?fromInvalidInput=true" />
|
||||
</dictionary>
|
||||
</property>
|
||||
</object>
|
||||
|
||||
<!--
|
||||
Ok.aspx doesn't have an explicit results. Instead it relies on "bubbling" results up the hierarchy,
|
||||
in our case up to Master.master (see above)
|
||||
-->
|
||||
<object type="Ok.aspx" parent="standardPage">
|
||||
<property name="Title" value="Navigation Flow Sample - Done"/>
|
||||
<property name="Results">
|
||||
<dictionary>
|
||||
</dictionary>
|
||||
</property>
|
||||
</object>
|
||||
|
||||
</objects>
|
||||
</spring>
|
||||
<system.web>
|
||||
|
||||
</system.web>
|
||||
</configuration>
|
||||
@@ -1843,7 +1843,7 @@ namespace Spring.Objects.Factory.Support
|
||||
|| suppressConfigure)
|
||||
{
|
||||
// Clone ObjectDefinition
|
||||
mergedObjectDefinition = new RootObjectDefinition( mergedObjectDefinition );
|
||||
mergedObjectDefinition = CreateRootObjectDefinition(mergedObjectDefinition);
|
||||
mergedObjectDefinition.IsSingleton = false;
|
||||
if (arguments != null)
|
||||
{
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace Spring.Objects.Factory.Support
|
||||
/// <author>Aleksandar Seovic</author>
|
||||
public sealed class WebObjectUtils
|
||||
{
|
||||
private static ILog s_log = LogManager.GetLogger(typeof(WebObjectUtils));
|
||||
private static ILog s_log = LogManager.GetLogger( typeof( WebObjectUtils ) );
|
||||
|
||||
// CLOVER:OFF
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace Spring.Objects.Factory.Support
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
private WebObjectUtils()
|
||||
{}
|
||||
{ }
|
||||
|
||||
// CLOVER:ON
|
||||
|
||||
@@ -84,51 +84,33 @@ namespace Spring.Objects.Factory.Support
|
||||
/// page could not be instantiated (for whatever reason, such as the
|
||||
/// ASPX <paramref name="pageUrl"/> not actually existing).
|
||||
/// </exception>
|
||||
public static IHttpHandler CreatePageInstance(string pageUrl)
|
||||
public static IHttpHandler CreatePageInstance( string pageUrl )
|
||||
{
|
||||
if (s_log.IsDebugEnabled)
|
||||
{
|
||||
s_log.Debug("creating page instance '" + pageUrl + "'");
|
||||
s_log.Debug( "creating page instance '" + pageUrl + "'" );
|
||||
}
|
||||
if (HttpContext.Current == null)
|
||||
|
||||
HttpContext ctx = HttpContext.Current;
|
||||
if (ctx == null)
|
||||
{
|
||||
throw new ObjectCreationException(
|
||||
"Unable to instantiate page. HttpContext is not defined.");
|
||||
"Unable to instantiate page. HttpContext is not defined." );
|
||||
}
|
||||
IHttpHandler page = null;
|
||||
try
|
||||
{
|
||||
#if NET_1_1
|
||||
HttpContext context = HttpContext.Current;
|
||||
string physicalPath = context.Server.MapPath(pageUrl);
|
||||
s_log.Debug(string.Format("constructing page virtual path '{0}' from physical file '{1}'", pageUrl, physicalPath));
|
||||
page = PageParser.GetCompiledPageInstance(pageUrl, physicalPath, context);
|
||||
#else
|
||||
HttpContext ctx = HttpContext.Current;
|
||||
if (ctx == null)
|
||||
{
|
||||
throw new ObjectCreationException("Unable to get page type. HttpContext is not defined.");
|
||||
}
|
||||
|
||||
string rootedVPath = WebUtils.CombineVirtualPaths(ctx.Request.CurrentExecutionFilePath, pageUrl);
|
||||
if (s_log.IsDebugEnabled)
|
||||
{
|
||||
s_log.Debug("page vpath is " + rootedVPath);
|
||||
}
|
||||
|
||||
page = BuildManager.CreateInstanceFromVirtualPath(rootedVPath,
|
||||
typeof(IHttpHandler)) as IHttpHandler;
|
||||
#endif
|
||||
page = CreateHandler( ctx, pageUrl );
|
||||
}
|
||||
catch (HttpException httpEx)
|
||||
{
|
||||
string msg = String.Format("Unable to instantiate page [{0}]: {1}", pageUrl, httpEx.Message);
|
||||
if(httpEx.GetHttpCode() == 404)
|
||||
string msg = String.Format( "Unable to instantiate page [{0}]: {1}", pageUrl, httpEx.Message );
|
||||
if (httpEx.GetHttpCode() == 404)
|
||||
{
|
||||
throw new FileNotFoundException(msg);
|
||||
throw new FileNotFoundException( msg );
|
||||
}
|
||||
s_log.Error(msg, httpEx);
|
||||
throw new ObjectCreationException(msg, httpEx);
|
||||
s_log.Error( msg, httpEx );
|
||||
throw new ObjectCreationException( msg, httpEx );
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -136,17 +118,42 @@ namespace Spring.Objects.Factory.Support
|
||||
FileNotFoundException fnfe = ex as FileNotFoundException;
|
||||
if (fnfe != null)
|
||||
{
|
||||
string fmsg = String.Format("Unable to instantiate page [{0}]: The file '{1}' does not exist.", pageUrl, fnfe.Message);
|
||||
throw new FileNotFoundException(fmsg);
|
||||
string fmsg = String.Format( "Unable to instantiate page [{0}]: The file '{1}' does not exist.", pageUrl, fnfe.Message );
|
||||
throw new FileNotFoundException( fmsg );
|
||||
}
|
||||
|
||||
string msg = String.Format("Unable to instantiate page [{0}]", pageUrl);
|
||||
s_log.Error(msg, ex);
|
||||
throw new ObjectCreationException(msg, ex);
|
||||
string msg = String.Format( "Unable to instantiate page [{0}]", pageUrl );
|
||||
s_log.Error( msg, ex );
|
||||
throw new ObjectCreationException( msg, ex );
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the raw handler instance without any exception handling
|
||||
/// </summary>
|
||||
/// <param name="ctx"></param>
|
||||
/// <param name="pageUrl"></param>
|
||||
/// <returns></returns>
|
||||
internal static IHttpHandler CreateHandler( HttpContext ctx, string pageUrl )
|
||||
{
|
||||
IHttpHandler page;
|
||||
#if NET_1_1
|
||||
string physicalPath = ctx.Server.MapPath(pageUrl);
|
||||
s_log.Debug(string.Format("constructing page virtual path '{0}' from physical file '{1}'", pageUrl, physicalPath));
|
||||
page = PageParser.GetCompiledPageInstance(pageUrl, physicalPath, ctx);
|
||||
#else
|
||||
string rootedVPath = WebUtils.CombineVirtualPaths( ctx.Request.CurrentExecutionFilePath, pageUrl );
|
||||
if (s_log.IsDebugEnabled)
|
||||
{
|
||||
s_log.Debug( "page vpath is " + rootedVPath );
|
||||
}
|
||||
|
||||
page = BuildManager.CreateInstanceFromVirtualPath( rootedVPath, typeof( IHttpHandler ) ) as IHttpHandler;
|
||||
#endif
|
||||
return page;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="System.Type"/> of the ASPX page
|
||||
/// referred to by the supplied <paramref name="pageUrl"/>.
|
||||
@@ -177,26 +184,26 @@ namespace Spring.Objects.Factory.Support
|
||||
/// page could not be instantiated (for whatever reason, such as the
|
||||
/// ASPX <paramref name="pageUrl"/> not actually existing).
|
||||
/// </exception>
|
||||
public static Type GetPageType(string pageUrl)
|
||||
public static Type GetPageType( string pageUrl )
|
||||
{
|
||||
AssertUtils.ArgumentHasText(pageUrl, "pageUrl");
|
||||
AssertUtils.ArgumentHasText( pageUrl, "pageUrl" );
|
||||
|
||||
HttpContext ctx = HttpContext.Current;
|
||||
if (ctx == null)
|
||||
{
|
||||
throw new ObjectCreationException("Unable to get page type. HttpContext is not defined.");
|
||||
throw new ObjectCreationException( "Unable to get page type. HttpContext is not defined." );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Type pageType = GetCompiledPageType(pageUrl);
|
||||
Type pageType = GetCompiledPageType( pageUrl );
|
||||
return pageType;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
string msg = String.Format("Unable to get page type for url [{0}]", pageUrl);
|
||||
s_log.Error(msg, ex);
|
||||
throw new ObjectCreationException(msg, ex);
|
||||
string msg = String.Format( "Unable to get page type for url [{0}]", pageUrl );
|
||||
s_log.Error( msg, ex );
|
||||
throw new ObjectCreationException( msg, ex );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,29 +218,29 @@ namespace Spring.Objects.Factory.Support
|
||||
/// The <see cref="System.Type"/> of the ASPX page
|
||||
/// referred to by the supplied <paramref name="pageUrl"/>.
|
||||
/// </returns>
|
||||
public static Type GetCompiledPageType(string pageUrl)
|
||||
public static Type GetCompiledPageType( string pageUrl )
|
||||
{
|
||||
if (s_log.IsDebugEnabled)
|
||||
{
|
||||
s_log.Debug("getting page type for " + pageUrl);
|
||||
s_log.Debug( "getting page type for " + pageUrl );
|
||||
}
|
||||
|
||||
string rootedVPath = WebUtils.CombineVirtualPaths(HttpContext.Current.Request.CurrentExecutionFilePath, pageUrl);
|
||||
string rootedVPath = WebUtils.CombineVirtualPaths( HttpContext.Current.Request.CurrentExecutionFilePath, pageUrl );
|
||||
if (s_log.IsDebugEnabled)
|
||||
{
|
||||
s_log.Debug("page vpath is " + rootedVPath);
|
||||
s_log.Debug( "page vpath is " + rootedVPath );
|
||||
}
|
||||
|
||||
Type pageType = null;
|
||||
#if NET_2_0
|
||||
pageType = BuildManager.GetCompiledType(rootedVPath); // requires rooted virtual path!
|
||||
pageType = BuildManager.GetCompiledType( rootedVPath ); // requires rooted virtual path!
|
||||
#else
|
||||
pageType = CreatePageInstance(pageUrl).GetType();
|
||||
#endif
|
||||
|
||||
if (s_log.IsDebugEnabled)
|
||||
{
|
||||
s_log.Debug(string.Format("got page type '{0}' for vpath '{1}'", pageType.FullName, rootedVPath));
|
||||
s_log.Debug( string.Format( "got page type '{0}' for vpath '{1}'", pageType.FullName, rootedVPath ) );
|
||||
}
|
||||
return pageType;
|
||||
}
|
||||
@@ -242,49 +249,49 @@ namespace Spring.Objects.Factory.Support
|
||||
/// <summary>
|
||||
/// Gets the controls type from a given filename
|
||||
/// </summary>
|
||||
public static Type GetControlType(string controlName)
|
||||
public static Type GetControlType( string controlName )
|
||||
{
|
||||
AssertUtils.ArgumentHasText(controlName, "controlName");
|
||||
AssertUtils.ArgumentHasText( controlName, "controlName" );
|
||||
if (s_log.IsDebugEnabled)
|
||||
{
|
||||
s_log.Debug("getting control type for " + controlName);
|
||||
s_log.Debug( "getting control type for " + controlName );
|
||||
}
|
||||
|
||||
HttpContext ctx = HttpContext.Current;
|
||||
if (ctx == null)
|
||||
{
|
||||
throw new ObjectCreationException("Unable to get control type. HttpContext is not defined.");
|
||||
throw new ObjectCreationException( "Unable to get control type. HttpContext is not defined." );
|
||||
}
|
||||
|
||||
string rootedVPath = WebUtils.CombineVirtualPaths(ctx.Request.CurrentExecutionFilePath, controlName);
|
||||
string rootedVPath = WebUtils.CombineVirtualPaths( ctx.Request.CurrentExecutionFilePath, controlName );
|
||||
|
||||
if (s_log.IsDebugEnabled)
|
||||
{
|
||||
s_log.Debug("control vpath is " + rootedVPath);
|
||||
s_log.Debug( "control vpath is " + rootedVPath );
|
||||
}
|
||||
|
||||
Type controlType = null;
|
||||
try
|
||||
{
|
||||
#if NET_2_0
|
||||
controlType = BuildManager.GetCompiledType(rootedVPath); // requires rooted virtual path!
|
||||
controlType = BuildManager.GetCompiledType( rootedVPath ); // requires rooted virtual path!
|
||||
#else
|
||||
controlType = (Type) miGetCompiledUserControlType.Invoke(null, new object[] { rootedVPath, null, ctx });
|
||||
#endif
|
||||
}
|
||||
catch(HttpException httpEx)
|
||||
catch (HttpException httpEx)
|
||||
{
|
||||
// for better error-handling suppress 404 HttpExceptions here
|
||||
if (httpEx.GetHttpCode() == 404)
|
||||
{
|
||||
throw new FileNotFoundException(string.Format("Control '{0}' does not exist", rootedVPath));
|
||||
throw new FileNotFoundException( string.Format( "Control '{0}' does not exist", rootedVPath ) );
|
||||
}
|
||||
throw;
|
||||
}
|
||||
|
||||
if (s_log.IsDebugEnabled)
|
||||
{
|
||||
s_log.Debug(string.Format("got control type '{0}' for vpath '{1}'", controlType.FullName, rootedVPath));
|
||||
s_log.Debug( string.Format( "got control type '{0}' for vpath '{1}'", controlType.FullName, rootedVPath ) );
|
||||
}
|
||||
return controlType;
|
||||
}
|
||||
|
||||
@@ -295,21 +295,6 @@
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Web\Process\IProcess.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Web\Process\IProcessAware.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Web\Process\ProcessManager.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Web\Providers\ConfigurableActiveDirectoryMembershipProvider.cs"
|
||||
SubType = "Code"
|
||||
@@ -390,11 +375,6 @@
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Web\Support\AbstractProcessHandler.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Web\Support\ContextMonitor.cs"
|
||||
SubType = "Code"
|
||||
@@ -405,6 +385,16 @@
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Web\Support\DefaultResultFactory.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Web\Support\IHierarchicalWebNavigator.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Web\Support\IInterceptionStrategy.cs"
|
||||
SubType = "Code"
|
||||
@@ -421,7 +411,17 @@
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Web\Support\ISharedStateAware.cs"
|
||||
RelPath = "Web\Support\IResult.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Web\Support\IResultFactory.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Web\Support\IResultWebNavigator.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
@@ -430,6 +430,16 @@
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Web\Support\IWebNavigable.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Web\Support\IWebNavigator.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Web\Support\MimeMediaType.cs"
|
||||
SubType = "Code"
|
||||
@@ -445,11 +455,21 @@
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Web\Support\ResultFactoryRegistry.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Web\Support\ResultMode.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Web\Support\ResultWebNavigator.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Web\Support\Script.cs"
|
||||
SubType = "Code"
|
||||
@@ -480,6 +500,11 @@
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Web\Support\WebFormsResultWebNavigator.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Web\UI\AbstractWizard.cs"
|
||||
SubType = "ASPXCodeBehind"
|
||||
|
||||
@@ -124,6 +124,15 @@
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Util\ISessionState.cs" />
|
||||
<Compile Include="Web\Support\DefaultResultFactory.cs" />
|
||||
<Compile Include="Web\Support\IResult.cs" />
|
||||
<Compile Include="Web\Support\IResultFactory.cs" />
|
||||
<Compile Include="Web\Support\ResultFactoryRegistry.cs" />
|
||||
<Compile Include="Web\Support\WebFormsResultWebNavigator.cs" />
|
||||
<Compile Include="Web\Support\IHierarchicalWebNavigator.cs" />
|
||||
<Compile Include="Web\Support\IResultWebNavigator.cs" />
|
||||
<Compile Include="Web\Support\IWebNavigable.cs" />
|
||||
<Compile Include="Web\Support\IWebNavigator.cs" />
|
||||
<Compile Include="Web\UI\IValidationContainer.cs" />
|
||||
<Compile Include="Web\Support\MimeMediaType.cs" />
|
||||
<Compile Include="Web\Support\SharedStateResourceCache.cs">
|
||||
@@ -260,6 +269,7 @@
|
||||
<Compile Include="Web\UI\Page.cs">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Web\Support\ResultWebNavigator.cs" />
|
||||
<Compile Include="Web\UI\UserControl.cs">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
|
||||
@@ -21,8 +21,7 @@
|
||||
#region Imports
|
||||
|
||||
using System;
|
||||
|
||||
|
||||
using System.Web.UI;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -241,5 +240,51 @@ namespace Spring.Util
|
||||
}
|
||||
return appRelativeVirtualPath;
|
||||
}
|
||||
|
||||
///<summary>
|
||||
/// Returns the 'logical' parent of the specified control. Technically when dealing with masterpages and control hierarchy,
|
||||
/// the order goes controls->masterpage->page. But one often wants the more logical order controls->page->masterpage.
|
||||
///</summary>
|
||||
///<param name="control">the control, who's parent is to be determined.</param>
|
||||
///<returns>the logical parent or <c>null</c> if the top of the hierarchy is reached.</returns>
|
||||
/// <exception cref="ArgumentNullException">if <paramref name="control"/> is <c>null</c></exception>
|
||||
public static Control GetLogicalParent(Control control)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(control, "control");
|
||||
|
||||
// to determine "correct" order of bubbling control->page->masterpage,
|
||||
// the trick below is necessary because technically the hierarchy goes
|
||||
// control->masterpage->page
|
||||
if (control is System.Web.UI.Page)
|
||||
{
|
||||
#if !NET_2_0
|
||||
control = ((Spring.Web.UI.Page)control).Master;
|
||||
#else
|
||||
control = ((System.Web.UI.Page)control).Master;
|
||||
#endif
|
||||
}
|
||||
else if (IsMaster(control))
|
||||
{
|
||||
control = null;
|
||||
}
|
||||
else if (IsMaster(control.Parent))
|
||||
{
|
||||
control = control.Page;
|
||||
}
|
||||
else
|
||||
{
|
||||
control = control.Parent;
|
||||
}
|
||||
return control;
|
||||
}
|
||||
|
||||
private static bool IsMaster(Control control)
|
||||
{
|
||||
#if !NET_2_0
|
||||
return (control is Spring.Web.UI.MasterPage);
|
||||
#else
|
||||
return (control is System.Web.UI.MasterPage);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2002-2005 the original author or authors.
|
||||
* Copyright <20> 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
34
src/Spring/Spring.Web/Web/Support/DefaultResultFactory.cs
Normal file
34
src/Spring/Spring.Web/Web/Support/DefaultResultFactory.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region Imports
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Web.Support
|
||||
{
|
||||
public class DefaultResultFactory : IResultFactory
|
||||
{
|
||||
public IResult CreateResult(string resultMode, string resultText)
|
||||
{
|
||||
return new Result(resultMode, resultText);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region Imports
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Web.Support
|
||||
{
|
||||
public interface IHierarchicalWebNavigator : IWebNavigator
|
||||
{
|
||||
IWebNavigator ParentNavigator { get; }
|
||||
}
|
||||
}
|
||||
8
src/Spring/Spring.Web/Web/Support/IResult.cs
Normal file
8
src/Spring/Spring.Web/Web/Support/IResult.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Spring.Web.Support
|
||||
{
|
||||
public interface IResult
|
||||
{
|
||||
void Navigate( object context );
|
||||
string GetRedirectUri( object context );
|
||||
}
|
||||
}
|
||||
7
src/Spring/Spring.Web/Web/Support/IResultFactory.cs
Normal file
7
src/Spring/Spring.Web/Web/Support/IResultFactory.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Spring.Web.Support
|
||||
{
|
||||
public interface IResultFactory
|
||||
{
|
||||
IResult CreateResult( string resultMode, string resultText );
|
||||
}
|
||||
}
|
||||
33
src/Spring/Spring.Web/Web/Support/IResultWebNavigator.cs
Normal file
33
src/Spring/Spring.Web/Web/Support/IResultWebNavigator.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region Imports
|
||||
|
||||
using System.Collections;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Web.Support
|
||||
{
|
||||
public interface IResultWebNavigator : IHierarchicalWebNavigator
|
||||
{
|
||||
IDictionary Results { get; set; }
|
||||
}
|
||||
}
|
||||
33
src/Spring/Spring.Web/Web/Support/IWebNavigable.cs
Normal file
33
src/Spring/Spring.Web/Web/Support/IWebNavigable.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region Imports
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Web.Support
|
||||
{
|
||||
public interface IWebNavigable
|
||||
{
|
||||
IWebNavigator WebNavigator { get; }
|
||||
}
|
||||
}
|
||||
39
src/Spring/Spring.Web/Web/Support/IWebNavigator.cs
Normal file
39
src/Spring/Spring.Web/Web/Support/IWebNavigator.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright 2002-2004 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region Imports
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Web.Support
|
||||
{
|
||||
public interface IWebNavigator
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines, whether this navigator or one of its parents can
|
||||
/// navigate to the result specified in <paramref name="resultName"/>.
|
||||
/// </summary>
|
||||
/// <param name="resultName">the name of the result</param>
|
||||
/// <returns>true, if this navigator or one of its parents can navigate to the result.</returns>
|
||||
bool CanNavigateTo( string resultName );
|
||||
void NavigateTo( string resultName, object context );
|
||||
string GetResultUri( string resultName, object context );
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright 2002-2004 the original author or authors.
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -118,7 +118,8 @@ namespace Spring.Web.Support
|
||||
}
|
||||
else
|
||||
{
|
||||
handler = WebObjectUtils.CreatePageInstance(url);
|
||||
handler = WebObjectUtils.CreateHandler(context, url);
|
||||
|
||||
// is this a nested call (HttpServerUtility.Transfer() or HttpServerUtility.Execute())?
|
||||
if (context.Handler != null)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2002-2005 the original author or authors.
|
||||
* Copyright <20> 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,6 +24,7 @@ using System;
|
||||
using System.Collections;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using Spring.Collections;
|
||||
using Spring.Expressions;
|
||||
using Spring.Util;
|
||||
|
||||
@@ -73,7 +74,7 @@ namespace Spring.Web.Support
|
||||
/// <author>Aleksandar Seovic</author>
|
||||
/// <author>Matan Shapira</author>
|
||||
[Serializable]
|
||||
public class Result
|
||||
public class Result : IResult
|
||||
{
|
||||
#region Constants
|
||||
|
||||
@@ -122,15 +123,52 @@ namespace Spring.Web.Support
|
||||
/// If the supplied <paramref name="result"/> is <see langword="null"/> or
|
||||
/// contains only whitespace character(s).
|
||||
/// </exception>
|
||||
public Result(string result)
|
||||
/// <exception cref="ArgumentOutOfRangeException">if the result mode is unknown.</exception>
|
||||
public Result( string result )
|
||||
{
|
||||
AssertUtils.ArgumentHasText(result, "result");
|
||||
result = ExtractAndSetResultMode(result);
|
||||
int indexOfQueryStringDelimiter = result.IndexOf('?');
|
||||
AssertUtils.ArgumentHasText( result, "result" );
|
||||
|
||||
result = ExtractAndSetResultMode( result );
|
||||
|
||||
int indexOfQueryStringDelimiter = result.IndexOf( '?' );
|
||||
if (indexOfQueryStringDelimiter > 0)
|
||||
{
|
||||
ParseParameters(result.Substring(indexOfQueryStringDelimiter + 1));
|
||||
result = result.Substring(0, indexOfQueryStringDelimiter);
|
||||
ParseParameters( result.Substring( indexOfQueryStringDelimiter + 1 ) );
|
||||
result = result.Substring( 0, indexOfQueryStringDelimiter );
|
||||
}
|
||||
targetPage = result.Trim();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="Spring.Web.Support.Result"/> class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// See both the class documentation (<see cref="Spring.Web.Support.Result"/>)
|
||||
/// and the reference documentation for the Spring.Web library for a
|
||||
/// discussion and examples of what values the supplied <paramref name="result"/>
|
||||
/// can have.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="resultMode">The desired result mode. May be null to use default mode.</param>
|
||||
/// <param name="resultText">The result descriptor (without resultMode prefix!).</param>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// If the supplied <paramref name="resultText"/> is <see langword="null"/> or
|
||||
/// contains only whitespace character(s).
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">if the result mode is unknown.</exception>
|
||||
public Result( string resultMode, string resultText )
|
||||
{
|
||||
AssertUtils.ArgumentHasText( resultText, "resultText" );
|
||||
|
||||
this.SetResultMode( resultMode );
|
||||
|
||||
string result = resultText;
|
||||
int indexOfQueryStringDelimiter = result.IndexOf( '?' );
|
||||
if (indexOfQueryStringDelimiter > 0)
|
||||
{
|
||||
ParseParameters( result.Substring( indexOfQueryStringDelimiter + 1 ) );
|
||||
result = result.Substring( 0, indexOfQueryStringDelimiter );
|
||||
}
|
||||
targetPage = result.Trim();
|
||||
}
|
||||
@@ -202,23 +240,23 @@ namespace Spring.Web.Support
|
||||
/// Navigates to the <see cref="Spring.Web.Support.Result.TargetPage"/>
|
||||
/// defined by this result.
|
||||
/// </summary>
|
||||
/// <param name="page">
|
||||
/// <param name="context">
|
||||
/// The context object for parameter resolution. This is typically
|
||||
/// a <see cref="System.Web.UI.Page"/>.
|
||||
/// </param>
|
||||
public virtual void Navigate(object page)
|
||||
public virtual void Navigate( object context )
|
||||
{
|
||||
switch (Mode)
|
||||
{
|
||||
case ResultMode.Redirect:
|
||||
DoRedirect(page);
|
||||
DoRedirect( context );
|
||||
break;
|
||||
case ResultMode.Transfer:
|
||||
case ResultMode.TransferNoPreserve:
|
||||
DoTransfer(page);
|
||||
DoTransfer( context );
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(string.Format("Unknown ResultMode {0}", Mode));
|
||||
throw new ArgumentOutOfRangeException( string.Format( "Unknown ResultMode {0}", Mode ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,33 +264,33 @@ namespace Spring.Web.Support
|
||||
/// Performs a server-side transfer to the
|
||||
/// <see cref="Spring.Web.Support.Result.TargetPage"/> defined by this result.
|
||||
/// </summary>
|
||||
/// <param name="page">
|
||||
/// <param name="context">
|
||||
/// The context object for parameter resolution. This is typically
|
||||
/// a <see cref="System.Web.UI.Page"/>.
|
||||
/// </param>
|
||||
/// <seealso cref="System.Web.HttpServerUtility.Transfer(string,bool)"/>
|
||||
protected virtual void DoTransfer(object page)
|
||||
protected virtual void DoTransfer( object context )
|
||||
{
|
||||
HttpContext ctx = HttpContext.Current;
|
||||
SetTransferParameters(ctx.Items, page);
|
||||
ctx.Server.Transfer(TargetPage, PreserveForm);
|
||||
SetTransferParameters( ctx.Items, context );
|
||||
ctx.Server.Transfer( GetResolvedTargetPage( context ), PreserveForm );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resolves transfer parameters and stores them into <see cref="IDictionary" /> instance.
|
||||
/// </summary>
|
||||
/// <param name="contextDictionary"></param>
|
||||
/// <param name="page"></param>
|
||||
protected void SetTransferParameters(IDictionary contextDictionary, object page)
|
||||
/// <param name="context"></param>
|
||||
protected void SetTransferParameters( IDictionary contextDictionary, object context )
|
||||
{
|
||||
if (this.parameters != null && this.parameters.Count > 0)
|
||||
{
|
||||
foreach (DictionaryEntry entry in this.parameters)
|
||||
{
|
||||
string value = entry.Value.ToString();
|
||||
if (IsRuntimeExpression(value))
|
||||
if (IsRuntimeExpression( value ))
|
||||
{
|
||||
contextDictionary[entry.Key] = ResolveRuntimeExpression(page, value);
|
||||
contextDictionary[entry.Key] = ResolveRuntimeExpression( context, value );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -267,14 +305,14 @@ namespace Spring.Web.Support
|
||||
/// <see cref="Spring.Web.Support.Result.TargetPage"/> defined by this
|
||||
/// result.
|
||||
/// </summary>
|
||||
/// <param name="page">
|
||||
/// <param name="context">
|
||||
/// The context object for parameter resolution. This is typically
|
||||
/// a <see cref="System.Web.UI.Page"/>.
|
||||
/// </param>
|
||||
/// <seealso cref="System.Web.HttpResponse.Redirect(string)"/>
|
||||
protected virtual void DoRedirect(object page)
|
||||
protected virtual void DoRedirect( object context )
|
||||
{
|
||||
HttpContext.Current.Response.Redirect(GetRedirectUri(page));
|
||||
HttpContext.Current.Response.Redirect( GetRedirectUri( context ) );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -282,45 +320,74 @@ namespace Spring.Web.Support
|
||||
/// <see cref="Spring.Web.Support.Result.TargetPage"/> defined by this
|
||||
/// result.
|
||||
/// </summary>
|
||||
/// <param name="page">
|
||||
/// <param name="context">
|
||||
/// A redirect url string.
|
||||
/// </param>
|
||||
public string GetRedirectUri(object page)
|
||||
public virtual string GetRedirectUri( object context )
|
||||
{
|
||||
StringBuilder url = new StringBuilder(256);
|
||||
url.Append(TargetPage);
|
||||
if (parameters != null && parameters.Count > 0)
|
||||
string path = GetResolvedTargetPage( context );
|
||||
|
||||
IDictionary resolvedParameters = null;
|
||||
if (this.Parameters != null && this.Parameters.Count > 0)
|
||||
{
|
||||
resolvedParameters = new CaseInsensitiveHashtable();
|
||||
foreach (DictionaryEntry entry in this.Parameters)
|
||||
{
|
||||
object key = ResolveRuntimeExpressionIfNecessary( context, entry.Key.ToString() );
|
||||
object value = ResolveRuntimeExpressionIfNecessary( context, entry.Value.ToString() );
|
||||
resolvedParameters[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return BuildUrl( path, resolvedParameters );
|
||||
}
|
||||
|
||||
protected virtual string BuildUrl( string resolvedPath, IDictionary resolvedParameters )
|
||||
{
|
||||
StringBuilder url = new StringBuilder( 256 );
|
||||
url.Append( resolvedPath );
|
||||
if (resolvedParameters != null && resolvedParameters.Count > 0)
|
||||
{
|
||||
char separator = '?';
|
||||
foreach (DictionaryEntry entry in parameters)
|
||||
foreach (DictionaryEntry entry in resolvedParameters)
|
||||
{
|
||||
url.Append(separator);
|
||||
url.Append(entry.Key).Append('=');
|
||||
string value = entry.Value.ToString();
|
||||
if (IsRuntimeExpression(value))
|
||||
{
|
||||
url.Append(HttpContext.Current.Server.UrlEncode(
|
||||
ResolveRuntimeExpression(page, value).ToString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
url.Append(HttpContext.Current.Server.UrlEncode(value));
|
||||
}
|
||||
url.Append( separator );
|
||||
url.Append( BuildUrlParameter( entry.Key.ToString(), entry.Value.ToString() ) );
|
||||
separator = '&';
|
||||
}
|
||||
}
|
||||
return url.ToString();
|
||||
}
|
||||
|
||||
private static bool IsRuntimeExpression(string value)
|
||||
protected virtual string BuildUrlParameter( string key, string value )
|
||||
{
|
||||
// allow for 2 alternative prefixes (SPRNET-864)
|
||||
return (value.StartsWith("${") || value.StartsWith("%{")) && value.EndsWith("}");
|
||||
return UrlEncode( key ) + "=" + UrlEncode( value );
|
||||
}
|
||||
|
||||
private static object ResolveRuntimeExpression(object page, string value)
|
||||
protected static string UrlEncode( string value )
|
||||
{
|
||||
return ExpressionEvaluator.GetValue(page, value.Substring(2, value.Length - 3));
|
||||
HttpContext ctx = HttpContext.Current;
|
||||
return (ctx == null) ? HttpUtility.UrlEncode( value ) : ctx.Server.UrlEncode( value );
|
||||
}
|
||||
|
||||
protected object ResolveRuntimeExpressionIfNecessary( object context, string value )
|
||||
{
|
||||
if (IsRuntimeExpression( value ))
|
||||
{
|
||||
return ResolveRuntimeExpression( context, value );
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private static bool IsRuntimeExpression( string value )
|
||||
{
|
||||
// allow for 2 alternative prefixes (SPRNET-864)
|
||||
return (value.StartsWith( "${" ) || value.StartsWith( "%{" )) && value.EndsWith( "}" );
|
||||
}
|
||||
|
||||
private static object ResolveRuntimeExpression( object context, string value )
|
||||
{
|
||||
return ExpressionEvaluator.GetValue( context, value.Substring( 2, value.Length - 3 ) );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -345,44 +412,61 @@ namespace Spring.Web.Support
|
||||
/// If the supplied <paramref name="result"/> starts with an illegal
|
||||
/// result mode (see <see cref="Spring.Web.Support.ResultMode"/>).
|
||||
/// </exception>
|
||||
private string ExtractAndSetResultMode(string result)
|
||||
private string ExtractAndSetResultMode( string result )
|
||||
{
|
||||
int indexOfResultModeDelimiter = result.IndexOf(':');
|
||||
int indexOfResultModeDelimiter = result.IndexOf( ':' );
|
||||
if (indexOfResultModeDelimiter > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
Mode = (ResultMode)Enum.Parse(typeof(ResultMode),
|
||||
result.Substring(0, indexOfResultModeDelimiter), true);
|
||||
return result.Substring(indexOfResultModeDelimiter + 1);
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("result", result, "Illegal result mode.");
|
||||
}
|
||||
string resultMode = result.Substring( 0, indexOfResultModeDelimiter );
|
||||
SetResultMode( resultMode );
|
||||
return result.Substring( indexOfResultModeDelimiter + 1 );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the actual <see cref="Mode"/> from the parsed <paramref name="resultMode"/> string.
|
||||
/// </summary>
|
||||
/// <param name="resultMode">the parsed result mode</param>
|
||||
protected virtual void SetResultMode( string resultMode )
|
||||
{
|
||||
try
|
||||
{
|
||||
if (StringUtils.HasText( resultMode ))
|
||||
{
|
||||
Mode = (ResultMode)Enum.Parse( typeof( ResultMode ), resultMode, true );
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new ArgumentOutOfRangeException( "resultMode", resultMode, "Illegal result mode." );
|
||||
}
|
||||
}
|
||||
|
||||
protected string GetResolvedTargetPage( object context )
|
||||
{
|
||||
return ResolveRuntimeExpressionIfNecessary( context, TargetPage ).ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses query parameters from the supplied <paramref name="queryString"/>.
|
||||
/// </summary>
|
||||
/// <param name="queryString">
|
||||
/// The query string (may be <cref lang="null"/>).
|
||||
/// </param>
|
||||
private void ParseParameters(string queryString)
|
||||
private void ParseParameters( string queryString )
|
||||
{
|
||||
if (StringUtils.HasText(queryString))
|
||||
if (StringUtils.HasText( queryString ))
|
||||
{
|
||||
this.parameters = new Hashtable();
|
||||
string[] nameValuePairs = queryString.Split("&,".ToCharArray());
|
||||
this.parameters = new CaseInsensitiveHashtable();
|
||||
string[] nameValuePairs = queryString.Split( "&,".ToCharArray() );
|
||||
foreach (string pair in nameValuePairs)
|
||||
{
|
||||
int n = pair.IndexOf('=');
|
||||
int n = pair.IndexOf( '=' );
|
||||
if (n > 0)
|
||||
{
|
||||
string name = pair.Substring(0, n);
|
||||
string val = pair.Substring(n + 1).Trim();
|
||||
string name = pair.Substring( 0, n );
|
||||
string val = pair.Substring( n + 1 ).Trim();
|
||||
this.parameters[name] = val;
|
||||
}
|
||||
}
|
||||
|
||||
101
src/Spring/Spring.Web/Web/Support/ResultFactoryRegistry.cs
Normal file
101
src/Spring/Spring.Web/Web/Support/ResultFactoryRegistry.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region Imports
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Spring.Collections;
|
||||
using Spring.Util;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Web.Support
|
||||
{
|
||||
public class ResultFactoryRegistry
|
||||
{
|
||||
private static readonly IDictionary s_registeredFactories = new CaseInsensitiveHashtable();
|
||||
private static volatile IResultFactory s_defaultFactory;
|
||||
|
||||
static ResultFactoryRegistry()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
public static void Reset()
|
||||
{
|
||||
s_defaultFactory = null;
|
||||
s_registeredFactories.Clear();
|
||||
|
||||
SetDefaultFactory( new DefaultResultFactory() );
|
||||
|
||||
foreach(string resultMode in Enum.GetNames(typeof(ResultMode)))
|
||||
{
|
||||
RegisterResultMode( resultMode, DefaultResultFactory );
|
||||
}
|
||||
}
|
||||
|
||||
public static IResultFactory DefaultResultFactory
|
||||
{
|
||||
get { return s_defaultFactory; }
|
||||
}
|
||||
|
||||
public static IResultFactory SetDefaultFactory(IResultFactory resultFactory)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(resultFactory, "resultFactory");
|
||||
IResultFactory prevFactory = s_defaultFactory;
|
||||
s_defaultFactory = resultFactory;
|
||||
return prevFactory;
|
||||
}
|
||||
|
||||
public static IResultFactory RegisterResultMode( string resultMode, IResultFactory resultFactory )
|
||||
{
|
||||
lock (s_registeredFactories.SyncRoot)
|
||||
{
|
||||
IResultFactory prevFactory = (IResultFactory) s_registeredFactories[resultMode];
|
||||
s_registeredFactories[resultMode] = resultFactory;
|
||||
return prevFactory;
|
||||
}
|
||||
}
|
||||
|
||||
public static IResult CreateResult( string resultText )
|
||||
{
|
||||
IResultFactory resultFactory = null;
|
||||
string resultMode = null;
|
||||
|
||||
int indexOfResultModeDelimiter = resultText.IndexOf( ':' );
|
||||
if (indexOfResultModeDelimiter > 0)
|
||||
{
|
||||
resultMode = resultText.Substring( 0, indexOfResultModeDelimiter ).Trim();
|
||||
resultFactory = (IResultFactory) s_registeredFactories[resultMode];
|
||||
resultText = resultText.Substring( indexOfResultModeDelimiter + 1 );
|
||||
}
|
||||
|
||||
if (resultFactory == null)
|
||||
{
|
||||
resultFactory = s_defaultFactory;
|
||||
}
|
||||
|
||||
IResult result = resultFactory.CreateResult( resultMode, resultText );
|
||||
AssertUtils.ArgumentNotNull(result, "ResultFactories must not return null results");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
169
src/Spring/Spring.Web/Web/Support/ResultWebNavigator.cs
Normal file
169
src/Spring/Spring.Web/Web/Support/ResultWebNavigator.cs
Normal file
@@ -0,0 +1,169 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region Imports
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Spring.Collections;
|
||||
using Spring.Core;
|
||||
using Spring.Util;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Web.Support
|
||||
{
|
||||
public class ResultWebNavigator : IResultWebNavigator
|
||||
{
|
||||
private IWebNavigator _parentNavigator;
|
||||
private bool _ignoreCase;
|
||||
private IDictionary _results;
|
||||
|
||||
public bool IsCaseSensitive
|
||||
{
|
||||
get { return !_ignoreCase; }
|
||||
}
|
||||
|
||||
public virtual IWebNavigator ParentNavigator
|
||||
{
|
||||
get { return _parentNavigator; }
|
||||
set
|
||||
{
|
||||
if (_parentNavigator != null)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull( _parentNavigator, "Parent", "Navigator already has a parent" );
|
||||
}
|
||||
_parentNavigator = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets map of result names to target URLs
|
||||
/// </summary>
|
||||
public IDictionary Results
|
||||
{
|
||||
get
|
||||
{
|
||||
return _results;
|
||||
}
|
||||
set
|
||||
{
|
||||
_results = CreateResultsDictionary(value);
|
||||
}
|
||||
}
|
||||
|
||||
public ResultWebNavigator()
|
||||
:this(null, null, true)
|
||||
{}
|
||||
|
||||
public ResultWebNavigator( IWebNavigator parent, IDictionary results, bool ignoreCase )
|
||||
{
|
||||
this._parentNavigator = parent;
|
||||
this._ignoreCase = ignoreCase;
|
||||
this._results = CreateResultsDictionary( results );
|
||||
}
|
||||
|
||||
protected virtual IDictionary CreateResultsDictionary( IDictionary initialResults )
|
||||
{
|
||||
IDictionary newResults = (_ignoreCase) ? new CaseInsensitiveHashtable() : new Hashtable();
|
||||
if (initialResults != null)
|
||||
{
|
||||
foreach(DictionaryEntry entry in initialResults)
|
||||
{
|
||||
newResults[entry.Key.ToString()] = entry.Value;
|
||||
}
|
||||
}
|
||||
return newResults;
|
||||
}
|
||||
|
||||
public virtual bool CanNavigateTo( string resultName )
|
||||
{
|
||||
if (_results.Contains( resultName ))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return (ParentNavigator != null) ? ParentNavigator.CanNavigateTo( resultName ) : false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Redirects user to a URL mapped to specified result name.
|
||||
/// </summary>
|
||||
/// <param name="resultName">Name of the result.</param>
|
||||
/// <param name="context">The context to use for evaluating the SpEL expression in the Result.</param>
|
||||
public virtual void NavigateTo( string resultName, object context )
|
||||
{
|
||||
IResult result = GetResult( resultName );
|
||||
if (result == null)
|
||||
{
|
||||
if (ParentNavigator != null)
|
||||
{
|
||||
ParentNavigator.NavigateTo( resultName, context );
|
||||
return;
|
||||
}
|
||||
throw new ArgumentException( string.Format( "No result mapping found for the specified name '{0}'.", resultName ), "resultName" );
|
||||
}
|
||||
result.Navigate( context );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a redirect url string that points to the
|
||||
/// <see cref="Spring.Web.Support.Result.TargetPage"/> defined by this
|
||||
/// result evaluated using this Page for expression
|
||||
/// </summary>
|
||||
/// <param name="resultName">Name of the result.</param>
|
||||
/// <param name="context">The context to use for evaluating the SpEL expression in the Result</param>
|
||||
/// <returns>A redirect url string.</returns>
|
||||
public virtual string GetResultUri( string resultName, object context )
|
||||
{
|
||||
IResult result = GetResult( resultName );
|
||||
if (result == null)
|
||||
{
|
||||
if (ParentNavigator != null)
|
||||
{
|
||||
return result.GetRedirectUri( context );
|
||||
}
|
||||
throw new ArgumentException( string.Format( "No result mapping found for the specified name '{0}'.", resultName ), "resultName" );
|
||||
}
|
||||
return result.GetRedirectUri( context );
|
||||
}
|
||||
|
||||
protected IResult GetResult( string name )
|
||||
{
|
||||
object val = _results[name];
|
||||
if (val == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (val is IResult)
|
||||
{
|
||||
return (IResult)val;
|
||||
}
|
||||
else if (val is String)
|
||||
{
|
||||
return ResultFactoryRegistry.CreateResult( (string)val );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new TypeMismatchException(
|
||||
"Unable to create result object. Please use either String or Result instances to define results." );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region Imports
|
||||
|
||||
using System.Collections;
|
||||
using System.Web.UI;
|
||||
using Spring.Util;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Web.Support
|
||||
{
|
||||
/// <summary>
|
||||
/// An implementation of <see cref="IHierarchicalWebNavigator"/> specific for <see cref="Control"/>s.
|
||||
/// The navigator hierarchy equals the control hierarchy when using a <see cref="WebFormsResultWebNavigator"/>.
|
||||
/// </summary>
|
||||
public class WebFormsResultWebNavigator : ResultWebNavigator
|
||||
{
|
||||
/// <summary>
|
||||
/// Finds the next <see cref="IWebNavigator"/> up the control hierarchy,
|
||||
/// starting at the specified <paramref name="control"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method checks both, for controls implementing <see cref="IWebNavigator"/> or <see cref="IWebNavigable"/>. In addition
|
||||
/// when MasterPages are used, it interprets the control hierarchy as control->page->masterpage.
|
||||
/// </remarks>
|
||||
/// <param name="control">the control to start the search with.</param>
|
||||
/// <param name="includeSelf">include checking the control itself or start search with its parent.</param>
|
||||
/// <returns>If found, the next <see cref="IWebNavigator"/> up the hierarchy. <c>null</c> otherwise</returns>
|
||||
public static IWebNavigator FindWebNavigator( Control control, bool includeSelf )
|
||||
{
|
||||
while (control != null)
|
||||
{
|
||||
if (!includeSelf)
|
||||
{
|
||||
// Get next parent in hierarchy
|
||||
control = WebUtils.GetLogicalParent( control );
|
||||
}
|
||||
includeSelf = false;
|
||||
|
||||
if (control is IWebNavigable || control is IWebNavigator)
|
||||
{
|
||||
return (control is IWebNavigable) ? ((IWebNavigable)control).WebNavigator : (IWebNavigator)control;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Control _owner;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of a <see cref="IHierarchicalWebNavigator"/> for the specified control.
|
||||
/// </summary>
|
||||
/// <param name="owner">the control to be associated with this navigator.</param>
|
||||
/// <param name="results">a dictionary containing results</param>
|
||||
/// <param name="ignoreCase">determines, whether to interpret result names case-sensitive or not.</param>
|
||||
public WebFormsResultWebNavigator( Control owner, IDictionary results, bool ignoreCase )
|
||||
: base( null, results, ignoreCase )
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(owner, "owner");
|
||||
_owner = owner;
|
||||
}
|
||||
|
||||
public override IWebNavigator ParentNavigator
|
||||
{
|
||||
get
|
||||
{
|
||||
if (base.ParentNavigator == null)
|
||||
{
|
||||
base.ParentNavigator = FindWebNavigator(_owner, false);
|
||||
}
|
||||
return base.ParentNavigator;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new System.NotSupportedException("cannot set parent navigator on a WebFormsResultWebNavigator");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -280,6 +280,7 @@ namespace Spring.Web.UI.Controls
|
||||
attributeCollection.Remove(ATTR_BINDINGTARGET);
|
||||
attributeCollection.Remove(ATTR_BINDINGSOURCE);
|
||||
attributeCollection.Remove(ATTR_BINDINGTYPE);
|
||||
attributeCollection.Remove(ATTR_BINDINGDIRECTION);
|
||||
attributeCollection.Remove(ATTR_BINDINGFORMATTER);
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,11 @@ namespace Spring.Web.UI.Controls
|
||||
/// <remarks>
|
||||
/// The url specified here is only rendered, if <see cref="SuppressAction"/> is true.
|
||||
/// </remarks>
|
||||
#if !NET_2_0
|
||||
public string Action
|
||||
#else
|
||||
public new string Action
|
||||
#endif
|
||||
{
|
||||
get { return this.action; }
|
||||
set { this.action = value; }
|
||||
|
||||
@@ -88,6 +88,13 @@ namespace Spring.Web.UI.Controls
|
||||
|
||||
private bool _suppressDependencyInjection;
|
||||
private bool _renderContainerTag;
|
||||
private string _visibleConditionExpression;
|
||||
|
||||
public string VisibleIf
|
||||
{
|
||||
get { return _visibleConditionExpression; }
|
||||
set { _visibleConditionExpression = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This flag controls, whether DI on child controls will be done or not
|
||||
@@ -114,6 +121,12 @@ namespace Spring.Web.UI.Controls
|
||||
/// <param name="writer"></param>
|
||||
protected override void Render(HtmlTextWriter writer)
|
||||
{
|
||||
bool visible = (_visibleConditionExpression != null)
|
||||
? Spring.Expressions.ExpressionEvaluator.GetValue(this, _visibleConditionExpression).Equals(true)
|
||||
: this.Visible;
|
||||
|
||||
if (!visible) return;
|
||||
|
||||
if (_renderContainerTag)
|
||||
{
|
||||
base.Render(writer);
|
||||
|
||||
@@ -24,6 +24,7 @@ using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Web.UI;
|
||||
using Spring.Collections;
|
||||
using Spring.Validation;
|
||||
using Spring.Web.UI.Controls;
|
||||
using IValidator = Spring.Validation.IValidator;
|
||||
@@ -100,13 +101,12 @@ namespace Spring.Web.UI
|
||||
#else
|
||||
|
||||
#region ASP.NET 2.0 Spring Master Page Implementation
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Spring.NET Master Page implementation for ASP.NET 2.0
|
||||
/// </summary>
|
||||
/// <author>Aleksandar Seovic</author>
|
||||
public class MasterPage : System.Web.UI.MasterPage, IApplicationContextAware, ISupportsWebDependencyInjection
|
||||
public class MasterPage : System.Web.UI.MasterPage, IApplicationContextAware, ISupportsWebDependencyInjection, IWebNavigable
|
||||
{
|
||||
#region Instance Fields
|
||||
|
||||
@@ -115,11 +115,21 @@ namespace Spring.Web.UI
|
||||
private IMessageSource messageSource;
|
||||
private IApplicationContext applicationContext;
|
||||
private IApplicationContext defaultApplicationContext;
|
||||
private IWebNavigator webNavigator;
|
||||
private IDictionary args;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Control lifecycle methods
|
||||
#region Lifecycle methods
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new MasterPage instance.
|
||||
/// </summary>
|
||||
public MasterPage()
|
||||
{
|
||||
InitializeNavigationSupport();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes user control.
|
||||
/// </summary>
|
||||
@@ -416,6 +426,148 @@ namespace Spring.Web.UI
|
||||
|
||||
#endregion
|
||||
|
||||
#region Result support
|
||||
|
||||
/// <summary>
|
||||
/// Ensure, that <see cref="WebNavigator"/> is set to a valid instance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If <see cref="WebNavigator"/> is not already set, creates and sets a new <see cref="WebFormsResultWebNavigator"/> instance.<br/>
|
||||
/// Override this method if you don't want to inject a navigator, but need a different default.
|
||||
/// </remarks>
|
||||
protected virtual void InitializeNavigationSupport()
|
||||
{
|
||||
webNavigator = new WebFormsResultWebNavigator(this, null, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets the navigator to be used for handling <see cref="SetResult(string, object)"/> calls.
|
||||
/// </summary>
|
||||
public IWebNavigator WebNavigator
|
||||
{
|
||||
get
|
||||
{
|
||||
return webNavigator;
|
||||
}
|
||||
set
|
||||
{
|
||||
webNavigator = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets map of result names to target URLs
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Using <see cref="Results"/> requires <see cref="WebNavigator"/> to implement <see cref="IResultWebNavigator"/>.
|
||||
/// </remarks>
|
||||
[Browsable( false )]
|
||||
[DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
|
||||
public virtual IDictionary Results
|
||||
{
|
||||
get
|
||||
{
|
||||
if (WebNavigator is IResultWebNavigator)
|
||||
{
|
||||
return ((IResultWebNavigator)WebNavigator).Results;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WebNavigator is IResultWebNavigator)
|
||||
{
|
||||
((IResultWebNavigator)WebNavigator).Results = value;
|
||||
return;
|
||||
}
|
||||
throw new NotSupportedException("WebNavigator must be of type IResultWebNavigator to support Results");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A convenience, case-insensitive table that may be used to e.g. pass data into SpEL expressions"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// By default, e.g. <see cref="SetResult(string)"/> passes the control instance into an expression. Using
|
||||
/// <see cref="Args"/> is an easy way to pass additional parameters into the expression
|
||||
/// <example>
|
||||
/// // config:
|
||||
///
|
||||
/// <property Name="Results">
|
||||
/// <dictionary>
|
||||
/// <entry key="ok_clicked" value="redirect:~/ShowResult.aspx?result=%{Args['result']}" />
|
||||
/// </dictionary>
|
||||
/// </property>
|
||||
///
|
||||
/// // code:
|
||||
///
|
||||
/// void OnOkClicked(object sender, EventArgs e)
|
||||
/// {
|
||||
/// Args["result"] = txtUserInput.Text;
|
||||
/// SetResult("ok_clicked");
|
||||
/// }
|
||||
/// </example>
|
||||
/// </remarks>
|
||||
public IDictionary Args
|
||||
{
|
||||
get
|
||||
{
|
||||
if (args == null)
|
||||
{
|
||||
args = new CaseInsensitiveHashtable();
|
||||
}
|
||||
return args;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Redirects user to a URL mapped to specified result name.
|
||||
/// </summary>
|
||||
/// <param name="resultName">Result name.</param>
|
||||
protected void SetResult( string resultName )
|
||||
{
|
||||
WebNavigator.NavigateTo( resultName, this );
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Redirects user to a URL mapped to specified result name.
|
||||
/// </summary>
|
||||
/// <param name="resultName">Name of the result.</param>
|
||||
/// <param name="context">The context to use for evaluating the SpEL expression in the Result.</param>
|
||||
protected void SetResult( string resultName, object context )
|
||||
{
|
||||
WebNavigator.NavigateTo( resultName, context );
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a redirect url string that points to the
|
||||
/// <see cref="Spring.Web.Support.Result.TargetPage"/> defined by this
|
||||
/// result evaluated using this Page for expression
|
||||
/// </summary>
|
||||
/// <param name="resultName">Name of the result.</param>
|
||||
/// <returns>A redirect url string.</returns>
|
||||
protected string GetResultUrl( string resultName )
|
||||
{
|
||||
return ResolveUrl( WebNavigator.GetResultUri( resultName, this ) );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a redirect url string that points to the
|
||||
/// <see cref="Spring.Web.Support.Result.TargetPage"/> defined by this
|
||||
/// result evaluated using this Page for expression
|
||||
/// </summary>
|
||||
/// <param name="resultName">Name of the result.</param>
|
||||
/// <param name="context">The context to use for evaluating the SpEL expression in the Result</param>
|
||||
/// <returns>A redirect url string.</returns>
|
||||
protected string GetResultUrl( string resultName, object context )
|
||||
{
|
||||
return ResolveUrl( WebNavigator.GetResultUri( resultName, context ) );
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Validation support
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright 2002-2004 the original author or authors.
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,9 +31,9 @@ using System.Security.Permissions;
|
||||
using System.Threading;
|
||||
using System.Web;
|
||||
using System.Web.UI;
|
||||
using Spring.Collections;
|
||||
using Spring.Context;
|
||||
using Spring.Context.Support;
|
||||
using Spring.Core;
|
||||
using Spring.DataBinding;
|
||||
using Spring.Globalization;
|
||||
using Spring.Globalization.Resolvers;
|
||||
@@ -50,6 +50,10 @@ using IValidator = Spring.Validation.IValidator;
|
||||
|
||||
namespace Spring.Web.UI
|
||||
{
|
||||
#region Result support
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Represents an .aspx file, also known as a Web Forms page, requested from a
|
||||
/// server that hosts an ASP.NET Web application.
|
||||
@@ -73,7 +77,7 @@ namespace Spring.Web.UI
|
||||
[AspNetHostingPermission( SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal )]
|
||||
[AspNetHostingPermission( SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal )]
|
||||
public class Page : System.Web.UI.Page, IHttpHandler, IApplicationContextAware, ISharedStateAware,
|
||||
ISupportsWebDependencyInjection, IWebDataBound, IValidationContainer
|
||||
ISupportsWebDependencyInjection, IWebDataBound, IValidationContainer, IWebNavigable
|
||||
{
|
||||
#region Constants
|
||||
|
||||
@@ -108,15 +112,15 @@ namespace Spring.Web.UI
|
||||
private String masterPageFile;
|
||||
#endif
|
||||
private object controller;
|
||||
private IDictionary sharedState;
|
||||
private IDictionary sharedState = new CaseInsensitiveHashtable();
|
||||
|
||||
private ILocalizer localizer;
|
||||
private ICultureResolver cultureResolver = new DefaultWebCultureResolver();
|
||||
private IMessageSource messageSource;
|
||||
private IBindingContainer bindingManager;
|
||||
private IValidationErrors validationErrors = new ValidationErrors();
|
||||
|
||||
private IDictionary results;
|
||||
private IWebNavigator webNavigator;
|
||||
private IDictionary args;
|
||||
private IApplicationContext applicationContext;
|
||||
private IApplicationContext defaultApplicationContext;
|
||||
private static readonly string traceCategory = "Spring.Page";
|
||||
@@ -132,6 +136,11 @@ namespace Spring.Web.UI
|
||||
|
||||
#region Page lifecycle methods
|
||||
|
||||
public Page()
|
||||
{
|
||||
InitializeNavigationSupport();
|
||||
}
|
||||
|
||||
#if !NET_2_0
|
||||
/// <summary>
|
||||
/// Determines the type of request made for the Page class.
|
||||
@@ -1027,39 +1036,97 @@ namespace Spring.Web.UI
|
||||
#region Result support
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets map of result names to target URLs
|
||||
/// Ensure, that <see cref="WebNavigator"/> is set to a valid instance.
|
||||
/// </summary>
|
||||
[Browsable( false )]
|
||||
[DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
|
||||
public IDictionary Results
|
||||
/// <remarks>
|
||||
/// If <see cref="WebNavigator"/> is not already set, creates and sets a new <see cref="WebFormsResultWebNavigator"/> instance.<br/>
|
||||
/// Override this method if you don't want to inject a navigator, but need a different default.
|
||||
/// </remarks>
|
||||
protected virtual void InitializeNavigationSupport()
|
||||
{
|
||||
webNavigator = new WebFormsResultWebNavigator( this, null, true );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets the navigator to be used for handling <see cref="SetResult(string, object)"/> calls.
|
||||
/// </summary>
|
||||
public virtual IWebNavigator WebNavigator
|
||||
{
|
||||
get
|
||||
{
|
||||
if (results == null)
|
||||
{
|
||||
results = new Hashtable();
|
||||
}
|
||||
return results;
|
||||
return webNavigator;
|
||||
}
|
||||
set
|
||||
{
|
||||
results = new Hashtable();
|
||||
foreach (DictionaryEntry entry in value)
|
||||
webNavigator = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets map of result names to target URLs
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Using <see cref="Results"/> requires <see cref="WebNavigator"/> to implement <see cref="IResultWebNavigator"/>.
|
||||
/// </remarks>
|
||||
[Browsable( false )]
|
||||
[DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
|
||||
public virtual IDictionary Results
|
||||
{
|
||||
get
|
||||
{
|
||||
if (WebNavigator is IResultWebNavigator)
|
||||
{
|
||||
if (entry.Value is Result)
|
||||
{
|
||||
results[entry.Key] = entry.Value;
|
||||
}
|
||||
else if (entry.Value is String)
|
||||
{
|
||||
results[entry.Key] = new Result( (string)entry.Value );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new TypeMismatchException(
|
||||
"Unable to create result object. Please use either String or Result instances to define results." );
|
||||
}
|
||||
return ((IResultWebNavigator)WebNavigator).Results;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WebNavigator is IResultWebNavigator)
|
||||
{
|
||||
((IResultWebNavigator)WebNavigator).Results = value;
|
||||
return;
|
||||
}
|
||||
throw new NotSupportedException( "WebNavigator must be of type IResultWebNavigator to support Results" );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A convenience, case-insensitive table that may be used to e.g. pass data into SpEL expressions"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// By default, e.g. <see cref="SetResult(string)"/> passes the control instance into an expression. Using
|
||||
/// <see cref="Args"/> is an easy way to pass additional parameters into the expression
|
||||
/// <example>
|
||||
/// This example shows how to pass an arbitrary value 'age' into a result expression.
|
||||
/// <code>
|
||||
/// // config:
|
||||
///
|
||||
/// <property Name="Results">
|
||||
/// <dictionary>
|
||||
/// <entry key="ok_clicked" value="redirect:~/ShowResult.aspx?age=%{Args['age']}" />
|
||||
/// </dictionary>
|
||||
/// </property>
|
||||
///
|
||||
/// // code:
|
||||
///
|
||||
/// void OnOkClicked(object sender, EventArgs e)
|
||||
/// {
|
||||
/// Args["result"] = txtAge.Text;
|
||||
/// SetResult("ok_clicked");
|
||||
/// }
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// </remarks>
|
||||
public IDictionary Args
|
||||
{
|
||||
get
|
||||
{
|
||||
if (args == null)
|
||||
{
|
||||
args = new CaseInsensitiveHashtable();
|
||||
}
|
||||
return args;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1067,23 +1134,21 @@ namespace Spring.Web.UI
|
||||
/// Redirects user to a URL mapped to specified result name.
|
||||
/// </summary>
|
||||
/// <param name="resultName">Result name.</param>
|
||||
protected internal void SetResult( string resultName )
|
||||
protected void SetResult( string resultName )
|
||||
{
|
||||
GetResult( resultName ).Navigate( this );
|
||||
WebNavigator.NavigateTo( resultName, this );
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Redirects user to a URL mapped to specified result name.
|
||||
/// </summary>
|
||||
/// <param name="resultName">Name of the result.</param>
|
||||
/// <param name="context">The context to use for evaluating the SpEL expression in the Result.</param>
|
||||
protected internal void SetResult( string resultName, object context )
|
||||
protected void SetResult( string resultName, object context )
|
||||
{
|
||||
GetResult( resultName ).Navigate( context );
|
||||
WebNavigator.NavigateTo( resultName, context );
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a redirect url string that points to the
|
||||
/// <see cref="Spring.Web.Support.Result.TargetPage"/> defined by this
|
||||
@@ -1091,10 +1156,9 @@ namespace Spring.Web.UI
|
||||
/// </summary>
|
||||
/// <param name="resultName">Name of the result.</param>
|
||||
/// <returns>A redirect url string.</returns>
|
||||
protected internal string GetResultUrl( string resultName )
|
||||
protected string GetResultUrl( string resultName )
|
||||
{
|
||||
Result result = GetResult( resultName );
|
||||
return ResolveUrl( result.GetRedirectUri( this ) );
|
||||
return ResolveUrl( WebNavigator.GetResultUri( resultName, this ) );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1105,26 +1169,11 @@ namespace Spring.Web.UI
|
||||
/// <param name="resultName">Name of the result.</param>
|
||||
/// <param name="context">The context to use for evaluating the SpEL expression in the Result</param>
|
||||
/// <returns>A redirect url string.</returns>
|
||||
protected internal string GetResultUrl( string resultName, object context )
|
||||
protected string GetResultUrl( string resultName, object context )
|
||||
{
|
||||
Result result = GetResult( resultName );
|
||||
return ResolveUrl( result.GetRedirectUri( context ) );
|
||||
return ResolveUrl( WebNavigator.GetResultUri( resultName, context ) );
|
||||
}
|
||||
|
||||
|
||||
private Result GetResult( string resultName )
|
||||
{
|
||||
Result result = (Result)Results[resultName];
|
||||
if (result == null)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
string.Format( "No URL mapping found for the specified result '{0}'.", resultName ), "resultName" );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Validation support
|
||||
|
||||
@@ -38,6 +38,7 @@ using Spring.Context.Support;
|
||||
using Spring.Core;
|
||||
using Spring.DataBinding;
|
||||
using Spring.Globalization;
|
||||
using Spring.Util;
|
||||
using Spring.Validation;
|
||||
using Spring.Web.Support;
|
||||
using IValidator = Spring.Validation.IValidator;
|
||||
@@ -51,7 +52,7 @@ namespace Spring.Web.UI
|
||||
/// </summary>
|
||||
/// <author>Aleksandar Seovic</author>
|
||||
public class UserControl : System.Web.UI.UserControl, IApplicationContextAware, IWebDataBound, ISupportsWebDependencyInjection,
|
||||
IPostBackDataHandler,IValidationContainer
|
||||
IPostBackDataHandler, IValidationContainer, IWebNavigable
|
||||
{
|
||||
#region Static fields
|
||||
|
||||
@@ -67,10 +68,11 @@ namespace Spring.Web.UI
|
||||
private object controller;
|
||||
private ILocalizer localizer;
|
||||
private IMessageSource messageSource;
|
||||
private IDictionary sharedState;
|
||||
private IDictionary sharedState = new CaseInsensitiveHashtable();
|
||||
private IBindingContainer bindingManager;
|
||||
private IValidationErrors validationErrors = new ValidationErrors();
|
||||
private IDictionary results;
|
||||
private IWebNavigator webNavigator;
|
||||
private IDictionary args;
|
||||
private IApplicationContext applicationContext;
|
||||
private IApplicationContext defaultApplicationContext;
|
||||
private bool needsUnbind = false;
|
||||
@@ -79,6 +81,14 @@ namespace Spring.Web.UI
|
||||
|
||||
#region Control lifecycle methods
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new UserControl instance.
|
||||
/// </summary>
|
||||
public UserControl()
|
||||
{
|
||||
InitializeNavigationSupport();
|
||||
}
|
||||
|
||||
#if !NET_2_0
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is in design mode.
|
||||
@@ -113,7 +123,7 @@ namespace Spring.Web.UI
|
||||
/// <summary>
|
||||
/// Initializes user control.
|
||||
/// </summary>
|
||||
protected override void OnInit(EventArgs e)
|
||||
protected override void OnInit( EventArgs e )
|
||||
{
|
||||
InitializeMessageSource();
|
||||
InitializeBindingManager();
|
||||
@@ -124,23 +134,23 @@ namespace Spring.Web.UI
|
||||
}
|
||||
else
|
||||
{
|
||||
LoadModel(LoadModelFromPersistenceMedium());
|
||||
LoadModel( LoadModelFromPersistenceMedium() );
|
||||
}
|
||||
|
||||
base.OnInit(e);
|
||||
base.OnInit( e );
|
||||
|
||||
OnInitializeControls(EventArgs.Empty);
|
||||
OnInitializeControls( EventArgs.Empty );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raises the <see cref="PreLoadViewState"/> event after page initialization.
|
||||
/// </summary>
|
||||
protected internal virtual void OnPreLoadViewState(EventArgs e)
|
||||
protected internal virtual void OnPreLoadViewState( EventArgs e )
|
||||
{
|
||||
EventHandler handler = (EventHandler) base.Events[EventPreLoadViewState];
|
||||
EventHandler handler = (EventHandler)base.Events[EventPreLoadViewState];
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, e);
|
||||
handler( this, e );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,8 +168,8 @@ namespace Spring.Web.UI
|
||||
/// </remarks>
|
||||
public event EventHandler PreLoadViewState
|
||||
{
|
||||
add { base.Events.AddHandler(EventPreLoadViewState, value); }
|
||||
remove { base.Events.RemoveHandler(EventPreLoadViewState, value); }
|
||||
add { base.Events.AddHandler( EventPreLoadViewState, value ); }
|
||||
remove { base.Events.RemoveHandler( EventPreLoadViewState, value ); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -170,16 +180,16 @@ namespace Spring.Web.UI
|
||||
/// has been called during <see cref="OnPreRender"/>
|
||||
/// </remarks>
|
||||
/// <returns>true if the server control's state changes as a result of the post back; otherwise false.</returns>
|
||||
bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection postCollection)
|
||||
bool IPostBackDataHandler.LoadPostData( string postDataKey, NameValueCollection postCollection )
|
||||
{
|
||||
return LoadPostData(postDataKey, postCollection);
|
||||
return LoadPostData( postDataKey, postCollection );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is called during a postback if this control has been visible when being rendered to the client.
|
||||
/// </summary>
|
||||
/// <returns>true if the server control's state changes as a result of the post back; otherwise false.</returns>
|
||||
protected virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection)
|
||||
protected virtual bool LoadPostData( string postDataKey, NameValueCollection postCollection )
|
||||
{
|
||||
// mark this control for unbinding form data during OnLoad()
|
||||
this.needsUnbind = true;
|
||||
@@ -210,14 +220,14 @@ namespace Spring.Web.UI
|
||||
/// then raises Load event in order to execute all associated handlers.
|
||||
/// </summary>
|
||||
/// <param name="e">Event arguments.</param>
|
||||
protected override void OnLoad(EventArgs e)
|
||||
protected override void OnLoad( EventArgs e )
|
||||
{
|
||||
if (IsPostBack && needsUnbind)
|
||||
{
|
||||
// unbind form data
|
||||
UnbindFormData();
|
||||
}
|
||||
base.OnLoad(e);
|
||||
base.OnLoad( e );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -225,32 +235,32 @@ namespace Spring.Web.UI
|
||||
/// PreRender event afterwards.
|
||||
/// </summary>
|
||||
/// <param name="e">Event arguments.</param>
|
||||
protected override void OnPreRender(EventArgs e)
|
||||
protected override void OnPreRender( EventArgs e )
|
||||
{
|
||||
if (Visible)
|
||||
{
|
||||
// causes IPostBackDataHandler.LoadPostData() to be called on next postback.
|
||||
// this is used for indicating a required call to UnbindFormData()
|
||||
Page.RegisterRequiresPostBack(this);
|
||||
Page.RegisterRequiresPostBack( this );
|
||||
|
||||
BindFormData();
|
||||
|
||||
if (localizer != null)
|
||||
{
|
||||
localizer.ApplyResources(this, messageSource, UserCulture);
|
||||
localizer.ApplyResources( this, messageSource, UserCulture );
|
||||
}
|
||||
else if (Page.Localizer != null)
|
||||
{
|
||||
Page.Localizer.ApplyResources(this, messageSource, UserCulture);
|
||||
Page.Localizer.ApplyResources( this, messageSource, UserCulture );
|
||||
}
|
||||
}
|
||||
|
||||
base.OnPreRender(e);
|
||||
base.OnPreRender( e );
|
||||
|
||||
object modelToSave = SaveModel();
|
||||
if (modelToSave != null)
|
||||
{
|
||||
SaveModelToPersistenceMedium(modelToSave);
|
||||
SaveModelToPersistenceMedium( modelToSave );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,11 +274,11 @@ namespace Spring.Web.UI
|
||||
/// Raises InitializeControls event.
|
||||
/// </summary>
|
||||
/// <param name="e">Event arguments.</param>
|
||||
protected virtual void OnInitializeControls(EventArgs e)
|
||||
protected virtual void OnInitializeControls( EventArgs e )
|
||||
{
|
||||
if (InitializeControls != null)
|
||||
{
|
||||
InitializeControls(this, e);
|
||||
InitializeControls( this, e );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,10 +290,10 @@ namespace Spring.Web.UI
|
||||
/// <returns>
|
||||
/// Returns the specified <see langword="UserControl"/> object, with dependencies injected.
|
||||
/// </returns>
|
||||
protected virtual new Control LoadControl(string virtualPath)
|
||||
protected virtual new Control LoadControl( string virtualPath )
|
||||
{
|
||||
Control control = base.LoadControl(virtualPath);
|
||||
control = WebDependencyInjectionUtils.InjectDependenciesRecursive(defaultApplicationContext, control);
|
||||
Control control = base.LoadControl( virtualPath );
|
||||
control = WebDependencyInjectionUtils.InjectDependenciesRecursive( defaultApplicationContext, control );
|
||||
return control;
|
||||
}
|
||||
|
||||
@@ -297,10 +307,10 @@ namespace Spring.Web.UI
|
||||
/// <returns>
|
||||
/// Returns the specified <see langword="UserControl"/> object, with dependencies injected.
|
||||
/// </returns>
|
||||
protected virtual new Control LoadControl( Type t, params object[] parameters)
|
||||
protected virtual new Control LoadControl( Type t, params object[] parameters )
|
||||
{
|
||||
Control control = base.LoadControl( t, parameters );
|
||||
control = WebDependencyInjectionUtils.InjectDependenciesRecursive(defaultApplicationContext, control);
|
||||
control = WebDependencyInjectionUtils.InjectDependenciesRecursive( defaultApplicationContext, control );
|
||||
return control;
|
||||
}
|
||||
#endif
|
||||
@@ -339,7 +349,7 @@ namespace Spring.Web.UI
|
||||
/// The default implementation uses <see cref="System.Web.UI.Page.Session"/> to store and retrieve
|
||||
/// the model for the current <see cref="System.Web.HttpRequest.CurrentExecutionFilePath" />
|
||||
/// </remarks>
|
||||
protected virtual void SaveModelToPersistenceMedium(object modelToSave)
|
||||
protected virtual void SaveModelToPersistenceMedium( object modelToSave )
|
||||
{
|
||||
Session[Request.CurrentExecutionFilePath + this.UniqueID + ".Model"] = modelToSave;
|
||||
}
|
||||
@@ -351,7 +361,7 @@ namespace Spring.Web.UI
|
||||
/// This method should be overriden by the developer
|
||||
/// in order to load data model for the page.
|
||||
/// </remarks>
|
||||
protected virtual void LoadModel(object savedModel)
|
||||
protected virtual void LoadModel( object savedModel )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -386,7 +396,7 @@ namespace Spring.Web.UI
|
||||
public object Controller
|
||||
{
|
||||
get { return GetController(); }
|
||||
set { SetController(value); }
|
||||
set { SetController( value ); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -397,7 +407,7 @@ namespace Spring.Web.UI
|
||||
/// but must ensure to also change the behaviour of <see cref="GetController"/> accordingly.
|
||||
/// </remarks>
|
||||
/// <param name="controller">Controller for the control.</param>
|
||||
protected virtual void SetController(object controller)
|
||||
protected virtual void SetController( object controller )
|
||||
{
|
||||
this.controller = controller;
|
||||
}
|
||||
@@ -425,7 +435,7 @@ namespace Spring.Web.UI
|
||||
/// </returns>
|
||||
protected virtual object GetController()
|
||||
{
|
||||
if(controller == null)
|
||||
if (controller == null)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
@@ -440,8 +450,8 @@ namespace Spring.Web.UI
|
||||
/// Returns a thread-safe dictionary that contains state that is shared by
|
||||
/// all instances of this control.
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable( false )]
|
||||
[DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
|
||||
protected IDictionary SharedState
|
||||
{
|
||||
get
|
||||
@@ -451,7 +461,7 @@ namespace Spring.Web.UI
|
||||
string thisTypeKey = this.GetType().FullName + this.GetType().GetHashCode() + ".SharedState";
|
||||
|
||||
sharedState = Application[thisTypeKey] as IDictionary;
|
||||
if (sharedState==null)
|
||||
if (sharedState == null)
|
||||
{
|
||||
Application.Lock();
|
||||
try
|
||||
@@ -460,7 +470,7 @@ namespace Spring.Web.UI
|
||||
if (sharedState == null)
|
||||
{
|
||||
sharedState = new SynchronizedHashtable();
|
||||
Application.Add(thisTypeKey, sharedState);
|
||||
Application.Add( thisTypeKey, sharedState );
|
||||
}
|
||||
}
|
||||
finally
|
||||
@@ -478,103 +488,141 @@ namespace Spring.Web.UI
|
||||
#region Result support
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets map of result names to target URLs
|
||||
/// Ensure, that <see cref="WebNavigator"/> is set to a valid instance.
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public IDictionary Results
|
||||
/// <remarks>
|
||||
/// If <see cref="WebNavigator"/> is not already set, creates and sets a new <see cref="WebFormsResultWebNavigator"/> instance.<br/>
|
||||
/// Override this method if you don't want to inject a navigator, but need a different default.
|
||||
/// </remarks>
|
||||
protected virtual void InitializeNavigationSupport()
|
||||
{
|
||||
webNavigator = new WebFormsResultWebNavigator(this, null, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets the navigator to be used for handling <see cref="SetResult(string, object)"/> calls.
|
||||
/// </summary>
|
||||
public IWebNavigator WebNavigator
|
||||
{
|
||||
get
|
||||
{
|
||||
if (results == null)
|
||||
{
|
||||
results = new Hashtable();
|
||||
}
|
||||
return results;
|
||||
return webNavigator;
|
||||
}
|
||||
set
|
||||
{
|
||||
results = new Hashtable();
|
||||
foreach (DictionaryEntry entry in value)
|
||||
{
|
||||
if (entry.Value is Result)
|
||||
{
|
||||
results[entry.Key] = entry.Value;
|
||||
}
|
||||
else if (entry.Value is String)
|
||||
{
|
||||
results[entry.Key] = new Result((string)entry.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new TypeMismatchException(
|
||||
"Unable to create result object. Please use either String or Result instances to define results.");
|
||||
}
|
||||
}
|
||||
webNavigator = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Redirects user to a URL mapped to specified result name.
|
||||
/// Gets or sets map of result names to target URLs
|
||||
/// </summary>
|
||||
/// <param name="resultName">Result name.</param>
|
||||
protected void SetResult(string resultName)
|
||||
/// <remarks>
|
||||
/// Using <see cref="Results"/> requires <see cref="WebNavigator"/> to implement <see cref="IResultWebNavigator"/>.
|
||||
/// </remarks>
|
||||
[Browsable( false )]
|
||||
[DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
|
||||
public virtual IDictionary Results
|
||||
{
|
||||
Result result = (Result)Results[resultName];
|
||||
if (result == null)
|
||||
get
|
||||
{
|
||||
// bubble up result in the hierarchy
|
||||
Control parent = this.Parent;
|
||||
while(parent != null)
|
||||
if (WebNavigator is IResultWebNavigator)
|
||||
{
|
||||
if (parent is UserControl)
|
||||
{
|
||||
((UserControl)parent).SetResult(resultName);
|
||||
return;
|
||||
}
|
||||
else if (parent is Page)
|
||||
{
|
||||
((Page) parent).SetResult(resultName);
|
||||
return;
|
||||
}
|
||||
parent = parent.Parent;
|
||||
return ((IResultWebNavigator)WebNavigator).Results;
|
||||
}
|
||||
throw new ArgumentException(string.Format("No URL mapping found for the specified result '{0}'.", resultName), "resultName");
|
||||
return null;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WebNavigator is IResultWebNavigator)
|
||||
{
|
||||
((IResultWebNavigator)WebNavigator).Results = value;
|
||||
return;
|
||||
}
|
||||
throw new NotSupportedException("WebNavigator must be of type IResultWebNavigator to support Results");
|
||||
}
|
||||
}
|
||||
|
||||
result.Navigate(this);
|
||||
/// <summary>
|
||||
/// A convenience, case-insensitive table that may be used to e.g. pass data into SpEL expressions"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// By default, e.g. <see cref="SetResult(string)"/> passes the control instance into an expression. Using
|
||||
/// <see cref="Args"/> is an easy way to pass additional parameters into the expression
|
||||
/// <example>
|
||||
/// // config:
|
||||
///
|
||||
/// <property Name="Results">
|
||||
/// <dictionary>
|
||||
/// <entry key="ok_clicked" value="redirect:~/ShowResult.aspx?result=%{Args['result']}" />
|
||||
/// </dictionary>
|
||||
/// </property>
|
||||
///
|
||||
/// // code:
|
||||
///
|
||||
/// void OnOkClicked(object sender, EventArgs e)
|
||||
/// {
|
||||
/// Args["result"] = txtUserInput.Text;
|
||||
/// SetResult("ok_clicked");
|
||||
/// }
|
||||
/// </example>
|
||||
/// </remarks>
|
||||
public IDictionary Args
|
||||
{
|
||||
get
|
||||
{
|
||||
if (args == null)
|
||||
{
|
||||
args = new CaseInsensitiveHashtable();
|
||||
}
|
||||
return args;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Redirects user to a URL mapped to specified result name.
|
||||
/// </summary>
|
||||
/// <param name="resultName">Result name.</param>
|
||||
protected void SetResult( string resultName )
|
||||
{
|
||||
WebNavigator.NavigateTo( resultName, this );
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Redirects user to a URL mapped to specified result name.
|
||||
/// </summary>
|
||||
/// <param name="resultName">Name of the result.</param>
|
||||
/// <param name="context">The context to use for evaluating the SpEL expression in the Result.</param>
|
||||
protected void SetResult(string resultName, object context)
|
||||
protected void SetResult( string resultName, object context )
|
||||
{
|
||||
Result result = (Result)Results[resultName];
|
||||
if (result == null)
|
||||
{
|
||||
// bubble up result in the hierarchy
|
||||
Control parent = this.Parent;
|
||||
while (parent != null)
|
||||
{
|
||||
if (parent is UserControl)
|
||||
{
|
||||
((UserControl)parent).SetResult(resultName, context);
|
||||
return;
|
||||
}
|
||||
else if (parent is Page)
|
||||
{
|
||||
((Page)parent).SetResult(resultName, context);
|
||||
return;
|
||||
}
|
||||
parent = parent.Parent;
|
||||
}
|
||||
throw new ArgumentException(string.Format("No URL mapping found for the specified result '{0}'.", resultName), "resultName");
|
||||
}
|
||||
WebNavigator.NavigateTo( resultName, context );
|
||||
}
|
||||
|
||||
result.Navigate(context);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a redirect url string that points to the
|
||||
/// <see cref="Spring.Web.Support.Result.TargetPage"/> defined by this
|
||||
/// result evaluated using this Page for expression
|
||||
/// </summary>
|
||||
/// <param name="resultName">Name of the result.</param>
|
||||
/// <returns>A redirect url string.</returns>
|
||||
protected string GetResultUrl( string resultName )
|
||||
{
|
||||
return ResolveUrl( WebNavigator.GetResultUri( resultName, this ) );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a redirect url string that points to the
|
||||
/// <see cref="Spring.Web.Support.Result.TargetPage"/> defined by this
|
||||
/// result evaluated using this Page for expression
|
||||
/// </summary>
|
||||
/// <param name="resultName">Name of the result.</param>
|
||||
/// <param name="context">The context to use for evaluating the SpEL expression in the Result</param>
|
||||
/// <returns>A redirect url string.</returns>
|
||||
protected string GetResultUrl( string resultName, object context )
|
||||
{
|
||||
return ResolveUrl( WebNavigator.GetResultUri( resultName, context ) );
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -598,7 +646,7 @@ namespace Spring.Web.UI
|
||||
/// <returns>
|
||||
/// <c>True</c> if all of the specified validators are valid, <c>False</c> otherwise.
|
||||
/// </returns>
|
||||
public bool Validate(object validationContext, params IValidator[] validators)
|
||||
public bool Validate( object validationContext, params IValidator[] validators )
|
||||
{
|
||||
IDictionary contextParams = CreateValidatorParameters();
|
||||
bool result = true;
|
||||
@@ -606,9 +654,9 @@ namespace Spring.Web.UI
|
||||
{
|
||||
if (validator == null)
|
||||
{
|
||||
throw new ArgumentException("Validator is not defined.");
|
||||
throw new ArgumentException( "Validator is not defined." );
|
||||
}
|
||||
result = validator.Validate(validationContext, contextParams, this.validationErrors) && result;
|
||||
result = validator.Validate( validationContext, contextParams, this.validationErrors ) && result;
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -660,7 +708,7 @@ namespace Spring.Web.UI
|
||||
/// Initializes the data bindings.
|
||||
/// </summary>
|
||||
protected virtual void InitializeDataBindings()
|
||||
{}
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the key to be used for looking up a cached
|
||||
@@ -707,7 +755,7 @@ namespace Spring.Web.UI
|
||||
this.bindingManager = sharedState[key] as BaseBindingManager;
|
||||
if (this.bindingManager == null)
|
||||
{
|
||||
lock(sharedState.SyncRoot)
|
||||
lock (sharedState.SyncRoot)
|
||||
{
|
||||
this.bindingManager = sharedState[key] as BaseBindingManager;
|
||||
if (this.bindingManager == null)
|
||||
@@ -715,10 +763,10 @@ namespace Spring.Web.UI
|
||||
try
|
||||
{
|
||||
this.bindingManager = CreateBindingManager();
|
||||
if(bindingManager == null)
|
||||
if (bindingManager == null)
|
||||
{
|
||||
throw new ArgumentNullException("bindingManager",
|
||||
"CreateBindingManager() must not return null");
|
||||
throw new ArgumentNullException( "bindingManager",
|
||||
"CreateBindingManager() must not return null" );
|
||||
}
|
||||
InitializeDataBindings();
|
||||
}
|
||||
@@ -728,7 +776,7 @@ namespace Spring.Web.UI
|
||||
throw;
|
||||
}
|
||||
sharedState[key] = this.bindingManager;
|
||||
this.OnDataBindingsInitialized(EventArgs.Empty);
|
||||
this.OnDataBindingsInitialized( EventArgs.Empty );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -737,13 +785,13 @@ namespace Spring.Web.UI
|
||||
/// <summary>
|
||||
/// Raises the <see cref="DataBindingsInitialized"/> event.
|
||||
/// </summary>
|
||||
protected virtual void OnDataBindingsInitialized(EventArgs e)
|
||||
protected virtual void OnDataBindingsInitialized( EventArgs e )
|
||||
{
|
||||
EventHandler handler = (EventHandler)base.Events[EventDataBindingsInitialized];
|
||||
|
||||
if(handler != null)
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, e);
|
||||
handler( this, e );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -754,11 +802,11 @@ namespace Spring.Web.UI
|
||||
{
|
||||
add
|
||||
{
|
||||
base.Events.AddHandler(EventDataBindingsInitialized, value);
|
||||
base.Events.AddHandler( EventDataBindingsInitialized, value );
|
||||
}
|
||||
remove
|
||||
{
|
||||
base.Events.RemoveHandler(EventDataBindingsInitialized, value);
|
||||
base.Events.RemoveHandler( EventDataBindingsInitialized, value );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -767,11 +815,11 @@ namespace Spring.Web.UI
|
||||
/// </summary>
|
||||
protected internal virtual void BindFormData()
|
||||
{
|
||||
if(BindingManager.HasBindings)
|
||||
if (BindingManager.HasBindings)
|
||||
{
|
||||
BindingManager.BindTargetToSource(this, Controller, Page.ValidationErrors);
|
||||
BindingManager.BindTargetToSource( this, Controller, Page.ValidationErrors );
|
||||
}
|
||||
OnDataBound(EventArgs.Empty);
|
||||
OnDataBound( EventArgs.Empty );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -779,11 +827,11 @@ namespace Spring.Web.UI
|
||||
/// </summary>
|
||||
protected internal virtual void UnbindFormData()
|
||||
{
|
||||
if(BindingManager.HasBindings)
|
||||
if (BindingManager.HasBindings)
|
||||
{
|
||||
BindingManager.BindSourceToTarget(this, Controller, Page.ValidationErrors);
|
||||
BindingManager.BindSourceToTarget( this, Controller, Page.ValidationErrors );
|
||||
}
|
||||
OnDataUnbound(EventArgs.Empty);
|
||||
OnDataUnbound( EventArgs.Empty );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -794,11 +842,11 @@ namespace Spring.Web.UI
|
||||
{
|
||||
add
|
||||
{
|
||||
base.Events.AddHandler(EventDataBound, value);
|
||||
base.Events.AddHandler( EventDataBound, value );
|
||||
}
|
||||
remove
|
||||
{
|
||||
base.Events.RemoveHandler(EventDataBound, value);
|
||||
base.Events.RemoveHandler( EventDataBound, value );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -806,12 +854,12 @@ namespace Spring.Web.UI
|
||||
/// Raises DataBound event.
|
||||
/// </summary>
|
||||
/// <param name="e">Event arguments.</param>
|
||||
protected virtual void OnDataBound(EventArgs e)
|
||||
protected virtual void OnDataBound( EventArgs e )
|
||||
{
|
||||
EventHandler handler = (EventHandler) base.Events[EventDataBound];
|
||||
EventHandler handler = (EventHandler)base.Events[EventDataBound];
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, e);
|
||||
handler( this, e );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -823,11 +871,11 @@ namespace Spring.Web.UI
|
||||
{
|
||||
add
|
||||
{
|
||||
base.Events.AddHandler(EventDataUnbound, value);
|
||||
base.Events.AddHandler( EventDataUnbound, value );
|
||||
}
|
||||
remove
|
||||
{
|
||||
base.Events.RemoveHandler(EventDataUnbound, value);
|
||||
base.Events.RemoveHandler( EventDataUnbound, value );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -835,12 +883,12 @@ namespace Spring.Web.UI
|
||||
/// Raises DataBound event.
|
||||
/// </summary>
|
||||
/// <param name="e">Event arguments.</param>
|
||||
protected virtual void OnDataUnbound(EventArgs e)
|
||||
protected virtual void OnDataUnbound( EventArgs e )
|
||||
{
|
||||
EventHandler handler = (EventHandler) base.Events[EventDataUnbound];
|
||||
EventHandler handler = (EventHandler)base.Events[EventDataUnbound];
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, e);
|
||||
handler( this, e );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -875,8 +923,8 @@ namespace Spring.Web.UI
|
||||
/// If thrown by any application context methods.
|
||||
/// </exception>
|
||||
/// <exception cref="Spring.Objects.Factory.ObjectInitializationException"/>
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable( false )]
|
||||
[DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
|
||||
public virtual IApplicationContext ApplicationContext
|
||||
{
|
||||
get { return applicationContext; }
|
||||
@@ -891,8 +939,8 @@ namespace Spring.Web.UI
|
||||
/// Gets or sets the localizer.
|
||||
/// </summary>
|
||||
/// <value>The localizer.</value>
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable( false )]
|
||||
[DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
|
||||
public ILocalizer Localizer
|
||||
{
|
||||
get { return localizer; }
|
||||
@@ -910,8 +958,8 @@ namespace Spring.Web.UI
|
||||
/// Gets or sets the local message source.
|
||||
/// </summary>
|
||||
/// <value>The local message source.</value>
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable( false )]
|
||||
[DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
|
||||
public IMessageSource MessageSource
|
||||
{
|
||||
get { return messageSource; }
|
||||
@@ -920,7 +968,7 @@ namespace Spring.Web.UI
|
||||
messageSource = value;
|
||||
if (messageSource != null && messageSource is AbstractMessageSource)
|
||||
{
|
||||
((AbstractMessageSource) messageSource).ParentMessageSource = applicationContext;
|
||||
((AbstractMessageSource)messageSource).ParentMessageSource = applicationContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -932,12 +980,12 @@ namespace Spring.Web.UI
|
||||
{
|
||||
if (this.MessageSource == null)
|
||||
{
|
||||
string key = CreateSharedStateKey("MessageSource");
|
||||
string key = CreateSharedStateKey( "MessageSource" );
|
||||
IDictionary sharedState = this.SharedState;
|
||||
IMessageSource messageSource = sharedState[key] as IMessageSource;
|
||||
if (messageSource == null)
|
||||
{
|
||||
lock(sharedState.SyncRoot)
|
||||
lock (sharedState.SyncRoot)
|
||||
{
|
||||
messageSource = sharedState[key] as IMessageSource;
|
||||
if (messageSource == null)
|
||||
@@ -947,7 +995,7 @@ namespace Spring.Web.UI
|
||||
ResourceManager rm = GetLocalResourceManager();
|
||||
if (rm != null)
|
||||
{
|
||||
defaultMessageSource.ResourceManagers.Add(rm);
|
||||
defaultMessageSource.ResourceManagers.Add( rm );
|
||||
}
|
||||
sharedState[key] = defaultMessageSource;
|
||||
messageSource = defaultMessageSource;
|
||||
@@ -978,13 +1026,13 @@ namespace Spring.Web.UI
|
||||
}
|
||||
#else
|
||||
{
|
||||
object resourceProvider = Page.GetLocalResourceProvider.Invoke(typeof(ResourceExpressionBuilder), new object[] {this});
|
||||
object resourceProvider = Page.GetLocalResourceProvider.Invoke( typeof( ResourceExpressionBuilder ), new object[] { this } );
|
||||
MethodInfo GetLocalResourceAssembly =
|
||||
resourceProvider.GetType().GetMethod("GetLocalResourceAssembly", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
Assembly localResourceAssembly = (Assembly) GetLocalResourceAssembly.Invoke(resourceProvider, null);
|
||||
resourceProvider.GetType().GetMethod( "GetLocalResourceAssembly", BindingFlags.NonPublic | BindingFlags.Instance );
|
||||
Assembly localResourceAssembly = (Assembly)GetLocalResourceAssembly.Invoke( resourceProvider, null );
|
||||
if (localResourceAssembly != null)
|
||||
{
|
||||
return new ResourceManager(VirtualPathUtility.GetFileName(this.AppRelativeVirtualPath), localResourceAssembly);
|
||||
return new ResourceManager( VirtualPathUtility.GetFileName( this.AppRelativeVirtualPath ), localResourceAssembly );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -995,9 +1043,9 @@ namespace Spring.Web.UI
|
||||
/// </summary>
|
||||
/// <param name="name">Resource name.</param>
|
||||
/// <returns>Message text.</returns>
|
||||
public string GetMessage(string name)
|
||||
public string GetMessage( string name )
|
||||
{
|
||||
return messageSource.GetMessage(name, UserCulture);
|
||||
return messageSource.GetMessage( name, UserCulture );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1006,9 +1054,9 @@ namespace Spring.Web.UI
|
||||
/// <param name="name">Resource name.</param>
|
||||
/// <param name="args">Message arguments that will be used to format return value.</param>
|
||||
/// <returns>Formatted message text.</returns>
|
||||
public string GetMessage(string name, params object[] args)
|
||||
public string GetMessage( string name, params object[] args )
|
||||
{
|
||||
return messageSource.GetMessage(name, UserCulture, args);
|
||||
return messageSource.GetMessage( name, UserCulture, args );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1016,16 +1064,16 @@ namespace Spring.Web.UI
|
||||
/// </summary>
|
||||
/// <param name="name">Resource name.</param>
|
||||
/// <returns>Resource object.</returns>
|
||||
public object GetResourceObject(string name)
|
||||
public object GetResourceObject( string name )
|
||||
{
|
||||
return messageSource.GetResourceObject(name, UserCulture);
|
||||
return messageSource.GetResourceObject( name, UserCulture );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets user's culture
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable( false )]
|
||||
[DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
|
||||
public virtual CultureInfo UserCulture
|
||||
{
|
||||
get { return Page.UserCulture; }
|
||||
@@ -1040,11 +1088,11 @@ namespace Spring.Web.UI
|
||||
/// Overrides Page property to return <see cref="Spring.Web.UI.Page"/>
|
||||
/// instead of <see cref="System.Web.UI.Page"/>.
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable( false )]
|
||||
[DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
|
||||
public new Page Page
|
||||
{
|
||||
get { return (Page) base.Page; }
|
||||
get { return (Page)base.Page; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -1057,7 +1105,7 @@ namespace Spring.Web.UI
|
||||
/// </summary>
|
||||
/// <param name="key">Key suffix</param>
|
||||
/// <returns>Generated unique shared state key.</returns>
|
||||
protected string CreateSharedStateKey(string key)
|
||||
protected string CreateSharedStateKey( string key )
|
||||
{
|
||||
return key;
|
||||
}
|
||||
@@ -1072,16 +1120,16 @@ namespace Spring.Web.UI
|
||||
IApplicationContext ISupportsWebDependencyInjection.DefaultApplicationContext
|
||||
{
|
||||
get { return defaultApplicationContext; }
|
||||
set { defaultApplicationContext = value; }
|
||||
set { defaultApplicationContext = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Injects dependencies into control before adding it.
|
||||
/// </summary>
|
||||
protected override void AddedControl(Control control,int index)
|
||||
protected override void AddedControl( Control control, int index )
|
||||
{
|
||||
WebDependencyInjectionUtils.InjectDependenciesRecursive( defaultApplicationContext, control );
|
||||
base.AddedControl(control,index);
|
||||
base.AddedControl( control, index );
|
||||
}
|
||||
|
||||
#endregion Dependency Injection Support
|
||||
|
||||
@@ -328,6 +328,11 @@
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Web\Support\ResultFactoryRegistryTests.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Web\Support\ResultTests.cs"
|
||||
SubType = "Code"
|
||||
|
||||
@@ -125,6 +125,7 @@
|
||||
<Compile Include="Web\Support\AbstractHandlerFactoryTests.cs" />
|
||||
<Compile Include="Web\Support\MimeMediaTypeTests.cs" />
|
||||
<Compile Include="Web\Support\PageHandlerFactoryTests.cs" />
|
||||
<Compile Include="Web\Support\ResultFactoryRegistryTests.cs" />
|
||||
<Compile Include="Web\Support\ResultTests.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region Imports
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using Rhino.Mocks;
|
||||
using Spring.Util;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Web.Support
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
[TestFixture]
|
||||
public class ResultFactoryRegistryTests
|
||||
{
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
ResultFactoryRegistry.Reset();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetDefaultFactory()
|
||||
{
|
||||
MockRepository mocks = new MockRepository();
|
||||
IResultFactory resultFactory = (IResultFactory)mocks.CreateMock( typeof( IResultFactory ) );
|
||||
|
||||
IResultFactory prevFactory = ResultFactoryRegistry.DefaultResultFactory;
|
||||
Assert.AreSame( prevFactory, ResultFactoryRegistry.SetDefaultFactory( resultFactory ) );
|
||||
Assert.AreSame( resultFactory, ResultFactoryRegistry.DefaultResultFactory );
|
||||
|
||||
// verify default factory is used for unknown result mode
|
||||
using (Record( mocks ))
|
||||
{
|
||||
Expect.Call( resultFactory.CreateResult( null, "resultText" ) ).Return( new Result() );
|
||||
Expect.Call( resultFactory.CreateResult( "resultMode", "resultText" ) ).Return( new Result() );
|
||||
}
|
||||
|
||||
using (Playback( mocks ))
|
||||
{
|
||||
ResultFactoryRegistry.CreateResult( "resultText" );
|
||||
ResultFactoryRegistry.CreateResult( "resultMode:resultText" );
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ResultModeValuesHavePredefinedFactories()
|
||||
{
|
||||
MockRepository mocks = new MockRepository();
|
||||
IResultFactory defaultFactory = (IResultFactory)mocks.CreateMock( typeof( IResultFactory ) );
|
||||
|
||||
ResultFactoryRegistry.SetDefaultFactory( defaultFactory );
|
||||
|
||||
// verify factory registry knows all ResultModes
|
||||
using (Record( mocks ))
|
||||
{
|
||||
// defaultFactory must never be called!
|
||||
}
|
||||
|
||||
using (Playback( mocks ))
|
||||
{
|
||||
foreach (string resultMode in Enum.GetNames( typeof( ResultMode ) ))
|
||||
{
|
||||
Assert.IsNotNull( ResultFactoryRegistry.CreateResult( resultMode+":resultText" ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SelectsFactoryByResultMode()
|
||||
{
|
||||
MockRepository mocks = new MockRepository();
|
||||
IResultFactory resultFactory = (IResultFactory)mocks.CreateMock( typeof( IResultFactory ) );
|
||||
|
||||
ResultFactoryRegistry.RegisterResultMode( "resultMode", resultFactory );
|
||||
|
||||
Result result = new Result();
|
||||
|
||||
// verify factory registry does not allow nulls to be returned
|
||||
using (Record( mocks ))
|
||||
{
|
||||
Expect.Call( resultFactory.CreateResult( "resultMode", "resultText" ) ).Return( result );
|
||||
}
|
||||
|
||||
using (Playback( mocks ))
|
||||
{
|
||||
Assert.AreSame( result, ResultFactoryRegistry.CreateResult( "resultMode:resultText" ) );
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
[ExpectedException( typeof( ArgumentNullException ) )]
|
||||
public void BailsOnNullReturnedFromFactory()
|
||||
{
|
||||
MockRepository mocks = new MockRepository();
|
||||
IResultFactory resultFactory = (IResultFactory)mocks.CreateMock( typeof( IResultFactory ) );
|
||||
|
||||
ResultFactoryRegistry.RegisterResultMode( "resultMode", resultFactory );
|
||||
|
||||
// verify factory registry does not allow nulls to be returned
|
||||
using (Record( mocks ))
|
||||
{
|
||||
Expect.Call( resultFactory.CreateResult( "resultMode", "resultText" ) ).Return( null );
|
||||
}
|
||||
|
||||
using (Playback( mocks ))
|
||||
{
|
||||
ResultFactoryRegistry.CreateResult( "resultMode:resultText" );
|
||||
}
|
||||
}
|
||||
|
||||
#region Rhino.Mocks Compatibility Adapter
|
||||
|
||||
private static IDisposable Record( MockRepository mocks )
|
||||
{
|
||||
#if !NET_1_1
|
||||
return mocks.Record();
|
||||
#else
|
||||
return new RecordModeChanger(mocks);
|
||||
#endif
|
||||
}
|
||||
|
||||
private static IDisposable Playback( MockRepository mocks )
|
||||
{
|
||||
#if !NET_1_1
|
||||
return mocks.Playback();
|
||||
#else
|
||||
return new PlaybackModeChanger(mocks);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if NET_1_1
|
||||
private class RecordModeChanger : IDisposable
|
||||
{
|
||||
private MockRepository _mocks;
|
||||
|
||||
public RecordModeChanger(MockRepository mocks)
|
||||
{
|
||||
_mocks = mocks;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_mocks.ReplayAll();
|
||||
}
|
||||
}
|
||||
|
||||
private class PlaybackModeChanger : IDisposable
|
||||
{
|
||||
private MockRepository _mocks;
|
||||
|
||||
public PlaybackModeChanger(MockRepository mocks)
|
||||
{
|
||||
_mocks = mocks;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_mocks.VerifyAll();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endregion Rhino.Mocks Compatibility Adapter
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,9 @@
|
||||
#region Imports
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using NUnit.Framework;
|
||||
using Spring.Util;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -333,5 +335,32 @@ namespace Spring.Web.Support
|
||||
"The TargetPage property is not being correctly extracted " +
|
||||
"from the result string passed into the ctor.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TargetPageMayBeRuntimeExpression()
|
||||
{
|
||||
Result result = new Result("%{['var1']}");
|
||||
string resultUri = result.GetRedirectUri( MakeDictionary("var1", "val1") );
|
||||
Assert.AreEqual( "val1", resultUri );
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ParameterKeysAndValuesMayBeRuntimeExpression()
|
||||
{
|
||||
Result result = new Result("redirect:%{['var1']}?%{['var2']}=%{['var3']}");
|
||||
string resultUri = result.GetRedirectUri( MakeDictionary("var1", "val1", "var2", "val2", "var3", "val3") );
|
||||
Assert.AreEqual( "val1?val2=val3", resultUri );
|
||||
}
|
||||
|
||||
private IDictionary MakeDictionary( params object[] args)
|
||||
{
|
||||
AssertUtils.IsTrue(args.Length % 2 == 0);
|
||||
Hashtable ht= new Hashtable();
|
||||
for(int i=0;i<args.Length;i+=2)
|
||||
{
|
||||
ht[args[i]] = args[i+1];
|
||||
}
|
||||
return ht;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -97,7 +97,7 @@ namespace Spring.Web.UI
|
||||
}
|
||||
catch(ArgumentException ae)
|
||||
{
|
||||
string expected = string.Format("No URL mapping found for the specified result '{0}'.", RESULTNAME);
|
||||
string expected = string.Format("No result mapping found for the specified name '{0}'.", RESULTNAME);
|
||||
string msg = ae.Message.Substring(0, expected.Length);
|
||||
Assert.AreEqual(expected, msg);
|
||||
}
|
||||
|
||||
@@ -41,19 +41,39 @@ namespace Spring.Web.UI
|
||||
{
|
||||
public class TestUserControl : UserControl
|
||||
{
|
||||
private static int instanceCount = 0;
|
||||
|
||||
public TestUserControl()
|
||||
:this(string.Format("_ctl_{0}", instanceCount++), null)
|
||||
{
|
||||
}
|
||||
|
||||
public TestUserControl(string id)
|
||||
:this(id, null)
|
||||
{
|
||||
}
|
||||
|
||||
public TestUserControl(Control parent)
|
||||
:this(null, parent)
|
||||
{
|
||||
parent.Controls.Add(this);
|
||||
}
|
||||
|
||||
public TestUserControl(string id, Control parent)
|
||||
{
|
||||
this.ID = id;
|
||||
if (parent != null) parent.Controls.Add(this);
|
||||
}
|
||||
|
||||
public new void SetResult(string name)
|
||||
{
|
||||
base.SetResult(name);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("{0}[{1}]", base.ToString(), this.ClientID);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -85,7 +105,8 @@ namespace Spring.Web.UI
|
||||
|
||||
using (mocks.Ordered())
|
||||
{
|
||||
theResult.Navigate(c1);
|
||||
// context is the control, that SetResult() was called on
|
||||
theResult.Navigate(c111);
|
||||
}
|
||||
mocks.ReplayAll();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user