Get href value with onServerClick - c#

I'm working with asp.net and c#
I got a list of link and i want to get the href value in the code behind.
So far I have:
<li>Room 101</li>
<li>Room 102</li>
<li>Room 103</li>
protected void room_click(object sender, EventArgs e)
{
}
The problem is I can't find a solution to get the href value, I tried the anchor or regex but it doesn't work.

You have to cast the sender to an HtmlAnchor so you can access the property:
public void room_click(object sender, EventArgs e)
{
var href = ((System.Web.UI.HtmlControls.HtmlAnchor)sender).HRef;
}

protected void room_click(object sender, EventArgs e)
{
var anchor = sender as HtmlAnchor;
if (anchor == null)
return;
var href = anchor.HRef;
//--do something
}

Your onServerClick is going to override your href anyway and instead cause a postback... so I'd recommend just removing it all and simply have:
<li>Room 101</li>
<li>Room 102</li>
<li>Room 103</li>
And then in your code behind:
protected void Page_Load(object sender, EventArgs e)
{
RoomClick();
}
private void RoomClick()
{
int roomId = 0;
//check to see if the id in the querystring exists and that it parses as an int.
if (!String.IsNullOrEmpty(Request.QueryString["id"]) && Int32.TryParse((Request.QueryString["id"]), out roomId))
{
//do something with roomId
}
}
This way seems more straightforward / easier to use, in my opinion. Jason's answer will work for you as well. I think that route is confusing though because although you can read the href and get that value, you can't read a # value from a URL... and this just isn't a standard way of accomplishing what you want to accomplish. Plus, how were you planning on easily getting the Room # out of that href?
The other reason I like this route is you can link someone directly to a room without telling them to click something first... if the id is there, it will load the room info or whatever you are doing.
UPDATE: If you don't want the room info in the URL and still want a "PostBack" approach, my recommendation is still a different route. Instead use a LinkButton which would be a more "traditional" way (in ASP.NET Web Forms) to do a PostBack and pass data:
So instead, have markup like:
<li><asp:LinkButton ID="_room104" OnCommand="RoomCommand" CommandArgument="104" Text="Room 104" runat="server"></asp:LinkButton></li>
<li><asp:LinkButton ID="_room105" OnCommand="RoomCommand" CommandArgument="105" Text="Room 105" runat="server"></asp:LinkButton></li>
and then code behind like:
protected void RoomCommand(object sender, CommandEventArgs e)
{
int roomId = 0;
if (Int32.TryParse((string)e.CommandArgument, out roomId)) {
//do something with roomId
}
}

Related

Navigation Source in Windows Phone

I have 2 pages in my application, A and B.
If I'm navigation from the outside of the application to A, I want to display a message box. If I'm navigation from B to A, I don't want to display anything.
Is there any way to identify in A the page which initiated navigation? i.e in A.Loaded (or any other event) I need something like
if(pageFromWhichIAmComingFrom == B)
OnNavigatedTo, OnNavigationFrom and OnNavigatedFrom don't seem to help me.
You could use the PhoneApplicationService class to store information about what page you were on last. For example, use OnNavigatedFrom on Page A:
void OnNavigatedFrom(object sender, Eventargs e)
{
PhoneApplicationService.Current.State["LastPage"] = "PageA";
}
And then check for that on the next page:
void OnNavigatedTo(object sender, Eventargs e)
{
if(PhoneApplicationService.Current.State["LastPage"].ToString() == "PageA")
{
// came from page A
}
else
{
// came from a different page
}
}
Hope this helps!
UPDATE:
One more thing I just saw that might be worth trying is using the NavigationService.BackStack property. I haven't tried this, but it seems like it should work. In your OnNavigatedTo event handler, you should be able to get the last entry from the stack to see your last page. This would be simpler and wouldn't require you to set any properties manually. Example:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
var lastPage = NavigationService.BackStack.FirstOrDefault();
}
Found here.

How to pass parameters from one page to another?

I have the following code behind:
public partial class _Default : System.Web.UI.Page
{
List<GlassesCollection> gc= BL.Example.GetCategory() ;
protected void Page_Load(object sender, EventArgs e)
{
rpt1.DataSource = gc;
rpt1.DataBind();
}
protected void rpt1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
Button btn = (Button)e.Item.FindControl("btn1");
btn.CommandArgument = DataBinder.Eval(e.Item.DataItem,"CollectionID").ToString();
}
}
I want to pass the content of the btn.CommandArgument to Label's event that placed in another ASPX.CS file.
Is there any way to implement this?
Thank you in advance!
You need to use Session. Put value in Session and read it in another page.
Session["key"]=value;
You can use QueryStrings. For example, your url will can look like:
string url = String.Format("http://www.example.com/somepage.aspx?labeltext={0}",btn.CommandArgument);
Then, in your somepage.aspx, you can have:
//"labeltext" is the same name we used above as the ID
string lblText = Request.QueryString["labeltext"];
if (lblText != null)
{
myLabel.Text = lblText;
}
If there's a chance that the text might not be suitable for passing in a URL, you can encode it with HttpServerUtility.UrlEncode and then decode it with HttpServerUtility.UrlDecode before assigning it to the label.
Use the query string for that:
Response.Redirect("AnotherPage.aspx?CommandArgument=SomeArgument");
Then read the QueryString on AnotherPage.aspx
string commArgument = Request.QueryString["CommandArgument"];

At what point in my code did this List<> become empty?

namespace Messages
{
public partial class Email
{
List<Document> attachments = new List<Document>();
protected void Page_Load(object sender, EventArgs e)
{
foreach(Document document in documentList)
{
attachments.Add(document);
}
}
protected void btnSend_Click(object sender, EventArgs e)
{
sendMail(attachments);
}
}
}
As you can guess, I've stripped this code right down for explanation purposes but that's pretty much all I'm doing with it. I've got a feeling it's to do with deep/shallow copying and cloning, if so - can someone help explain what's gone on here and how I can avoid it/populate the list differently.
Thanks a lot,
Dan
EDIT: Sorry, where I've wrote 'documentList' it actually reads:
(List<Document>)Session[Request.QueryString["documentList"]]
So yer - it's coming from a session variable. Using breakpoints I can see the attachments list is being populated just fine, but then when it comes to the click event handler it's empty!? Not null, just count == 0.
It becomes empty because it's not being stored in the ViewState (I'm assuming asp.net webforms here from the method names).
See How to: Save Values in View State and ASP.NET Page Life Cycle Overview
Alternatively store the value in the Session see How to: Save Values in Session State
EDIT2: with the extra info - I've had problems with this before that have been resolved by moving the code out of Page_load and into a helper method (better) and use this in the event callback. I did originally state that the event callback was coming before the Page_Load - however I've just checked this, and it doesn't, however I'm sure that I've had a problem in the past where in certain situations, with child controls, the Page_Load wasn't completing - possibly related to validation.
Anyway it should probably be recoded along the following lines - to remove the dependancy between Page_load and attachments. Using IENumerables (rather than lists) can also be neat - see the final example.
e.g.
List<Document> getAttachments()
{
List<Document> attachments = new List<Document>();
foreach(Document document in (List<Document>)Session[Request.QueryString["documentList"]])
attachments.Add(document);
}
and then in the callback:
protected void btnSend_Click(object sender, EventArgs e)
{
sendMail(getAttachments());
}
however also worth suggesting using LINQ to do it like this:
IEnumerable<Document> getAttachments()
{
return ((List<Document>)Session[Request.QueryString["documentList"]]).Select(doc => doc);
}
protected void btnSend_Click(object sender, EventArgs e)
{
sendMail(getAttachments());
// or if sendMail doesn't accept IEnumerable then do :
//sendMail(getAttachments().ToList());
}

Button.OnClientClick question

I'm gonna post some more code to show exactly what I'm trying to do,
I'm adding the button using programming code and not markup but the OnClick won't work (giving the following error:
System.Web.UI.WebControls.Button.OnClick(System.EventArgs)' is inaccessible due to its protection level.
Button btnopslaan = new Button();
btnopslaan.Text = "Opslaan";
btnopslaan.ID = "btnOpslaan";
btnopslaan.CssClass = ".opslaan";
btnopslaan.Click += new EventHandler(btnopslaanClick);
btnopslaan_arr[btn_count] = btnopslaan;
add_button(btnopslaan);
protected void btnopslaanClick(object sender, EventArgs e)
{
Debug.WriteLine("success");
}
I just can't find out why this isn't working.
Anyone who can help me out?
You need to use OnClick for server side clicks rather than OnClientClick
Either you can use it inline >
<asp:Button id="btnopslaan" runat="server' OnClick="btnopslaanClick" />
Or in Code behind >
btnopslaan.Click+=new EventHandler(btnopslaanClick);
or you make it a postback call to the server. in your
aspx write:
<asp:Button runat="server" ID="buttonOpslaan" Text="opslaan" ></asp:Button>
codebehind write this:
protected void Page_Init(object sender, EventArgs e)
{
buttonOpslaan.Click += new EventHandler(buttonOpslaan_Click);
}
// mind: this method can be private
void buttonOpslaan_Click(object sender, EventArgs e)
{
//do something
}
or handle it with the AutoEventWireUp (recommended) like:
<asp:Button runat="server"
ID="buttonOpslaan"
OnClick="buttonOpslaan_Click"
Text="opslaan" ></asp:Button>
// mind: this method cannot be private, but has to be protected at least.
protected void buttonOpslaan_Click(object sender, EventArgs e)
{
//do something
}
or do it completely from code behind:
// note: buttonOpslaan must have an (autoassigned) ID.
protected void Page_Init(object sender, EventArgs e)
{
Button buttonOpslaan = new Button();
buttonOpslaan.Text = "opslaan!";
buttonOpslaan.Click += new EventHandler(buttonOpslaan_Click);
form1.Controls.Add(buttonOpslaan);
}
protected void buttonOpslaan_Click(object sender, EventArgs e)
{
//do something
}
or handle it clientside with javascript in your ASPX (it will not reach the server)
<script type="text/javascript">
function buttonOpslaan_Click(){
alert("test");
return false;
}
</script>
<asp:Button runat="server"
ID="buttonOpslaan"
OnClientClick="buttonOpslaan_Click()"
Text="opslaan" ></asp:Button>
Update: (by comments)
if you add the control via an eventhandler (like the onchange event of a dropdownlist), the control is 'lost' on next postback, or even as soon as the Page is send to the client (due to the stateless (there is no mechanism to maintain the state of application) behaviour and lifecycle of .Net).
So simply adding a control once is never going to work.
That means you have to rebuild the control every time a postback occurs. My preferred way to do this is store a list/document somewhere that descrbes what controls must be created each time. Possible locations are, from worse to good (IMHO):
Session
Viewstate
Cache
XML/IO
Database
After all, you are posting "data" to the server (that represents a control) and you want to save that for further use.
If the controls to be created aren't that complex you could implement a Factory Pattern like a WebControlFactory that stores only a few properties in a List or Dictionary, which is read every time to recreate the controls again (and again, and again, and again)
btnopslaanClick should be client side, in the .aspx itself have:
<script type="text/javascript">
function btnopslaanClick() {
alert("success");
}
</script>
btnopslaan.Click+=new EventHandler(btnopslaanClick);
protected void btnopslaanClick(object sender, EventArgs e)
{
Debug.WriteLine("succes");
}

What is the best way to distinguish beteen "Refresh Post" or a "Real Post Back"

What is the best way to distinguish beteen "Refresh Post" or a "Real Post Back".
This is what I need to attain
protected void Button1_Click(object sender, EventArgs e)
{
if(PostBack && !Refresh)
{
//Do Something
}
}
I usually do a Response.Redirect to the same page in the postback event.
That way all my Page.IsPostBack are real Postbacks and not Refreshes
You could set a hidden input with a nonce value generated randomly every time the form is loaded (but not on postback), then check if the nonce value got sent twice. If it got sent a second time, it was a refresh.
you could try like
protected void Button1_Click(object sender, EventArgs e)
{
//your code of Click event
//..............
//...............
// and then add this statement at the end
Response.Redirect(Request.RawUrl); // Can you test and let me know your findings
}
Sample working code for the accepted answer
Add this line in designer
<input type="hidden" runat="server" id="Tics1" value="GGG" />
Add following lined in the code behind
public partial class WebForm1 : System.Web.UI.Page
{
long tics = DateTime.Now.Ticks;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
this.Tics1.Value = tics.ToString();
Session["Tics"] = tics;
}
}
protected void Button1_Click(object sender, EventArgs e)
{
if (Session["Tics"] != null && Request["Tics1"] != null)
{
if (Session["Tics"].ToString().Equals((Request["Tics1"].ToString())))
{
Response.Write("Postback");
}
else
{
Response.Write("Refresh");
}
}
this.Tics1.Value = tics.ToString();
Session["Tics"] = tics;
}
}

Categories