Jag har byggt en klass med lite egna valideringskontroller som ärver BasValidator. Här kommer "lite" kod Page.Parent.Validate() ??? Sidan finns ju inte i det nuvarande objektet eftersom du befinner dig i en kontroll. Eller så. det är lite rörigt. Page.Parent.Validate var bar en test eftesom Page.Validate Ej fungerade, glömde att ta bort. Eftersom det är så mkt kod så orkar jag inte gå genom den, kan du skicka in hela ditt felmedenande här? -> Det har inte löst sig :-( Felet ligger i din EvaluateIsValid() metod. Hur förklarar du att det första exemplet fungerar (kolla URL:arna ovan, hmm ibland är det svårt med svengelskan). Båda exempel är identiskt uppbyggda i formuläret med samma valideringskontroller mm. Är koden exakt identisk under båda URL:erna? Du kör völ en med kontrol och en utan? Jo, men jag menar själva formulärkoden. I det första exemplet ligger formuläret i .aspx-sidan och i andra exemplet ligger det i .ascx-kontrollen. Skillnaden är att när du kör all kod i din aspx sida (din första URL) så kommer metoden FindControl leta i Page objektet. Men kör du i FindControl i en custom controll så kommer FindControl att enbart leta bland kontrollens kontroller. Som vanligt, allt är SÅ lätt när man kan det. Binda klass till anpassad kontroll
Klassen är kompilerad.
Om jag kör detta på en vanlig .aspx-sida med codebehind fungerar allt perfekt med Page.Validate() men nu är det såhär: I min .aspx-sida inkluderar jag dynamiskt .ascx-kontroller. Jag registrerar klassens tagprefix mm i dessa kontroller istället för i .aspx-sidan. Problemet är att när jag nu kör Page.Validate() får jag ett system.nullreferenceexception, varför och hur kan jag lösa detta?
Exempel:
Fungerar, aspx-sida + codebehind
http://www.skadebas.com/test/testvalidatorcontrols.aspx
Fungerar EJ, aspx-sida som inkluderar en ascx-kontroll med codebehind
http://www.skadebas.com/test/testvalidatorcontrolsinusercontrol.aspx
Tackar på förhand!Sv: Binda klass till anpassad kontroll
KLASSEN
*******
<code>
Imports System
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports Microsoft.VisualBasic
Imports System.Text.RegularExpressions
Imports System.Collections.Specialized
Namespace ValidatorControls
#Region " KLASS: KONTROLLERAR ATT TEXBOX EJ ÄR TOM "
Public Class RequiredTextBoxValidator : Inherits BaseValidator
'--> Deklarerar klass-globala variabler
Private objControlToValidate As TextBox
Private strErrorMessage As String
Private strInput As String
Private pnlClientMessage As Panel
#Region " FUNKTION (ControlPropertiesValid()): Letar upp kontroll som skall valideras "
Protected Overrides Function ControlPropertiesValid() As Boolean
'--> Deklarerar kontroll-variabel
Dim ValidatorControl As Control
'--> Letar upp kontroll som skall valideras
ValidatorControl = FindControl(ControlToValidate)
'--> Letar upp meddelande-ruta-kontroll
pnlClientMessage = FindControl("pnlClientMessage")
'--> Kontroll hittad
If Not (ValidatorControl Is Nothing) Then
'--> Tilldelar klass-globala variabler värden
objControlToValidate = ValidatorControl
strInput = objControlToValidate.Text.ToString
strErrorMessage = ErrorMessage
Return True
'--> Ingen kontroll hittades
Else
Return False
End If '//f Not (ValidatorControl Is Nothing)
End Function
#End Region
#Region " FUNKTION (EvaluateIsValid()): Kontrollerar om kontrollen är godkänd eller ej "
Protected Overrides Function EvaluateIsValid() As Boolean
'--> Deklarerar variabel samt förutsätter
' att fel kommer att hittas
Dim boolIsValid As Boolean = False
'--> Om inte kontrollen är tom, allt OK
If Not (strInput.Trim = "") Then
'--> Om endast panelen innehåller rubrik-kontroll
' tilldelas den en ny Css-klass som gömmer panelen
If (pnlClientMessage.Controls.Count = 1) Then
pnlClientMessage.CssClass = "NoMessage"
End If
'--> Booleanskt värde: Allt OK
boolIsValid = True
'--> Kontrollen tom
Else
'--> Tlldelar panelen ny klass
pnlClientMessage.CssClass = "InfoMessage"
'--> Adderar ny literal-kontroll (felmeddelande)
pnlClientMessage.Controls.Add(New LiteralControl("» " & strErrorMessage & "<br>"))
End If
'--> Returnerar valideringsvärde
Return boolIsValid
End Function
#End Region
End Class
#End Region
#Region " KLASS : KONTROLLERAR ATT TEXBOX ENDAST INNEHÅLLER SIFFROR "
Public Class IsNumericValidator : Inherits BaseValidator
'--> Deklarerar klass-globala variabler
Private objControlToValidate As TextBox
Private strErrorMessage As String
Private strInput As String
Private pnlClientMessage As Panel
#Region " FUNKTION (ControlPropertiesValid()): Letar upp kontroll som skall valideras "
Protected Overrides Function ControlPropertiesValid() As Boolean
'--> Deklarerar kontroll-variabel
Dim ValidatorControl As Control
'--> Letar upp kontroll som skall valideras
ValidatorControl = FindControl(ControlToValidate)
'--> Letar upp meddelande-ruta-kontroll
pnlClientMessage = FindControl("pnlClientMessage")
'--> Kontroll hittad
If Not (ValidatorControl Is Nothing) Then
'--> Tilldelar klass-globala variabler värden
objControlToValidate = ValidatorControl
strInput = objControlToValidate.Text.ToString
strErrorMessage = ErrorMessage
Return True
'--> Ingen kontroll hittades
Else
Return False
End If '//f Not (ValidatorControl Is Nothing)
End Function
#End Region
#Region " FUNKTION (EvaluateIsValid()): Kontrollerar om kontrollen är godkänd eller ej "
Protected Overrides Function EvaluateIsValid() As Boolean
'--> Deklarerar variabel samt förutsätter
' att fel kommer att hittas
Dim boolIsValid As Boolean = False
'--> Om allt OK
If IsNumeric(strInput.Trim) Then
'--> Om endast panelen innehåller rubrik-kontroll
' tilldelas den en ny Css-klass som gömmer panelen
If (pnlClientMessage.Controls.Count = 1) Then
pnlClientMessage.CssClass = "NoMessage"
End If
'--> Booleanskt värde: Allt OK
boolIsValid = True
'--> Fel hittat
Else
'--> Tlldelar panelen ny klass
pnlClientMessage.CssClass = "InfoMessage"
'--> Adderar ny literal-kontroll (felmeddelande)
pnlClientMessage.Controls.Add(New LiteralControl("» " & strErrorMessage & "<br>"))
End If
'--> Returnerar valideringsvärde
Return boolIsValid
End Function
#End Region
End Class
#End Region
#Region " KLASS: KONTROLLERAR ATT TEXTBOX INNEHÅLLER PERSONUPPGIFTER I RÄTT FORMAT EX: 123456-1234 "
Public Class OrgNoValidator_SWE : Inherits BaseValidator
'--> Deklarerar klass-globala variabler
Private objControlToValidate As TextBox
Private strErrorMessage As String
Private strInput As String
Private pnlClientMessage As Panel
#Region " FUNKTION (ControlPropertiesValid()): Letar upp kontroll som skall valideras "
Protected Overrides Function ControlPropertiesValid() As Boolean
'--> Deklarerar kontroll-variabel
Dim ValidatorControl As Control
'--> Letar upp kontroll som skall valideras
ValidatorControl = FindControl(ControlToValidate)
'--> Letar upp meddelande-ruta-kontroll
pnlClientMessage = FindControl("pnlClientMessage")
'--> Kontroll hittad
If Not (ValidatorControl Is Nothing) Then
'--> Tilldelar klass-globala variabler värden
objControlToValidate = ValidatorControl
strInput = objControlToValidate.Text.ToString
strErrorMessage = ErrorMessage
Return True
'--> Ingen kontroll hittades
Else
Return False
End If '//f Not (ValidatorControl Is Nothing)
End Function
#End Region
#Region " FUNKTION (EvaluateIsValid()): Kontrollerar om kontrollen är godkänd eller ej "
Protected Overrides Function EvaluateIsValid() As Boolean
'--> Deklarerar variabel samt förutsätter
' att fel kommer att hittas
Dim boolIsValid As Boolean = False
'--> Deklarerar regexpression
Dim objRegEx As Regex
objRegEx = New Regex("[0-9]{6}-[0-9]{4}")
'--> Deklarearar variabel samt kontrollerar
' textBox-värdet mot regexpression
Dim boolCheckExpression As Boolean = objRegEx.IsMatch(strInput.Trim)
'--> Om allt OK
If (boolCheckExpression) Then
'--> Om endast panelen innehåller rubrik-kontroll
' tilldelas den en ny Css-klass som gömmer panelen
If (pnlClientMessage.Controls.Count = 1) Then
pnlClientMessage.CssClass = "NoMessage"
End If
'--> Booleanskt värde: Allt OK
boolIsValid = True
'--> Fel hittat
Else
'--> Tlldelar panelen ny klass
pnlClientMessage.CssClass = "InfoMessage"
'--> Adderar ny literal-kontroll (felmeddelande)
pnlClientMessage.Controls.Add(New LiteralControl("» " & strErrorMessage & "<br>"))
End If
'--> Returnerar valideringsvärde
Return boolIsValid
End Function
#End Region
End Class
#End Region
#Region " KLASS: KONTROLLERAR ATT TEXTBOX INNEHÅLLER E-POSTADRESS I RÄTT FORMAT EX: adam@skadebas.com "
Public Class EmailValidator : Inherits BaseValidator
'--> Deklarerar klass-globala variabler
Private objControlToValidate As TextBox
Private strErrorMessage As String
Private strInput As String
Private pnlClientMessage As Panel
#Region " FUNKTION (ControlPropertiesValid()): Letar upp kontroll som skall valideras "
Protected Overrides Function ControlPropertiesValid() As Boolean
'--> Deklarerar kontroll-variabel
Dim ValidatorControl As Control
'--> Letar upp kontroll som skall valideras
ValidatorControl = FindControl(ControlToValidate)
'--> Letar upp meddelande-ruta-kontroll
pnlClientMessage = FindControl("pnlClientMessage")
'--> Kontroll hittad
If Not (ValidatorControl Is Nothing) Then
'--> Tilldelar klass-globala variabler värden
objControlToValidate = ValidatorControl
strInput = objControlToValidate.Text.ToString
strErrorMessage = ErrorMessage
Return True
'--> Ingen kontroll hittades
Else
Return False
End If '//f Not (ValidatorControl Is Nothing)
End Function
#End Region
#Region " FUNKTION (EvaluateIsValid()): Kontrollerar om kontrollen är godkänd eller ej "
Protected Overrides Function EvaluateIsValid() As Boolean
'--> Deklarerar variabel samt förutsätter
' att fel kommer att hittas
Dim boolIsValid As Boolean = False
'--> Deklarerar regexpression
Dim objRegEx As Regex
objRegEx = New Regex("^[\w-\.]+@([\w-]+\.)+[\w-]{2,3}$")
'--> Deklarearar variabel samt kontrollerar
' textBox-värdet mot regexpression
Dim boolCheckExpression As Boolean = objRegEx.IsMatch(strInput.Trim)
'--> Om allt OK
If (boolCheckExpression) Then
'--> Om endast panelen innehåller rubrik-kontroll
' tilldelas den en ny Css-klass som gömmer panelen
If (pnlClientMessage.Controls.Count = 1) Then
pnlClientMessage.CssClass = "NoMessage"
End If
'--> Booleanskt värde: Allt OK
boolIsValid = True
'--> Fel hittat
Else
'--> Tlldelar panelen ny klass
pnlClientMessage.CssClass = "InfoMessage"
'--> Adderar ny literal-kontroll (felmeddelande)
pnlClientMessage.Controls.Add(New LiteralControl("» " & strErrorMessage & "<br>"))
End If
'--> Returnerar valideringsvärde
Return boolIsValid
End Function
#End Region
End Class
#End Region
#Region " KLASS: KONTROLLERAR ATT EN OPTION HAR VALTS I DROPDOWNLIST "
Public Class RequiredDropDownListValidator : Inherits BaseValidator
'--> Deklarerar klass-globala variabler
Private objControlToValidate As DropDownList
Private strErrorMessage As String
Private intInput As Integer
Private pnlClientMessage As Panel
#Region " FUNKTION (ControlPropertiesValid()): Letar upp kontroll som skall valideras "
Protected Overrides Function ControlPropertiesValid() As Boolean
'--> Deklarerar kontroll-variabel
Dim ValidatorControl As Control
'--> Letar upp kontroll som skall valideras
ValidatorControl = FindControl(ControlToValidate)
'--> Letar upp meddelande-ruta-kontroll
pnlClientMessage = FindControl("pnlClientMessage")
'--> Kontroll hittad
If Not (ValidatorControl Is Nothing) Then
'--> Tilldelar klass-globala variabler värden
objControlToValidate = ValidatorControl
intInput = objControlToValidate.SelectedIndex.ToString
strErrorMessage = ErrorMessage
Return True
'--> Ingen kontroll hittades
Else
Return False
End If '//f Not (ValidatorControl Is Nothing)
End Function
#End Region
#Region " FUNKTION (EvaluateIsValid()): Kontrollerar om kontrollen är godkänd eller ej "
Protected Overrides Function EvaluateIsValid() As Boolean
'--> Deklarerar variabel samt förutsätter
' att fel kommer att hittas
Dim boolIsValid As Boolean = False
'--> Om inte kontrollen är tom, allt OK
If Not (intInput = 0) And Not IsNothing(intInput) Then
'--> Om endast panelen innehåller rubrik-kontroll
' tilldelas den en ny Css-klass som gömmer panelen
If (pnlClientMessage.Controls.Count = 1) Then
pnlClientMessage.CssClass = "NoMessage"
End If
'--> Booleanskt värde: Allt OK
boolIsValid = True
'--> Kontrollen tom
Else
'--> Tlldelar panelen ny klass
pnlClientMessage.CssClass = "InfoMessage"
'--> Adderar ny literal-kontroll (felmeddelande)
pnlClientMessage.Controls.Add(New LiteralControl("» " & strErrorMessage & "<br>"))
End If
'--> Returnerar valideringsvärde
Return boolIsValid
End Function
#End Region
End Class
#End Region
End Namespace
</code>
ASPX-SIDAN
**********
<code>
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="TestValidatorControlsInUserControl.aspx.vb" Inherits="skadebas.TestValidatorControlsInUserControl"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>TestValidatorControlsInUserControl</title>
<link rel="stylesheet" type="text/css" href="/SB_System/SB_CSS/default_frames_IE.css">
<script language="javascript" src="/SB_System/SB_Scripts/SB_Javascripts/shared.js"></script>
</head>
<body onload="handleBodyLayers();" onresize="handleBodyLayers();">
<form id="Form1" action="usercontrol.ascx" method="post" runat="server">
<!-- START KLIENTMEDDELENDE -->
<asp:Panel ID="pnlClientMessage" Runat="server" CssClass="NoMessage"><strong>Följande fel påträffades:</strong><br></asp:Panel>
<!-- SLUT KLIENTMEDDELENDE -->
<!-- START SIDINNEHÅLL -->
<asp:Panel ID="pnlBodyContainer" Runat="server">
</asp:Panel>
<!-- SLUT SIDINNEHÅLL -->
</form>
</body>
</html>
</code>
CODEBEHIND FÖR ASPX-SIDAN
*************************
<code>
Public Class TestValidatorControlsInUserControl
Inherits System.Web.UI.Page
Protected WithEvents pnlClientMessage As Panel
Protected WithEvents pnlBodyContainer As Panel
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
End Sub
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'--> Initierar meddelanderuta
pnlClientMessage = Page.FindControl("pnlClientMessage")
'--> Adderar usercontrol till panel
pnlBodyContainer.Controls.Add(Page.LoadControl("UserControl.ascx"))
End Sub
Sub Submit(ByVal Obj As Object, ByVal EA As EventArgs)
Page.Validate()
If (Page.IsValid) Then
pnlClientMessage.Controls.Item(0).Visible = False
pnlClientMessage.Controls.Add(New LiteralControl("Formuläret har validerats"))
pnlClientMessage.CssClass = "ConfirmMessage"
End If
End Sub
End Class
</code>
ASCX-KONTROLLEN
****************
<code>
<%@ Control Language="vb" AutoEventWireup="false" Codebehind="UserControl.ascx.vb" Inherits="skadebas.UserControl" TargetSchema="http://schemas.microsoft.com/intellisense/ie5" %>
<%@ Register TagPrefix="SkadeBas" NameSpace="ValidatorControls" Assembly="ValidatorControls" %>
Förnamn:<asp:TextBox ID="tbFirstName" Runat="server"/>
<SkadeBas:RequiredTextBoxValidator ID="rtbv_tbFirstName" Runat="server" ControlToValidate="tbFirstName" Text="*" ErrorMessage="Förnamn får ej vara tomt"/>
<br>
Efternamn:<asp:TextBox ID="tbLastName" Runat="server"/>
<SkadeBas:RequiredTextBoxValidator ID="rtbv_tbLastName" Runat="server" ControlToValidate="tbLastName" Text="*" ErrorMessage="Efternamn får ej vara tomt"/>
<br>
Personnummer:<asp:TextBox ID="tbOrgNo" Runat="server" MaxLength="11"/>
<SkadeBas:OrgNoValidator_SWE ID="on_tbOrgNo" Runat="server" ControlToValidate="tbOrgNo" Text="*" ErrorMessage="Personnummer måste vara i formatet: 123456-1234"/>
<br>
Siffror:<asp:TextBox ID="tbNumbers" Runat="server"/>
<SkadeBas:IsNumericValidator ID="is_tbNumbers" Runat="Server" ControlToValidate="tbNumbers" Text="*" ErrorMessage="Siffror får endast innehålla siffror"/>
<br>
Välj stad:
<asp:DropDownList ID="ddlCities" Runat="server">
<asp:ListItem Value="">-- Välj stad --</asp:ListItem>
<asp:ListItem Value="1">Arboga</asp:ListItem>
<asp:ListItem Value="2">Björknäs</asp:ListItem>
<asp:ListItem Value="3">Stockholm</asp:ListItem>
</asp:DropDownList>
<SkadeBas:RequiredDropDownListValidator ID="rddlv_ddlCities" Runat="Server" ControlToValidate="ddlCities" Text="*" ErrorMessage="Du måste välja en av städerna"/>
<br>
E-post: <asp:TextBox ID="tbEmail" Runat="server"/>
<SkadeBas:EmailValidator ID="ev_tbEmail" Runat="server" ControlToValidate="tbEmail" Text="*" ErrorMessage="Du angav ingen riktig e-postadress"/>
<br>
<asp:Button Runat="server" Text="Skicka" OnClick="Submit" CausesValidation="False" ID="Button1"/>
</p>
</code>
CODEBEHIND FÖR ASCX-KLASS
<code>
Public MustInherit Class UserControl
Inherits System.Web.UI.UserControl
Protected WithEvents pnlClientMessage As Panel
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
End Sub
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'--> Initierar meddelanderuta
pnlClientMessage = Page.FindControl("pnlClientMessage")
End Sub
Sub Submit(ByVal Obj As Object, ByVal EA As EventArgs)
Page.Validate()
If (Page.IsValid) Then
pnlClientMessage.Controls.Item(0).Visible = False
pnlClientMessage.Controls.Add(New LiteralControl("Formuläret har validerats"))
pnlClientMessage.CssClass = "ConfirmMessage"
End If
End Sub
End Class
</code>Sv: Binda klass till anpassad kontroll
I vilket fall som helst ska du npg genast göra lite ändringar i din web.config-fil. Jag fick upp hela felmeddelandet på din sida som du länkade till. Kanske du specifikt sett till att det är så men om inte så kan jag garantera dig att det kraschar då du ska göra en databaskoppling och HEPP där ligger lösenordet i klartext!!!
Sök på "<customErrors> element" i din dokumentation eller på MSDN för närmare information.
vad du behöver göra är att ge användaren en annan sida som felhantering och sen konfigurera så att du och utvecklingsdatorn får all information. Det är ganska smart tänkt av MS.
//Mikael.NETSv: Binda klass till anpassad kontroll
Jag har testat applikationen från flera olika platser och ej haft några problem med databaskopplingen med jag skall titta närmare på det här med <customErrors>
Tack!Sv: Binda klass till anpassad kontroll
Då du verkar hanteradet på ett annat sätt. kan ge dig ett tips. KÖR inte med <customError> och hantera ditt fel i bakgrunden så länge du sitter och utvecklar. Detta är något du bör slå på i din release istället. Varför orkar jag inte gå in på.
Har det löst sig annars? Har du kört step by debugging?
//Johan NSv: Binda klass till anpassad kontroll
-> Jag har aldrig användt mig av step by debugging, hur?
-> Här kommer alla felmeddelanden på en o samma gång //Christer Gessle
Server Error in '/' Application.
--------------------------------------------------------------------------------
Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
Source Error:
Line 25:
Line 26: Sub Submit(ByVal Obj As Object, ByVal EA As EventArgs)
Line 27: Page.Validate()
Line 28: If (Page.IsValid) Then
Line 29: pnlClientMessage.Controls.Item(0).Visible = False
Source File: \\webserver\webs\skadebas\test\UserControl.ascx.vb Line: 27
Stack Trace:
[NullReferenceException: Object reference not set to an instance of an object.]
ValidatorControls.RequiredTextBoxValidator.EvaluateIsValid() +94
System.Web.UI.WebControls.BaseValidator.Validate() +138
System.Web.UI.Page.Validate() +234
skadebas.UserControl.Submit(Object Obj, EventArgs EA) in \\webserver\webs\skadebas\test\UserControl.ascx.vb:27
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +108
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +57
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +18
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33
System.Web.UI.Page.ProcessRequestMain() +1244
Sv: Binda klass till anpassad kontroll
I din EvalutateIsValid metod så har du två fall som kan ge "Object reference not set to an instance of an object"
det första är strInput.Trim om strInput inte innehåller något värde alltså är null, så kan du inte köra Trim.
Om nu strInput inte skulle vara null se då till att kontrollera så att inte pnlClientMessage är null.
/Fredrik NorménSv: Binda klass till anpassad kontroll
Sv: Binda klass till anpassad kontroll
//Johan NSv: Binda klass till anpassad kontroll
Sv: Binda klass till anpassad kontroll
I din ControlPropertiesValid() ändra följande:
<code>
FindControl("pnlClientMessage")
</code>
till
<code>
Page.FindControl("pnlClientMessage")
</code>
/Fredrik NorménSv: Binda klass till anpassad kontroll
Tusen tack ALLA för hjälpen!!!