|
|
Частичная проверка правильности ввода данных.
В данной публикации рассказывается о том, как можно организовать частичную проверку правильности введенных данных в ASP.NET форме.
Довольно часто можно столкнуться с проблемой, когда на одной странице находятся две «формы», правильность данных в которых необходимо проверять по отдельности. Обычно приходиться жертвовать клиентской частью проверок и делать все проверки на сервере, но не очень удобно.
Далее мы рассмотрим способы, которыми можно реализовать частичную проверку. Первый способ достаточно прост и подходит, когда у нас все проверяющие элементы управления (Валидаторы) находятся на одной странице. Ниже представлен пример того, как это реализуется. <%@ Page %>
<%@ Import Namespace="System.Collections"%>
<head>
<script language="javascript">
function EnableValidationGroup( activeValidators ) {
// Если на странице нет валидаторов то ничего не делаем
if (typeof(Page_Validators)=='undefined') return;
//Выключаем все валидаторы
for( i = 0; i < Page_Validators.length; i++ )
Page_Validators[i].enabled = false;
//Включаем нужные нам валидаторы
for( i = 0; i < activeValidators.length; i++ )
activeValidators[i].enabled = true;
}
</script>
<script runat="server" language="c#">
Hashtable _validationGroups = new Hashtable();
void CreateValidationGroup(string name, params BaseValidator[] validators) {
_validationGroups[name] = validators;
foreach(BaseValidator validator in validators) {
RegisterArrayDeclaration(name,string.Format("document.all[\"{0}\"]",validator.ClientID));
}
}
bool IsValidationGroupValid(string name) {
BaseValidator[] validators = (BaseValidator[])_validationGroups[name];
bool isValid = true;
foreach(BaseValidator validator in validators) {
isValid &= validator.IsValid;
}
return isValid;
}
void RegisterControlValidationGroup(Button button,string name) {
button.Attributes.Add("onclick","EnableValidationGroup(" + name + ");");
}
void Page_Load(object sender, EventArgs e) {
CreateValidationGroup("__validatorGroup1",_passwordRequired,_loginRequired);
CreateValidationGroup("__validatorGroup2",_titleRequired,_messageRequired);
RegisterControlValidationGroup(_loginButton,"__validatorGroup1");
RegisterControlValidationGroup(_postButton,"__validatorGroup2");
}
void OnLoginButtonClick(object sender, EventArgs e) {
if (!IsValidationGroupValid("__validatorGroup1")) {
return;
}
Response.Write("Login sucessfull");
}
void OnPostButtonClick(object sender, EventArgs e) {
if (!IsValidationGroupValid("__validatorGroup2")) {
return;
}
Response.Write("Post sucessfull");
}
</script>
</head>
<body>
<form runat="server">
<table width="100%">
<tr>
<td width="200px" valign="top">
<fieldset>
<legend>Login</legend>
<table width="200">
<tr>
<td>Login:</td>
<td>
<asp:TextBox id="_loginText" runat="server" Width="150px"/>
<asp:RequiredFieldValidator ErrorMessage="Login is required field"
runat="server" id="_loginRequired" Text="*" Display="None"
ControlToValidate="_loginText"/>
</td>
</tr>
<tr>
<td>Password:</td>
<td><asp:TextBox id="_passwordText" TextMode="Password"
runat="server" Width="150px"/>
<asp:RequiredFieldValidator ErrorMessage="Password is required field"
runat="server" id="_passwordRequired" Text="*"
Display="None" ControlToValidate="_passwordText"/>
</td>
</tr>
<tr>
<td></td>
<td><asp:Button runat="server" id="_loginButton"
Text="Log In" Width="100px" OnClick="OnLoginButtonClick"/></td>
</tr>
</table>
</fieldset>
</td>
<td width="100%">
<fieldset>
<legend>Message Post</legend>
<table>
<tr>
<td>Title:</td>
<td><asp:TextBox id="_titleText" runat="server" Width="400px"/>
<asp:RequiredFieldValidator ErrorMessage="Title is required field"
runat="server" id="_titleRequired" Text="*" Display="None"
ControlToValidate="_titleText"/>
</td>
</tr>
<tr>
<td colspan="2">Message:</td>
</tr>
<tr>
<td colspan="2">
<asp:TextBox TextMode="MultiLine" Rows="20" id="_messageText"
runat="server" Width="600px"/>
<asp:RequiredFieldValidator runat="server"
ErrorMessage="Message is required field" id="_messageRequired" Text="*"
Display="None" ControlToValidate="_messageText"/>
</td>
</tr>
<tr>
<td align="right" colspan="2"><asp:Button id="_postButton"
runat="server" Text="Post" Width="100px"
OnClick="OnPostButtonClick"/></td>
</tr>
</table>
</fieldset>
</td>
</tr>
</table>
<asp:ValidationSummary runat="server" ShowMessageBox="true" ShowSummary="false"/>
</form>
</body>
Но, в случае использования данного функционала на нескольких страницах, приходится делать Copy & Paste кода, что не очень красиво и муторно, тем более, что достаточно просто допустить ошибку. Для того чтобы избежать этого, мы инкапсулируем всю логику в отдельный элемент управления. using System;
using System.IO;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
namespace TestWebControls
{
[
Designer("System.Web.UI.Design.WebControls.PanelDesigner, System.Design,
Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"),
PersistChildren(true), ParseChildren(false)]
public class ValidationGroup : Panel
{
public static readonly string ValidationGroupScriptKey = "__validationGroupScript";
protected override void Render(HtmlTextWriter writer)
{
base.RenderChildren(writer);
}
protected override void OnPreRender(EventArgs e)
{
if(!Page.IsClientScriptBlockRegistered(ValidationGroupScriptKey))
{
string resourceName = typeof(ValidationGroup).Namespace +
".Resources.ValidationGroup.js";
using(StreamReader reader = new StreamReader(
typeof(ValidationGroup).Assembly.GetManifestResourceStream(resourceName)))
{
Page.RegisterClientScriptBlock(ValidationGroupScriptKey,reader.ReadToEnd());
}
}
RegisterValidators(this);
base.OnPreRender (e);
}
public string GetValidationGroupScript()
{
return string.Format("if (typeof({0}_Validators)!='undefined') " +
"{{ EnableValidationGroup({0}_Validators,{0}_InitialEnabled)}} else " +
"{{EnableValidationGroup();}};",ClientID);
}
public void RegisterControl(Button button)
{
button.Attributes.Add("onclick",GetValidationGroupScript());
}
public void RegisterControl(LinkButton button)
{
button.Attributes.Add("onclick",GetValidationGroupScript());
}
public bool IsValid
{
get
{
return CheckValidators(this);
}
}
bool CheckValidators(Control c)
{
bool isValid = true;
foreach(Control childControl in c.Controls)
{
if (childControl is BaseValidator && childControl.Visible)
{
BaseValidator validator = (BaseValidator)childControl;
if (validator.Enabled)
{
isValid &= validator.IsValid;
}
}
else
{
if (childControl is INamingContainer && childControl.Visible)
{
isValid &= CheckValidators(childControl);
}
}
}
return isValid ;
}
void RegisterValidators(Control c)
{
foreach(Control childControl in c.Controls)
{
if (childControl is BaseValidator && childControl.Visible)
{
Page.RegisterArrayDeclaration(ClientID + "_Validators",
string.Format("document.all['{0}']",childControl.ClientID));
Page.RegisterArrayDeclaration(ClientID + "_InitialEnabled",
((BaseValidator)childControl).Enabled.ToString().ToLower());
}
else
{
if (childControl is INamingContainer && childControl.Visible)
{
RegisterValidators(childControl);
}
}
}
}
}
}
Кроме того, как видно из кода, клиентский скрипт был вынесен в ресурсный файл <script language="javascript">
function EnableValidationGroup( activeValidators, initialValues ) {
// Если на странице нет валидаторов то ничего не делаем
if (typeof(Page_Validators)=='undefined') return;
//Выключаем все валидаторы
for( i = 0; i < Page_Validators.length; i++ )
Page_Validators[i].enabled = false;
if (typeof(activeValidators)=='undefined') return;
//Включаем нужные нам валидаторы
for( i = 0; i < activeValidators.length; i++ )
activeValidators[i].enabled = initialValues[i];
}
</script>
Ну и в конце, приведу пример использования нашего элемента управления в aspx страничке. <%@ Page %>
<%@ Register tagPrefix="ej" Namespace="TestWebControls" Assembly="TestWebControls"%>
<%@ Import Namespace="System.Collections"%>
<head>
<script runat="server" language="c#">
void Page_Load(object sender, EventArgs e) {
_group1.RegisterControl(_loginButton);
_group2.RegisterControl(_postButton);
}
void OnLoginButtonClick(object sender, EventArgs e) {
if (!_group1.IsValid) {
return;
}
Response.Write("Login sucessfull");
}
void OnPostButtonClick(object sender, EventArgs e) {
if (!_group2.IsValid) {
return;
}
Response.Write("Post sucessfull");
}
</script>
</head>
<body>
<form runat="server">
<table width="100%">
<tr>
<td width="200px" valign="top">
<fieldset>
<legend>Login</legend>
<ej:ValidationGroup runat="server" id="_group1">
<table width="200">
<tr>
<td>Login:</td>
<td>
<asp:TextBox id="_loginText" runat="server" Width="150px" />
<asp:RequiredFieldValidator ErrorMessage="Login is required field"
runat="server" id="_loginRequired" Text="*"
Display="None" ControlToValidate="_loginText" />
</td>
</tr>
<tr>
<td>Password:</td>
<td><asp:TextBox id="_passwordText" TextMode="Password"
runat="server" Width="150px" />
<asp:RequiredFieldValidator ErrorMessage="Password is required field"
runat="server" id="_passwordRequired"
Text="*" Display="None" ControlToValidate="_passwordText" />
</td>
</tr>
<tr>
<td></td>
<td><asp:Button runat="server" id="_loginButton" Text="Log In"
Width="100px" OnClick="OnLoginButtonClick" /></td>
</tr>
</table>
</ej:ValidationGroup>
</fieldset>
</td>
<td width="100%">
<fieldset>
<legend>Message Post</legend>
<ej:ValidationGroup runat="server" id="_group2">
<table>
<tr>
<td>Title:</td>
<td><asp:TextBox id="_titleText" runat="server" Width="400px" />
<asp:RequiredFieldValidator ErrorMessage="Title is required field"
runat="server" id="_titleRequired" Text="*"
Display="None" ControlToValidate="_titleText" />
</td>
</tr>
<tr>
<td colspan="2">Message:</td>
</tr>
<tr>
<td colspan="2">
<asp:TextBox TextMode="MultiLine" Rows="20" id="_messageText"
runat="server" Width="600px" />
<asp:RequiredFieldValidator runat="server"
ErrorMessage="Message is required field" id="_messageRequired" Text="*"
Display="None" ControlToValidate="_messageText" />
</td>
</tr>
<tr>
<td align="right" colspan="2"><asp:Button id="_postButton"
runat="server" Text="Post" Width="100px"
OnClick="OnPostButtonClick" /></td>
</tr>
</table>
</ej:ValidationGroup>
</fieldset>
</td>
</tr>
</table>
<asp:ValidationSummary runat="server" ShowMessageBox="true" ShowSummary="false" />
</form>
</body>
Вот и все.
|