I am making a custom web control for my ASP page that inherits from CompositeDataBoundControl. I have a public property in the definition of my control that is required, if the user does not provide this property in the control definition on an ASP page it will break and we will get an exception. I want the compiler to throw a warning similar to the one when a user forgets to provide the 'runat' property of a Control.
"Validation (ASP.Net): Element 'asp:Button' is missing required attribute 'runat'."
Here is basically what my code looks like:
public class MyControl : CompositeDataBoundControl, IPostBackEventHandler
{
private string _someString;
public string SomeString
{
get { return _someString; }
set { _someString = value; }
}
// Other Control Properties, Functions, Events, etc.
}
I want "SomeString" to be a required property and throw a compiler warning when I build my page.
I have tried putting a Required attribute above the property like so:
[Required]
public string SomeString
{
get { return _someString; }
set { _someString = value; }
}
but this doesnt seem to work.
How can I generate such a compiler message?
Thats quite simple, on page load you can check if the property has some value or not. You can check it for Null or Empty case depending on your property type.
like if i have this
private string _someString;
public string SomeString
{
get { return _someString; }
set { _someString = value; }
}
On page_load event i will check if
if(_someString != null && _someString != "")
{
String message = "Missing someString property";
isAllPropertySet = false; //This is boolean variable that will decide whether any property is not left un-initialised
}
All The Best.
and finally
Related
Newbie here, I need help with a website I'm creating.
I have a class that does some analysis on some text that is input by the user, the class then finds an appropriate answer and sends it back to the textbox. (in theory)
Problem is I don't know how I can control and access the textbox on the default.aspx page from a class, all I get is "object reference is required non static field".
I made the textbox public in the designer file yet still no joy. :(
I've also read this: How can I access the controls on my ASP.NET page from a class within the solution? , which I think is along the lines of what I'm trying to achieve but I need clarification/step by step on how to achieve this.
Hope someone can point me in the right direction.
Many thanks,
Kal
This is the code I have added to the designer.cs file:
public global::System.Web.UI.WebControls.TextBox TextBox3;
public string MyTextBoxText
{
get
{
return TextBox3.Text;
}
set
{
TextBox3.Text = value;
}
}
This is the class method i have created:
public static cleanseMe(string input)
{
string utterance = input;
string cleansedUtt = Regex.Replace(utterance, #"[!]|[.]|[?]|[,]|[']", "");
WebApplication1._Default.TextBox3.text = cleansedUtt;
}
I could just return the cleansedUtt string i know, but is it possible for me to just append this string to the said textbox from this method, within this class?
I also tried it this way, i wrote a class that takes in the name of the textbox and string to append to that textbox. it works BUT only on the default.aspx page and does not recognise the textbox names within the difference classes. The code is as follows:
public class formControl
{
public static void ModifyText(TextBox textBox, string appendthis)
{
textBox.Text += appendthis + "\r\n";
}
I would suggest you that do not access the Page Controls like TextBox in your class. It will be more useful and a good practice that whatever functionality your class does, convert them into function which accept the parameters and returns some value and then on the basis of that value you can set the controls value.
So now you have reusable function that you can use from any of the page you want. You do not need to write it for every textbox.
Here I am giving you a simple example
public class Test
{
public bool IsValid(string value)
{
// Your logic
return true;
}
}
Now you can use it simple on your page like this
Test objTest = new Test();
bool result=objTest.IsValid(TextBox1.Text);
if(result)
{
TextBox1.Text="Everything is correct";
}
else
{
TextBox1.Text="Something went wrong";
}
If you have your class in the same project (Web Project) the following will work:
public class Test
{
public Test()
{
//
// TODO: Add constructor logic here
//
}
public static void ValidateTextBox(System.Web.UI.WebControls.TextBox txt)
{
//validation logic here
if (txt != null)
txt.Text = "Modified from class";
}
}
You can use this from your webform like this:
protected void Page_Load(object sender, EventArgs e)
{
Test.ValidateTextBox(this.txt);
}
If your class is in a different (class project), you would need to add a reference to System.Web to your project.
I am trying to pass a few parameters between two web pages
within the source page I have the following properties
private string _testString { get; set; }
public string TestString
{
get
{
return _testString;
}
}
In previous msdn examples the return type was always set to a UI element (textbox.text)
However I am trying to pass the value from a dynamically generated link button which is why I chose to use the private accessor
In the click event of the link button on the source page I have the following:
protected void RenderReportInNewPage(LinkButton lb)
{
_testString = lb.CommandArgument.ToString();
Response.BufferOutput = true;
Response.Redirect("~/stuff/testviewer.aspx");
}
On the target page I have the source page referenced in the aspx as follows:
<%# PreviousPageType VirtualPath="~/stuff/testviewer.aspx"%>
And then in the codebehind of the target page I have the following:
Textbox.Text = PreviousPage.TestString;
PreviousPage displays the public property TestString but it is always null (as I don't think it is getting set but not sure why)
Is is possible to set a private accessor (_teststring) and have that value reflected within the public property? I'd appreciate any suggestions on what I have done wrong.
-Cheers
Found the error. It was not in the setting of the property but in how I was invoking the target page. In order to pass the properties across I needed to user Server.Transfer instead of Response.Redirect
protected void RenderReportInNewPage(LinkButton lb)
{
_testString = lb.CommandArgument.ToString();
Response.BufferOutput = true;
Server.Transfer("~/ReportBuilder/viewer.aspx");
}
-cheers
I'm trying to figure out how to create a web server control which is basically an ExpandoObject.
The desire is to automatically create a property on the control when it is created in the aspx markup.
For example:
<x:ExpandoControl someProperty="a value"></x:ExpandoControl>
Where the someProperty attribute does not yet exist as a property on the control.
I should also mention that I don't strictly need any functionality of Control or WebControl. I just need to be able to declare it in markup with runat="server" (which in and of itself may require it to be a control, at least that's what I'm thinking).
Is it possible? If so how can I get started?
Many thanks.
I think your first bet would be to implement IAttributeAccessor:
public interface IAttributeAccessor
{
string GetAttribute(string key);
void SetAttribute(string key, string value);
}
The ASP.NET page parser calls IAttributeAccessor.SetAttribute for each attribute it cannot map to a public property.
So perhaps you can start with
public class ExpandoControl : Control, IAttributeAccessor
{
IDictionary<string, object> _expando = new ExpandoObject();
public dynamic Expando
{
{
return _expando;
}
}
void IAttributeAccessor.SetValue(string key, string value)
{
_expando[key] = value;
}
string IAttributeAccessor.GetValue(string key)
{
object value;
if (_expando.TryGetValue(key, out value) && value != null)
return value.ToString();
else
return null;
}
}
I searched the web but haven't found a real good answer for this question..
Let's say I have a form, on AddToList.aspx, and i want that after you hit send, it will direct you back to List.aspx, with a message "The Item was added to list" in a message box div.
do i need to send List.aspx?msg=my message, or is there another good way of doing it?
EDIT:
so i made this helper class:
public class MessageHelper : System.Web.UI.MasterPage
{
public void SetMessage(String message)
{
Session["Message"] = message;
}
public string GetMessage()
{
if (String.IsNullOrEmpty(Session["Message"]))
{
String temp = Session["Message"];
Session["Message"] = "";
return temp;
}
else
{
return "";
}
}
}
and got this error:
Error 32 The best overloaded method match for 'string.IsNullOrEmpty(string)' has some invalid arguments
Error 33 Argument '1': cannot convert from 'object' to 'string'
Error 34 Cannot implicitly convert type 'object' to 'string'. An explicit conversion exists (are you missing a cast?)
You need to convert to string. Session parameters are stored as objects.
It may also be userful to implement this as a extension method. This way it will be available on all page types (Master and UI)
public static class MessageHelper
{
public static void SetMessage(this Page page, String message)
{
Session["Message"] = message;
}
public static string GetMessage(this Page page)
{
var messageText = Session["Message"] as string;
if (!String.IsNullOrEmpty(messageText ))
{
Session["Message"] = "";
return messageText;
}
return "";
}
}
You could certainly use the query string to pass data to your List.aspx page, but be careful passing text that you're planning on writing out in the HTML - you'll need to protect against XSS attacks.
There are several other ways to do this. Chances are, you're going to have several places in your application where you want to redirect the user to another page, but also display a message that has something to do with what they did on the previous page (saved an item, deleted an item, etc.). It would be better to come up with more of a global scheme for this rather than a one-off just for this particular instance.
One idea is to use the Session for storing a message, then do your redirect.
Session("Message") = "Item was added to list."
Response.Redirect("List.aspx")
Then, on your pages (or a Master Page, perhaps), you check Session("Message") and if it's got something, you show that message to the user, then clear that variable.
If Session("Message") IsNot Nothing Then
Response.Write(CType(Session("Message"), String)) 'or set a label text, or show a pop up div, or whatever'
Session("Message") = Nothing
End If
If you use this approach, I recommend you write a helper class, and just use that to manage your messaging:
MessageHelper.SetMessage("Item added to list.")
and
MessageHelper.GetMessage()
would be the methods you would need.
I believe you could do it by setting the PostBackUrl of the button used to save the data to "List.aspx". Maybe set a variable to true/false on AddToList.aspx and then access it from List.aspx?
Not sure if it's better but it's an option.
I can't comment yet or I would have just commented this to your post. You need to cast your session variable like this: (string)Session["Message"]. So, code would look like this:
public class MessageHelper : System.Web.UI.MasterPage
{
public void SetMessage(String message)
{
Session["Message"] = message;
}
public string GetMessage()
{
if (String.IsNullOrEmpty((string)Session["Message"]))
{
String temp = (string)Session["Message"];
Session["Message"] = "";
return temp;
}
else
{
return "";
}
}
}
Actually there's a better way of writing that class: make it one property instead of two methods. It would look like this: (I also fixed your logic; GetMessage was always returning blank)
public class MessageHelper : System.Web.UI.MasterPage
{
public MessageHelper()
{
}
public string Message
{
set { Session["Message"] = value; }
get
{
if (String.IsNullOrEmpty((string)Session["Message"]))
{
Session["Message"] = "";
}
return (string)Session["Message"];
}
}
}
In your two respective files, you would set and get it like so:
//in AddToList.aspx
MessageHelper msg = new MessageHelper();
msg.Message = "The Item was added to your list.";
//and in List.aspx, assigned to an arbitrary Label named myMessageLabel
MessageHelper msg = new MessageHelper();
myMessageLabel.Text = msg.Message;
I have a user control on a web form that is declared as follows:
<nnm:DeptDateFilter ID="deptDateFilter" runat="server" AllowAllDepartments="True" />
In the code-behind for this control, AllowAllDepartments is declared as follows:
internal bool AllowAllDepartments { get; set; }
Yet when I view the page, and set a breakpoint in the control's Page_Load event handler, my AllowAllDepartments property is always false. What are possible reasons for this?
BREAKING NEWS: Even setting the property programmatically has no effect on the property value when I hit my breakpoint in Page_Load of the control. Here is the Page_Load of the host page:
deptDateFilter.FilterChanged += deptDateFilter_FilterChanged;
if (!IsPostBack)
{
deptDateFilter.AllowAllDepartments = true;
PresentReport();
}
Try adding the property value to the ViewState:
protected bool AllowAllDepartments
{
get
{
if (ViewState["AllowAllDepartments"] != null)
return bool.Parse(ViewState["AllowAllDepartments"]);
else
return false;
}
set
{
ViewState["AllowAllDepartments"] = value;
}
}
EDIT
Furthermore, you may want to handle the control's PreRender event, to see whether the the control's property has been correctly set there or not.
Make the property bindable like:
[Bindable(true), Category("Appearance"), DefaultValue(false)]
internal bool AllowAllDepartments { get; set; }
Just out of curiosity... does it work OK if you don't use the get;set; shortcut?
private bool _allowAllDepartments;
public bool AllowAllDepartments
{
get { return _allowAllDepartments; }
set { _allowAllDepartments = value;}
}
Have you tried making the property public?