Custom TextBox with built-in Validator: server side validation not firing - asp.net

I have a class that looks like this:
public class TextField : TextBox
{
public bool Required { get; set; }
RequiredFieldValidator _validator;
protected override void CreateChildControls()
{
base.CreateChildControls();
_validator = new RequiredFieldValidator();
_validator.ControlToValidate = this.ID;
if(Required)
Controls.Add(_validator);
}
public override void Render(HtmlTextWriter tw)
{
base.Render(tw);
if(Required)
_validator.RenderControl(tw);
}
}
This has been working for a while in a internal application where javascript is always enabled. I recently noticed that an upstream javascript error can prevent the validators from firing, so the server side validation should kick in... right? right?
So the Page.IsValid property always returns true (I even tried explicitly calling Page.Validate() before-hand).
After some digging, I found that the validator init method should add the validator to the page, but due to the way I'm building it up, I don't think this ever happens. Thus, client side validation works, but server side validation does not.
I've tried this:
protected override OnInit()
{
base.OnInit();
Page.Validators.Add(_validator); // <-- validator is null here
}
But of course the validator is null here (and sometimes it's not required so it shouldn't be added)... but OnInit() is really early for me to make those decisions (the Required property won't have been loaded from ViewState for example).
Ideas?

The CreateChildControls is basically for the controls that have childs. RequiredFieldValidator is like a sibling to TextBox.
Here is the code that works for me:
public class RequiredTextBox : TextBox
{
private RequiredFieldValidator _req;
private string _errorMessage;
public string ErrorMessage
{
get { return _errorMessage; }
set { _errorMessage = value; }
}
protected override void OnInit(EventArgs e)
{
_req = new RequiredFieldValidator();
_req.ControlToValidate = this.ID;
_req.ErrorMessage = _errorMessage;
Controls.Add(_req);
base.OnInit(e);
}
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
base.Render(writer);
_req.RenderControl(writer);
}
}
And here it the ASP.NET page behind:
protected void SubmitClick(object sender, EventArgs e)
{
if(Page.IsValid)
{
// do something
}
}
And here is the ASPX code:
<MyControl:RequiredTextBox runat="server" ErrorMessage="Name is required!" ID="txtName"></MyControl:RequiredTextBox>
<asp:Button ID="Btn_Submit" runat="server" Text="Submit" OnClick="SubmitClick" />

Validators have to inherit from BaseValidator.

Related

How to assign the value of user control property to aspx or codebehind in VB?

I have a user control with a public property which updates each time when a date from my calender(part of user control) is selected. Now I need to bring this value to page on which this user control is kept. How to do this.
I tried bringing the property value on page load event of aspx.vb(master page on which user control is present) but couldn't do it as page load is happening first and user property is loading next(null reference exception).
i tried this on page load of aspx hdnPPSeq.Value = PPCalender1.test1.ToString
Please share ideas to bring this value to aspx or codebehind in vb.
Create a method in usercontrol, which will return property value.
public partial class PassPropertyToPage : System.Web.UI.UserControl
{
string strSelectDateTime;
public string SelectedDateTime
{
set { strSelectDateTime = value; }
get { return strSelectDateTime; }
}
protected void Page_Load(object sender, EventArgs e){}
public string GetDateTime()
{
strSelectDateTime = <calendar value>;
return strSelectDateTime;
}
}
And in page, call the method to get the value:
public partial class AccessUserControlProperty : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Response.Write("DateTime selected in page: " + PassPropertyToPage1.GetDateTime() + "<br/>");
}
}

Dynamic Control creation, event handling and control properties in asp.net

I am trying to solve the following issue:
I have a user control that needs to be dynamically loaded inside another control. This dynamically loaded control raises an event and as per my knowledge the events raised by dynamically loaded control will only be handled correctly if the control is created and loaded during the onload event. There is one more constraint that i have to consider when loading the control dynamically and that is a property in parent control. This property will determine if the control should be loaded or not.
Pseudo Code:
ControlA
Property ShowControl
ControlA has a CheckBox(chkShowControlIfSelected)
OnLoadEvent()
If chkShowControlIfSelected.checked checked and ShowControlProperty is set
{
reate ControlB Dynamically
ControlB.Event += EventHandler()
Add ControlB to ControlCollection
}
The problem i am running into is that if I include the code to load the controlB in prerender event then the property ShowControl is set correctly but the EventHandler() is not called. If I put the code to load the controlB dynamically in pageLoad event then property ShowControl is not yet set but in that case the eventHandler Code is called correctly.
Am i missing something or handling the code in incorrect event handlers?
Following is the working example:
ControlA:
public partial class ControlA : System.Web.UI.UserControl
{
public bool ShowControl
{
get
{
if (this.ViewState["ShowControl"] == null)
return false;
else
return (bool)this.ViewState["ShowControl"];
}
set
{
this.ViewState["ShowControl"] = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (this.ShowControl)
{
var controlB = (ControlB)this.LoadControl("ControlB.ascx");
controlB.FileUploadingComplete += controlB_FileUploadingComplete;
this.pnl1.Controls.Add(controlB);
}
}
void controlB_FileUploadingComplete(object sender, EventArgs e)
{
//throw new NotImplementedException();
Trace.Write("file upload completed");
}
}
ControlB:
public partial class ControlB : System.Web.UI.UserControl
{
public event EventHandler FileUploadingComplete;
protected void OnFileUploadingComplete()
{
if (this.FileUploadingComplete != null)
this.FileUploadingComplete(this, EventArgs.Empty);
}
protected void btn1_Click(object sender, EventArgs e)
{
this.OnFileUploadingComplete();
}
}
Page (has ControlA present):
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
this.ControlA1.ShowControl = true;
}
}

textBox onBlur to call server method instead of client method

I'm extending a web control. I need to call server methods on every event fired by the control instead of javascript.
public partial class MyTextBox : RadTextBox, IScriptControl
{
public MyTextBox()
{
Attributes.Add("onBlur", "handleLostFocus();");
Attributes.Add("runat", "server");
}
public void handleLostFocus()
{
MyObject obj = new MyObject();
obj.someproperty = this.Text; //or somehow get the user entered text.
MyService1 service = new MyService1();
service.sendRequest(obj);
}
}
As I said in my comment, TextBox will post by default if AutoPostBack = "True", however, you need to handle your event. Supposing your TextBox is named TextBox1:
protected void TextBox1_TextChanged(object sender, EventArgs e)
{
string str = TextBox1.Text;
}
Get rid of handleLostFocus() or have it be the handler for your TextBox control.
Good luck mate.

passing a value to WebUserControl for show in a lable

hi
i have a WebUserControl that have a lable for show message
how can i send a value to the lable from Page to my WebUserControl at runtime.
In the code behind file of your control you can specify an attribute
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(true)]
public String customType
{
get
{
String s = (String)ViewState["customType"];
return ((s == null) ? String.Empty : s);
}
set
{
ViewState["customType"] = value;
}
}
And after you can get this attribute to fill your label in the pageload with
mylabel.text = mycontrol.customType
In the asp page you specify the attribute (here is the 'customType'):
<wuc:ContSign customType="person" ID="ContSignPanel" runat="server" />
MSDN
You can create a public method in your user control such as
public void ShowMessage(string message)
{
Label1.Text = message;
}
Label1 being the label control in user control. Now you can use the method from Page as and when you need it - for example,
protected void Page_Load(object Sender, EventArgs e)
{
MyUserControl1.ShowMessage("Hello");
}
where MyUserControl1 is the name/ID of web user control put on the page.
just make a property to get and set values for the lable in the user control
private string _labelmsg;
public string LableMsg
get
{
return _labelmsg;
}
set
{
_labelmsg=lblID.Text;
}
and then set in the aspx.cs page like
UserControlID.LabelMsg="Set Any Value";

ASP CompositeControl & ScriptManager

I'm really new to the WebControl / CompositeControl world, and I have a small test class I am playing with. It's just a LinkButton that updates when clicked. Things work great when I leave it out of UpdatePanel. But when I try to run it inside I still get a full page POST response. How can I make this class work inside a UpdatePanel?
Here's the class:
public class Test2 : CompositeControl
{
private static readonly object testButtonEvent = new object();
public event EventHandler OnTestClick
{
add { Events.AddHandler(testButtonEvent, value); }
remove { Events.RemoveHandler(testButtonEvent, value); }
}
private LinkButton testLinkButton;
public virtual string testLinkButtonText
{
get
{
object o = ViewState["testLinkButtonText"];
return (o == null) ? String.Empty : (string)o;
}
set
{
if (value == null)
ViewState.Remove("testLinkButtonText");
else
ViewState["testLinkButtonText"] = value;
}
}
protected override void OnInit(EventArgs e)
{
/* This stuff makes it ajax friendly but stops the text rendering
EnsureChildControls();
ScriptManager ScMan = ScriptManager.GetCurrent(Page);
if (ScMan != null)
{
ScMan.RegisterAsyncPostBackControl(testLinkButton);
} */
base.OnInit(e);
}
protected override void CreateChildControls()
{
Controls.Clear();
testLinkButton = new LinkButton();
testLinkButton.Command += new CommandEventHandler(testClick);
testLinkButtonText = "Test ViewState Text";
Controls.Add(testLinkButton);
}
void testClick(object sender, CommandEventArgs e)
{
testLinkButtonText = "Updated Text On " + DateTime.Now.ToLongTimeString();
}
protected override void Render(HtmlTextWriter writer)
{
RenderContents(writer);
}
protected override void RenderContents(HtmlTextWriter writer)
{
EnsureChildControls();
testLinkButton.Text = testLinkButtonText;
testLinkButton.RenderControl(writer);
}
}
The code in OnInit() causes the control to post correctly, but I don't get the updated text for the LinkButton. It is still firing off the event - when I debug I can see it being called. What's the proper way to set this control up for use in a UpdatePanel?
Usage, just in case:
<asp:UpdatePanel runat="server" UpdateMode="Conditional">
<ContentTemplate>
<cc:Test2 ID="jqTest02" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
You have to give the button an ID property...this is used in the client-side javascript that drives the UpdatePanel. More specifically, it's listed in the list of controls to intercept and do async postbacks for.
testLinkButton.ID = "btn";

Resources