fixed SPRNET-1118 + added sample "NestedEmployeeInfo" to WebQuickStart
This commit is contained in:
@@ -35,6 +35,10 @@
|
||||
<p>
|
||||
Demonstrates basic model validation capabilities
|
||||
</p>
|
||||
<h3><a href="NestedEmployeeInfo/Default.aspx">Nested Employee Info</a></h3>
|
||||
<p>
|
||||
Demonstrates basic model validation capabilities on controls
|
||||
</p>
|
||||
<h3><a href="Lists/Default.aspx">Lists</a></h3>
|
||||
<p>
|
||||
Demonstrates bi-directional binding of multi-selection listboxes
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<%@ Page Language="C#" EnableViewState="false" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="DataBinding_RobustEmployeeInfo_Default" %>
|
||||
<%-- @ Reference Control="EmployeeInfoEditor.ascx" --%>
|
||||
<%@ Register TagPrefix="user" TagName="EmployeeInfoEditor" Src="EmployeeInfoEditor.ascx" %>
|
||||
<!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>Data Binding - Nested Employee Info example</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2><a href="../../Default.aspx">Welcome to Spring.NET Web Framework Quick Start Guide</a></h2>
|
||||
<h2><a href="../Default.aspx">Bi-directional DataBinding</a></h2>
|
||||
<form id="form1" runat="server">
|
||||
<div>
|
||||
<h2>Nested Employee Info example</h2>
|
||||
<p>
|
||||
This is the same as Robust Employee Info example except that all controls are placed on nested a user control
|
||||
</p>
|
||||
<!-- this summary control captures validation errors from the "Editor" control below -->
|
||||
<spring:ValidationSummary ID="summary" Provider="summary" ValidationContainerName="Editor" runat="server" />
|
||||
<user:EmployeeInfoEditor ID="Editor" runat="server" />
|
||||
</div>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
/// <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 DataBinding_RobustEmployeeInfo_Default : Spring.Web.UI.Page
|
||||
{
|
||||
private EmployeeInfoEditor employeeInfoEditor;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="EmployeeInfoEditor.ascx.cs" Inherits="EmployeeInfoEditor" %>
|
||||
<%@ Register TagPrefix="spring" Namespace="Spring.Web.UI.Controls" Assembly="Spring.Web" %>
|
||||
<table cellpadding="3" cellspacing="3" border="0">
|
||||
<tr>
|
||||
<td>Employee ID:</td>
|
||||
<td>
|
||||
<asp:TextBox ID="txtId" runat="server" EnableViewState="false" />
|
||||
<spring:ValidationError ID="errId" Provider="id.errors" runat="server" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>First Name:</td>
|
||||
<td><asp:TextBox ID="txtFirstName" runat="server" EnableViewState="false" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Last Name:</td>
|
||||
<td><asp:TextBox ID="txtLastName" runat="server" EnableViewState="false" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Date of Birth:</td>
|
||||
<td>
|
||||
<asp:TextBox ID="txtDOB" runat="server" EnableViewState="false" />
|
||||
<spring:ValidationError ID="errDOB" Provider="dob.errors" runat="server" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Gender:</td>
|
||||
<td>
|
||||
<!--
|
||||
RadioButtonGroup control exposes Value property which is set
|
||||
to the value of the ID property of the selected radio button
|
||||
-->
|
||||
<spring:RadioButtonGroup ID="rbgGender" runat="server" EnableViewState="false">
|
||||
<asp:RadioButton ID="Male" Text="Male" runat="server" EnableViewState="false" />
|
||||
<asp:RadioButton ID="Female" Text="Female" runat="server" EnableViewState="false" />
|
||||
</spring:RadioButtonGroup>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Salary:</td>
|
||||
<td>
|
||||
<asp:TextBox ID="txtSalary" runat="server" EnableViewState="false" />
|
||||
<spring:ValidationError ID="errSalary" Provider="salary.errors" runat="server" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Address Type:</td>
|
||||
<td>
|
||||
<!--
|
||||
Another way to select one of the predefined values, which is
|
||||
how enum values should always be entered
|
||||
-->
|
||||
<asp:DropDownList ID="ddlAddressType" runat="server" EnableViewState="false">
|
||||
<asp:ListItem Value="Home" Text="Home" Selected="True" />
|
||||
<asp:ListItem Value="Office" Text="Office" />
|
||||
</asp:DropDownList>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Street 1:</td>
|
||||
<td><asp:TextBox ID="txtStreet1" runat="server" EnableViewState="false" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Street 2:</td>
|
||||
<td><asp:TextBox ID="txtStreet2" runat="server" EnableViewState="false" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>City:</td>
|
||||
<td><asp:TextBox ID="txtCity" runat="server" EnableViewState="false" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>State:</td>
|
||||
<td><asp:TextBox ID="txtState" runat="server" EnableViewState="false" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Postal Code/ZIP:</td>
|
||||
<td><asp:TextBox ID="txtPostalCode" runat="server" EnableViewState="false" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Country:</td>
|
||||
<td><asp:TextBox ID="txtCountry" runat="server" EnableViewState="false" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td><asp:Button ID="btnSave" runat="server" Text="Save" OnClick="btnSave_Click" /></td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Spring.Globalization.Formatters;
|
||||
|
||||
public partial class EmployeeInfoEditor : Spring.Web.UI.UserControl
|
||||
{
|
||||
private EmployeeInfo employee = new EmployeeInfo();
|
||||
|
||||
public EmployeeInfo Employee
|
||||
{
|
||||
get { return employee; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// In order to declare data bindings, all you need to do is
|
||||
/// override InitializeDataBindings method and add all necessary
|
||||
/// data bindings to the BindingManager.
|
||||
/// </summary>
|
||||
protected override void InitializeDataBindings()
|
||||
{
|
||||
BindingManager.AddBinding("txtId.Text", "Employee.Id")
|
||||
.SetErrorMessage("ID has to be an integer", "id.errors", "summary");
|
||||
BindingManager.AddBinding("txtFirstName.Text", "Employee.FirstName");
|
||||
BindingManager.AddBinding("txtLastName.Text", "Employee.LastName");
|
||||
BindingManager.AddBinding("txtDOB.Text", "Employee.DateOfBirth")
|
||||
.SetErrorMessage("Invalid date value", "dob.errors", "summary");
|
||||
BindingManager.AddBinding("txtSalary.Text", "Employee.Salary", new CurrencyFormatter())
|
||||
.SetErrorMessage("Salary must be a valid currency value.", "salary.errors", "summary");
|
||||
BindingManager.AddBinding("rbgGender.Value", "Employee.Gender");
|
||||
BindingManager.AddBinding("ddlAddressType.SelectedValue", "Employee.MailingAddress.AddressType");
|
||||
BindingManager.AddBinding("txtStreet1.Text", "Employee.MailingAddress.Street1");
|
||||
BindingManager.AddBinding("txtStreet2.Text", "Employee.MailingAddress.Street2");
|
||||
BindingManager.AddBinding("txtCity.Text", "Employee.MailingAddress.City");
|
||||
BindingManager.AddBinding("txtState.Text", "Employee.MailingAddress.State");
|
||||
BindingManager.AddBinding("txtPostalCode.Text", "Employee.MailingAddress.PostalCode");
|
||||
BindingManager.AddBinding("txtCountry.Text", "Employee.MailingAddress.Country");
|
||||
}
|
||||
|
||||
protected void btnSave_Click(object sender, EventArgs e)
|
||||
{
|
||||
// do something with employee such as:
|
||||
// employeeDao.Save(Employee);
|
||||
|
||||
Debug.Write(Employee);
|
||||
}
|
||||
}
|
||||
@@ -33,12 +33,14 @@
|
||||
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>
|
||||
<!-- this summary control captures validation errors on this page -->
|
||||
<spring:ValidationSummary ID="summary" Provider="summary" ValidationContainerName="Editor" runat="server" />
|
||||
<table cellpadding="3" cellspacing="3" border="0">
|
||||
<tr>
|
||||
<td>Employee ID:</td>
|
||||
<td>
|
||||
<asp:TextBox ID="txtId" runat="server" EnableViewState="false" />
|
||||
<spring:ValidationError ID="errId" Provider="id.errors" runat="server" />
|
||||
<spring:ValidationError ID="errId" Provider="id.errors" runat="server" /><!-- read msg from "id.error" provider -->
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -23,7 +23,7 @@ public partial class DataBinding_RobustEmployeeInfo_Default : Spring.Web.UI.Page
|
||||
protected override void InitializeDataBindings()
|
||||
{
|
||||
BindingManager.AddBinding("txtId.Text", "Employee.Id")
|
||||
.SetErrorMessage("ID has to be an integer", "id.errors");
|
||||
.SetErrorMessage("ID has to be an integer", "id.errors"); // send msg to "id.errors" provider
|
||||
BindingManager.AddBinding("txtFirstName.Text", "Employee.FirstName");
|
||||
BindingManager.AddBinding("txtLastName.Text", "Employee.LastName");
|
||||
BindingManager.AddBinding("txtDOB.Text", "Employee.DateOfBirth")
|
||||
|
||||
@@ -1,81 +1,73 @@
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="spring">
|
||||
<section name="context" type="Spring.Context.Support.WebContextHandler, Spring.Web"/>
|
||||
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core"/>
|
||||
</sectionGroup>
|
||||
<sectionGroup name="common">
|
||||
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging"/>
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
<!-- to see logging output in the attached debugger -->
|
||||
<common>
|
||||
<logging>
|
||||
<factoryAdapter type="Common.Logging.Simple.TraceLoggerFactoryAdapter, Common.Logging">
|
||||
<arg key="Level" value="ALL"/>
|
||||
</factoryAdapter>
|
||||
</logging>
|
||||
</common>
|
||||
<system.web>
|
||||
<customErrors mode="Off" />
|
||||
|
||||
<compilation debug="true">
|
||||
<assemblies>
|
||||
<add assembly="System.DirectoryServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
|
||||
</assemblies>
|
||||
</compilation>
|
||||
<pages>
|
||||
<controls>
|
||||
<add tagPrefix="spring" namespace="Spring.Web.UI.Controls" assembly="Spring.Web"/>
|
||||
</controls>
|
||||
</pages>
|
||||
<!--
|
||||
<configSections>
|
||||
<sectionGroup name="spring">
|
||||
<section name="context" type="Spring.Context.Support.WebContextHandler, Spring.Web"/>
|
||||
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core"/>
|
||||
</sectionGroup>
|
||||
<sectionGroup name="common">
|
||||
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging"/>
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
<!-- to see logging output in the attached debugger -->
|
||||
<common>
|
||||
<logging>
|
||||
<factoryAdapter type="Common.Logging.Simple.TraceLoggerFactoryAdapter, Common.Logging">
|
||||
<arg key="Level" value="ALL"/>
|
||||
</factoryAdapter>
|
||||
</logging>
|
||||
</common>
|
||||
<system.web>
|
||||
<customErrors mode="Off"/>
|
||||
<compilation debug="true">
|
||||
</compilation>
|
||||
<pages>
|
||||
<controls>
|
||||
<add tagPrefix="spring" namespace="Spring.Web.UI.Controls" assembly="Spring.Web"/>
|
||||
</controls>
|
||||
</pages>
|
||||
<!--
|
||||
The following needs to be configured in order to enable Spring.NET Web Framework features
|
||||
-->
|
||||
<httpModules>
|
||||
<add name="SpringModule" type="Spring.Context.Support.WebSupportModule, Spring.Web"/>
|
||||
<add name="HtmlCommentAppender" type="HtmlCommentAppenderModule"/>
|
||||
<!-- this custom module is only for DI demonstration purposes -->
|
||||
</httpModules>
|
||||
<httpHandlers>
|
||||
<add verb="*" path="*.aspx" type="Spring.Web.Support.PageHandlerFactory, Spring.Web"/>
|
||||
</httpHandlers>
|
||||
</system.web>
|
||||
|
||||
<system.webServer>
|
||||
<validation validateIntegratedModeConfiguration="false"/>
|
||||
|
||||
<modules>
|
||||
<add name="SpringModule" type="Spring.Context.Support.WebSupportModule, Spring.Web"/>
|
||||
<add name="HtmlCommentAppender" type="HtmlCommentAppenderModule"/>
|
||||
</modules>
|
||||
|
||||
<handlers>
|
||||
<add name="SpringPageHandler" verb="*" path="*.aspx" type="Spring.Web.Support.PageHandlerFactory, Spring.Web"/>
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
|
||||
<!-- demonstrates how to configure IHttpModule instances -->
|
||||
<spring>
|
||||
<context>
|
||||
<resource uri="config://spring/objects"/>
|
||||
</context>
|
||||
<objects xmlns="http://www.springframework.net">
|
||||
<!-- configure our custom HttpModule -->
|
||||
<object name="HttpApplicationConfigurer" type="Spring.Context.Support.HttpApplicationConfigurer, Spring.Web">
|
||||
<property name="ModuleTemplates">
|
||||
<dictionary>
|
||||
<entry key="HtmlCommentAppender">
|
||||
<!-- this name must match the module name -->
|
||||
<object>
|
||||
<!-- select "view source" in your browser on any page to see the appended html comment -->
|
||||
<property name="AppendText" value="My configured comment!"/>
|
||||
</object>
|
||||
</entry>
|
||||
</dictionary>
|
||||
</property>
|
||||
</object>
|
||||
</objects>
|
||||
</spring>
|
||||
<httpModules>
|
||||
<add name="SpringModule" type="Spring.Context.Support.WebSupportModule, Spring.Web"/>
|
||||
<add name="HtmlCommentAppender" type="HtmlCommentAppenderModule"/>
|
||||
<!-- this custom module is only for DI demonstration purposes -->
|
||||
</httpModules>
|
||||
<httpHandlers>
|
||||
<add verb="*" path="*.aspx" type="Spring.Web.Support.PageHandlerFactory, Spring.Web"/>
|
||||
</httpHandlers>
|
||||
</system.web>
|
||||
<system.webServer>
|
||||
<validation validateIntegratedModeConfiguration="false"/>
|
||||
<modules>
|
||||
<add name="SpringModule" type="Spring.Context.Support.WebSupportModule, Spring.Web"/>
|
||||
<add name="HtmlCommentAppender" type="HtmlCommentAppenderModule"/>
|
||||
</modules>
|
||||
<handlers>
|
||||
<add name="SpringPageHandler" verb="*" path="*.aspx" type="Spring.Web.Support.PageHandlerFactory, Spring.Web"/>
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
<!-- demonstrates how to configure IHttpModule instances -->
|
||||
<spring>
|
||||
<context>
|
||||
<resource uri="config://spring/objects"/>
|
||||
</context>
|
||||
<objects xmlns="http://www.springframework.net">
|
||||
<!-- configure our custom HttpModule -->
|
||||
<object name="HttpApplicationConfigurer" type="Spring.Context.Support.HttpApplicationConfigurer, Spring.Web">
|
||||
<property name="ModuleTemplates">
|
||||
<dictionary>
|
||||
<entry key="HtmlCommentAppender">
|
||||
<!-- this name must match the module name -->
|
||||
<object>
|
||||
<!-- select "view source" in your browser on any page to see the appended html comment -->
|
||||
<property name="AppendText" value="My configured comment!"/>
|
||||
</object>
|
||||
</entry>
|
||||
</dictionary>
|
||||
</property>
|
||||
</object>
|
||||
</objects>
|
||||
</spring>
|
||||
</configuration>
|
||||
|
||||
@@ -20,8 +20,11 @@
|
||||
|
||||
#region Imports
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
using Spring.Context;
|
||||
using Spring.Util;
|
||||
using Spring.Validation;
|
||||
@@ -38,6 +41,7 @@ namespace Spring.Web.UI.Controls
|
||||
public abstract class AbstractValidationControl : Control
|
||||
{
|
||||
private string provider;
|
||||
private string validationContainerName;
|
||||
private IValidationErrorsRenderer renderer;
|
||||
|
||||
#if !NET_2_0
|
||||
@@ -70,6 +74,18 @@ namespace Spring.Web.UI.Controls
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/// <summary>
|
||||
/// If set, <see cref="ValidationContainer"/> will resolve to the named control specified
|
||||
/// by this property. The behavior of name resolution is identical to
|
||||
/// <see cref="System.Web.UI.WebControls.BaseValidator.ControlToValidate"/>, except that if the name
|
||||
/// starts with "::", the resolution will start at the page level instead of relative to this
|
||||
/// control
|
||||
/// </summary>
|
||||
public virtual string ValidationContainerName
|
||||
{
|
||||
get { return validationContainerName; }
|
||||
set { validationContainerName = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the provider.
|
||||
@@ -146,15 +162,34 @@ namespace Spring.Web.UI.Controls
|
||||
{
|
||||
get
|
||||
{
|
||||
// is an explicit container specified?
|
||||
if (ValidationContainerName != null)
|
||||
{
|
||||
Control start = this.NamingContainer;
|
||||
string containerName = this.ValidationContainerName;
|
||||
// shall we do a global search?
|
||||
if (containerName.StartsWith("::"))
|
||||
{
|
||||
containerName = containerName.Substring(2);
|
||||
start = this.Page;
|
||||
}
|
||||
IValidationContainer container = start.FindControl(containerName) as IValidationContainer;
|
||||
if (container == null)
|
||||
{
|
||||
throw new ArgumentException(string.Format("Validation Container Control specified by {0} does not exist or does not implement IValidationContainer", this.ValidationContainerName));
|
||||
}
|
||||
return container;
|
||||
}
|
||||
|
||||
for (Control parent = this.Parent; parent != null; parent = parent.Parent)
|
||||
{
|
||||
IValidationContainer container = parent as IValidationContainer;
|
||||
if (container != null)
|
||||
if (container != null
|
||||
&& container.ValidationErrors != null)
|
||||
{
|
||||
return container;
|
||||
}
|
||||
}
|
||||
// throw new NotSupportedException(string.Format("Controls of Type {0} must be placed on a container control implementing IValidationContainer", this.GetType().Name));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -201,7 +236,7 @@ namespace Spring.Web.UI.Controls
|
||||
|
||||
errorMessages = ResolveErrorMessages();
|
||||
|
||||
Renderer.RenderErrors(Page as Spring.Web.UI.Page, writer, errorMessages);
|
||||
Renderer.RenderErrors(Page as Page, writer, errorMessages);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -676,7 +676,7 @@ namespace Spring.Web.UI
|
||||
{
|
||||
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;
|
||||
@@ -837,7 +837,7 @@ namespace Spring.Web.UI
|
||||
{
|
||||
if (BindingManager.HasBindings)
|
||||
{
|
||||
BindingManager.BindTargetToSource( this, Controller, Page.ValidationErrors );
|
||||
BindingManager.BindTargetToSource( this, Controller, this.ValidationErrors );
|
||||
}
|
||||
OnDataBound( EventArgs.Empty );
|
||||
}
|
||||
@@ -849,7 +849,7 @@ namespace Spring.Web.UI
|
||||
{
|
||||
if (BindingManager.HasBindings)
|
||||
{
|
||||
BindingManager.BindSourceToTarget( this, Controller, Page.ValidationErrors );
|
||||
BindingManager.BindSourceToTarget( this, Controller, this.ValidationErrors );
|
||||
}
|
||||
OnDataUnbound( EventArgs.Empty );
|
||||
}
|
||||
|
||||
@@ -179,6 +179,80 @@ namespace Spring.Web.UI.Controls
|
||||
Assert.AreEqual(messageSource, ctl.TheMessageSource);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ReadsErrorsFromClosestValidationContainerByDefault()
|
||||
{
|
||||
// indirect containment
|
||||
Spring.Web.UI.Page page = new Spring.Web.UI.Page();
|
||||
TestValidationControl vc = new TestValidationControl();
|
||||
Spring.Web.UI.UserControl inBetweenControl = new Spring.Web.UI.UserControl();
|
||||
inBetweenControl.Controls.Add(vc);
|
||||
page.Controls.Add(inBetweenControl);
|
||||
Assert.AreSame(inBetweenControl, vc.TheValidationContainer);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DoesNotReadErrorsFromCrossValidationContainerByDefault()
|
||||
{
|
||||
// containment tree:
|
||||
//
|
||||
// Page : IValidationContainer
|
||||
// - outerVC
|
||||
// - inBetweenControl1 : IValidationContainer
|
||||
// - innerVC
|
||||
|
||||
Spring.Web.UI.Page page = new Spring.Web.UI.Page();
|
||||
Spring.Web.UI.UserControl inBetweenControl1 = new Spring.Web.UI.UserControl();
|
||||
inBetweenControl1.ID = "InBetweenControl1";
|
||||
TestValidationControl innerVC = new TestValidationControl();
|
||||
inBetweenControl1.Controls.Add(innerVC);
|
||||
page.Controls.Add(inBetweenControl1);
|
||||
TestValidationControl outerVC = new TestValidationControl();
|
||||
page.Controls.Add(outerVC);
|
||||
|
||||
inBetweenControl1.ValidationErrors.AddError("provider", new ErrorMessage("msg"));
|
||||
|
||||
Assert.AreSame(inBetweenControl1, innerVC.TheValidationContainer);
|
||||
Assert.AreSame(page, outerVC.TheValidationContainer);
|
||||
Assert.AreEqual(1, innerVC.TheValidationContainer.ValidationErrors.GetErrors("provider").Count);
|
||||
Assert.AreEqual(0, outerVC.TheValidationContainer.ValidationErrors.GetErrors("provider").Count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanReadErrorsFromCrossValidationContainerByDefault()
|
||||
{
|
||||
// containment tree:
|
||||
//
|
||||
// Page : IValidationContainer
|
||||
// - outerVC
|
||||
// - inBetweenControl1 : IValidationContainer
|
||||
// - innerVC
|
||||
|
||||
Spring.Web.UI.Page page = new Spring.Web.UI.Page();
|
||||
Spring.Web.UI.UserControl userControl = new Spring.Web.UI.UserControl();
|
||||
userControl.ID = "userControl";
|
||||
TestValidationControl innerVC = new TestValidationControl();
|
||||
userControl.Controls.Add(innerVC);
|
||||
page.Controls.Add(userControl);
|
||||
TestValidationControl outerVC = new TestValidationControl();
|
||||
page.Controls.Add(outerVC);
|
||||
|
||||
userControl.ValidationErrors.AddError("provider", new ErrorMessage("msg"));
|
||||
|
||||
Assert.AreSame(userControl, innerVC.TheValidationContainer);
|
||||
Assert.AreSame(page, outerVC.TheValidationContainer);
|
||||
Assert.AreEqual(1, innerVC.TheValidationContainer.ValidationErrors.GetErrors("provider").Count);
|
||||
Assert.AreEqual(0, outerVC.TheValidationContainer.ValidationErrors.GetErrors("provider").Count);
|
||||
|
||||
// test local-relative name resolution
|
||||
outerVC.ValidationContainerName = "userControl";
|
||||
Assert.AreEqual(1, outerVC.TheValidationContainer.ValidationErrors.GetErrors("provider").Count);
|
||||
|
||||
// test global name resolution
|
||||
outerVC.ValidationContainerName = "::userControl";
|
||||
Assert.AreEqual(1, outerVC.TheValidationContainer.ValidationErrors.GetErrors("provider").Count);
|
||||
}
|
||||
|
||||
#region TestValidationControl
|
||||
|
||||
private class TestValidationControl : AbstractValidationControl
|
||||
|
||||
Reference in New Issue
Block a user