I'm trying to find a way of opening a page from a button if its NOT already open.
What I have so far is 2 pages.
Default page opens Option page via a button like:-
protected void btnCreateNewWindow_Click(object sender, EventArgs e)
{
if (SharedMethods.Is_Page_Displayed == 0)
{
ClientScript.RegisterStartupScript(typeof(Page), "Order", "<script type='text/javascript'>window.open('Option1.aspx', '', 'fullscreen = yes')</script>");
SharedMethods.Is_Page_Displayed = 1;
}
}
Shared Session code:-
namespace ns_SharedMethods
{
public class SharedMethods
{
#region Session
public static String sIs_Page_Displayed = "Is_Page_Displayed";
#endregion Session
public static int Is_Page_Displayed
{
get
{
if (System.Web.HttpContext.Current.Session[sIs_Page_Displayed] != null)
{
return (Convert.ToInt32(System.Web.HttpContext.Current.Session[sIs_Page_Displayed]));
}
else
{
return (0);
}
}
set
{
System.Web.HttpContext.Current.Session[sIs_Page_Displayed] = value;
}
}
public static String Is_The_Page_Displayed()
{
if (Is_Page_Displayed == 1)
{
return ("YES");
}
else
{
return ("NO");
}
}
}
}
I've tried is using a Session variable as a flag to denote the page is open/closed.
Is it possible to trigger an OnClosePage event in the second Page to set a Session variable "Is_Page_Displayed = 0"?
Any examples is appreciated.
tia
PS I've tried to publish all pages .aspx source code but the formatting was being distorted :(
Base on the initial code used, add:-
On "Option1.aspx"
Add this to the source:-
<script>
// Window Event to trigger when the page has closed
window.onbeforeunload = function (event)
{
// C# method called from the Java Script
PageMethods.SetWebPageClosedSession();
}
</script>
And this under the "< body > < form id="form1" runat="server" >"
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true">
</asp:ScriptManager>
Add this to the Option1.aspx.cs:-
[System.Web.Services.WebMethod]
public static void SetWebPageClosedSession()
{
// Method called from the .aspx Script function WebPageClosed()
SharedMethods.Is_Page_Displayed = 0;
}
So what I've done is use the window.onbeforeunload event, in Option1.aspx, to call a C# method to set a Session variable. The Default.aspx page checks prior to trying to open Option1.aspx
Related
I use several UpdatePanel in the same page, with UpdateMode = Conditional, and i'm trying to find a clean way to only execute code behind related to the UpdatePanel which will be updated.
So, when i'm calling a __doPostBack from JS, i am able, on the code behind side, to detect the name of the UpdatePanel which is asked to refresh by using Request["__EVENTTARGET"] (which gives me the ClientID of the UpdatePanel).
But when i'm calling the UpdatePanel1.Update() method (from server side), is there a built-in way to know if an Update panel is about to be updated ?
I am posting here to myself my temporary (?) answer.
Because there is apparently no way to detect if a UpdatePanel is being updated (when UpdatePanel is updated by code behind), i've created a class which handle the update, and put some data in session, so, this same class will be able to tell if the UpdatePanel is updating.
So, I doesn't call anymore directly UpdatePanel.Update(), but UpdatePanelManager.RegisterToUpdate().
The method bool isUpdating() is able to tell if an UpdatePanel is updating, and can tell automatically if an updatePanel is Updating though Javascript using HttpContext.Current.Request["__EVENTTARGET"].
Note: isUpdating() need to be used within the OnPreRender Page event.
public static class UpdatePanelManager
{
private const string SessionName = "UpdatePanelRefresh";
public static void RegisterToUpdate(System.Web.UI.UpdatePanel updatePanel)
{
updatePanel.Update();
if (HttpContext.Current.Session[SessionName] == null)
{
HttpContext.Current.Session[SessionName] = new List<string>();
}
((List<string>)HttpContext.Current.Session[SessionName]).Add(updatePanel.ClientID);
}
public static bool IsUpdating(System.Web.UI.UpdatePanel updatePanel)
{
bool output = false;
// check if there is a JavaScript update request
if (HttpContext.Current.Request["__EVENTTARGET"] == updatePanel.ClientID)
output = true;
// check if there is a code behind update request
if (HttpContext.Current.Session[SessionName] != null
&& ((List<string>)HttpContext.Current.Session[SessionName]).Contains(updatePanel.ClientID))
{
output = true;
((List<string>)HttpContext.Current.Session[SessionName]).Remove(updatePanel.ClientID);
}
return output;
}
public static bool IsUpdatingOrPageLoading(System.Web.UI.UpdatePanel updatePanel, System.Web.UI.Page page)
{
bool output = false;
if (!page.IsPostBack || IsUpdating(updatePanel))
output = true;
return output;
}
}
I have a button in one page that opens up a window with inside an exchange rate calculator.
The exchange rate calculator is a an external web service.
Can happen that the session is expired but the user is still on the page and clicking on the button that open such window, instead of the calculator, the web site login page appears.
To avoid the user to login from the page in the window, I am trying to check if the session is still existing and if not prompt the user that the session is expired and he needs to login again.
To avoid that despite the warning the user still try to login from the window, I would like to stop the page in the window to load and redirect to the login page when the user click ok in the prompt button.
public void Page_Init(object o, EventArgs e)
{
if (Session ["isUser"] != "isUser")
{
ScriptManager.RegisterStartupScript(
this,
this.GetType(),
"Warning",
"alert('Your session expired! You shall login again.');",
true);
Response.Redirect("~/Login.aspx");
}
}
The above method sometimes shows the prompt sometimes it doesn't and in any case newer reach the last line to redirect to the login page. I need some help to get the above scenario under control. How can I make the above logic working? I mean get the prompt displayed if the condition is not meet, the page not loading and redirect on the ok of the user?
I just implemented this in my project, and it works live and fine now :
1) implement a class that handle your session
public static class SessionManager
{
public static object _Session_UserInfo
{
get
{
if (HttpContext.Current.Session["isUser"] == null)
{
HttpContext.Current.Response.Redirect("Index?Expired=1");
return null;
}
else
{
return HttpContext.Current.Session["isUser"];
}
}
set
{
HttpContext.Current.Session["isUser"] = value;
}
}
}
//2) start referencing the sesison variable from this calss:
public void Page_Init(object o, EventArgs e)
{
//do whatever you wanna do with it, it will automatically redirect if expired
//SessionManager._Session_UserInfo;
}
//in javascript do the following :
function getParameterByName(n) {
var half = location.search.split(n + '=')[1];
return half !== undefined ? decodeURIComponent(half.split('&')[0]) : null;
}
$(document).ready(function () {
var _IsSessionExpired = getParameterByName("Expired");
// alert(_IsSessionExpired);
if (_IsSessionExpired != null)
alert('Your Session Has Expired, please login to the system !');
window.location="any page you want to redirect to";
});
your welcome
I finally found the way to solve the problem. To avoid a never ending loop trying to redirect from the window I need to close, I did it from the javascript function used to open the window.
So basically before I open the window I check if the session is valid and if not I redirect before opening it.
function openRadWin() {
var session='<%= Session["isUser"]%>';
if (session != "isUser") {
alert("Your Session has expired. Click OK to login again.");
window.location = "../Login.aspx";
}
else {
var width = "430px";
var height = "355px";
var left = "800px";
var top = "150px";
radopen("currencies.aspx", "RadWindow1", width, height, left, top);
}
}
Thanks to Wizpert for some good suggestion but I decided to minimize the code and to do all in few lines.
You can try this code which uses WebMethod to invalidate current login session cookie then alerts user about session expiration and then redirects user to the login page.
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication1.WebForm1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script type="text/javascript">
var HeartBeatTimer;
function StartHeartBeat()
{
if (HeartBeatTimer == null) {
//timouts after 1 minute
HeartBeatTimer = setInterval("HeartBeat()", 1000 * 60*1);
}
}
function HeartBeat()
{
PageMethods.PokePage(onSucess, onError);
function onSucess(result) {
alert('Session Expired');
window.location = result;
}
function onError(result) {
alert('Something wrong.');
}
}
</script>
</head>
<body onload="StartHeartBeat();">
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true"></asp:ScriptManager>
<div>
</div>
</form>
</body>
</html>
And the C# code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication1
{
public partial class WebForm1 : System.Web.UI.Page
{
static int x = 0;
protected void Page_Load(object sender, EventArgs e)
{
HttpCookie hc = new HttpCookie("kk", "kk");
hc.Expires = DateTime.Now.AddMinutes(5);
Response.Cookies.Add(hc);
}
[WebMethod(EnableSession = true)]
public static String PokePage()
{
HttpCookie hc = new HttpCookie("kk", "kk");
hc.Expires = DateTime.Now.AddMinutes(-5);
HttpContext.Current.Response.Cookies.Add(hc);
return "http://www.google.com";
}
}
}
My page code looks like this:
<asp:Button ID="btnSearch" runat="server" Text="Search" onclick="btnSearch_Click"/>
My method looks like this:
protected void btnSearch_Click(object sender, EventArgs e)
{
var value = lblGraphicNameValue.Text.ToString();
Response.Redirect("Search.aspx?txtGraphicName=" +
value);
}
Currently, when the user press the 'Search' button the page refreshes and loads the Search.aspx page. What I'd like to happen is have the Search.aspx open in a new window, instead. I've looked at using Window.Open, but I'm not sure if this is the correct route, or if I can use the same method of passing in my variable (querystring). Can someone point me in the right direction? What I have works, I just want it to open in a new page while leaving the prior page alone.
EDIT: I should mention that I cannot use javascript (secure environment, every browser has javascript disabled).
From what I'm reading, it seems to indicate that opening a new web page from within an asp.net page and having parms passed in is not do-able without javascript? Is this correct?
This code below ultimately does exactly what I needed it to:
<a href="<%= this.ResolveUrl("Search.aspx?id=" + lblGraphicNameValue.Text.Remove(lblGraphicNameValue.Text.Length -4)) %>"
target="_blank">Search Related</a>
This code does three things:
1) Opens Search in new page.
2) Truncates the search value by four
characters (I only needed part of the search string)
3) Passes in
parameter to new page.
This accomplished exactly what I needed without resorting to custom classes or javascript, although it did make me have to use a link instead of a button.
Use this class.
ResponseHelper .Redirect("popup.aspx", "_blank", "menubar=0,width=100,height=100");
public static class ResponseHelper {
public static void Redirect(string url, string target, string windowFeatures) {
HttpContext context = HttpContext.Current;
if ((String.IsNullOrEmpty(target) ||
target.Equals("_self", StringComparison.OrdinalIgnoreCase)) &&
String.IsNullOrEmpty(windowFeatures)) {
context.Response.Redirect(url);
}
else {
Page page = (Page)context.Handler;
if (page == null) {
throw new InvalidOperationException(
"Cannot redirect to new window outside Page context.");
}
url = page.ResolveClientUrl(url);
string script;
if (!String.IsNullOrEmpty(windowFeatures)) {
script = #"window.open(""{0}"", ""{1}"", ""{2}"");";
}
else {
script = #"window.open(""{0}"", ""{1}"");";
}
script = String.Format(script, url, target, windowFeatures);
ScriptManager.RegisterStartupScript(page,
typeof(Page),
"Redirect",
script,
true);
}
}
}
I think your on the right track, but you're confusing server side code, and client side code. window.open is a Javascript function which works on the client side. So you'll need to render some Javascript from C# to make the window popup. Try:
protected void btnSearch_Click(object sender, EventArgs e)
{
var value = lblGraphicNameValue.Text.ToString();
ClientScript.RegisterStartupScript(this.GetType(), "newWindow", String.Format("<script>window.open('Search.aspx?txtGraphicName={0}');</script>", value));
}
That will re-render the page, and then add a script on pageload that will popup the window. A little warning, this will probably be blocked by a browser popup blocker. If you want to get around that, you can probably achieve this without posting back to the server by using Javascript.
A better option would be to create a javascript function like:
function PreviewPOSTransaction(Id)
{
if (Id != null)
{
window.open('POSTransReport.aspx?TransID=' + Id);
return true;
}
}
</script>
and call this function on button "OnClientClick" event like:
OnClientClick="PreviewPOSTransaction(1);
I have a page, where I want to log every validation message which the user failed to meet the requirements the associated field.
The problem is my postback/button click never occurs (maybe because of clientside validation), and therefore the logging never takes place before the user actually got every field right (no validation errors).
The button click event method:
protected void btnNext_Click(object sender, EventArgs e)
{
Page.Validate();
if(Page.IsValid)
{
//code
}
else
{
foreach (IValidator validator in Validators)
{
if (!validator.IsValid)
{
PageValidatorErrors error = new PageValidatorErrors
{
WebsiteID = AppState.WebsiteID,
Page = Request.Url.AbsolutePath,
URL = Request.Url.ToString(),
UserIP = Tools.GetIP(),
ErrorMessage = validator.ErrorMessage,
CreatedDate = DateTime.Now
};
pageValidatorErrorsRep.insert(error);
}
}
}
}
Any ideas, how I could log theese messages?
Edit:
<script type="text/javascript">
function validatePage()
{
if (window.Page_IsValid != true)
{
//Page_Validators is an array of validation controls in the page.
if (window.Page_Validators != undefined && window.Page_Validators != null)
{
//Looping through the whole validation collection.
for (var i = 0; i < window.Page_Validators.length; i++)
{
window.ValidatorEnable(window.Page_Validators[i]);
//if condition to check whether the validation was successfull or not.
if (!window.Page_Validators[i].isvalid)
{
var errMsg = window.Page_Validators[i].getAttribute('ErrorMessage');
alert(errMsg);
}
}
}
}
}
</script>
Here is part of the solution, you can get the validates/true false by invoking it client side:
http://razeeb.wordpress.com/2009/01/11/calling-aspnet-validators-from-javascript/
function performCheck()
{
if(Page_ClientValidate())
{
//Do something to log true/ false
}
}
Try to change EnableClientScript property on all validators to false. All your validations will occur only on server side.
I have a problem with this that works for one button and not for another.
The one that works is a button that calls a ModalPopup to add a new row to a GridView inside an UpdatePanel. If it's successful, it pops up an alert with a message, else another alert with the Exception message. The code is very similar to the other one's, except it's in a ModalPopupExtender.
The button that throws the known exception about the EventValidation goes as follow:
Web:
<asp:Button ID="btnAlquilar" runat="server" Text="Alquilar" CssClass="AdminButtons"
OnClientClick="Click_Alquilar(); return false"/>
The JavaScript function it calls
function Click_Alquilar() {
if (index == '') {
alert("Debe elegir una película para alquilar");
}
else {
if (confirm("¿Quiere alquilar la película '" + selected.childNodes[2].innerText + "'?")) {
__doPostBack('<%= btnAlquilar.UniqueID %>', index);
}
}
}
Where index is the index of the selected row in the GridView (done with a similar architecture, and works fine).
The code-behind starts in the Page_Load method, and calls the function I'm having trouble with:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{...}
else
{
ProcessAjaxPostBack(sender, e);
}
}
private void ProcessAjaxPostBack(object sender, EventArgs e)
{
if ((Request.Params["__EVENTTARGET"] != null) && (Request.Params["__EVENTARGUMENT"] != null))
{
...
if (Request.Params["__EVENTTARGET"] == this.btnAlquilar.UniqueID)
{
index = Convert.ToInt32(Request.Params.Get("__EVENTARGUMENT").TrimStart('r', 'o', 'w'));
btnAlquilar_Click(Request.Params.Get("__EVENTARGUMENT"));
}
}
}
protected void btnAlquilar_Click(string id)
{
string message = "";
if (BAC.BAC.CheckUserAge(lblUserId.Text) < Convert.ToInt32(dgvPeliculas.Rows[index].Cells[7].Text))
{
btnBorrar.Visible = false;
btnEditar.Visible = false;
btnNuevo.Visible = false;
System.Web.UI.ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), Guid.NewGuid().ToString(), "alert('No tiene la edad mínima para alquilar la película.')", true);
}
else
{
try
{
BAC.BAC.NewAlquiler(lblUserId.Text, dgvPeliculas.Rows[index].Cells[0].Text, dgvPeliculas.Rows[index].Cells[9].Text);
}
catch (Exception ex)
{
message = Change_ExceptionMessage(ex.Message);
System.Web.UI.ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), Guid.NewGuid().ToString(), "alert('No se pudo alquilar la película: " + message + "')", true);
}
}
}
The RegisterClientScriptBlock method is THE SAME I use for the other button (which doesn't do anything more complex than this one: if things are wrong, it changes the text of a label in the Popup and shows the alert; if it's right, it loads the GridView and shows the success alert), and works there. Here, it throws the exception "EnableEventValidation is true so...". I have this button registered for Event Validation on Render:
protected override void Render(HtmlTextWriter writer)
{
this.Page.ClientScript.RegisterForEventValidation(btnAlquilar.UniqueID);
base.Render(writer);
}
So why does this happen here? Why it doesn't work this time?
EDIT: Now that I check, the label changed by the working button in the ModalPopup is wrapped in an UpdatePanel. I don't know if it matters, but just to note it.
EDIT2: The page also works within a Master page. Don't know if it's of any use. I have tried wrapping both the Edit button and the GridView with UpdatePanels and using AsyncPostBackTrigger, but still I get the same exception.
OnClientClick="Click_Alquilar(); return false"
instead of this use
OnClientClick="return Click_Alquilar();
and in javascript
use return false;
in functions like
function Click_Alquilar() {
if (index == '') {
alert("Debe elegir una película para alquilar");
return false;
}
else {
if (confirm("¿Quiere alquilar la película '" + selected.childNodes[2].innerText + "'?")) {
__doPostBack('<%= btnAlquilar.UniqueID %>', index);
}
}
}
OK, for those who are interested in it, the problem was with the _doPostBack calls. Since the arguments I passed (_EVENTARGUMENT) were dynamic, I could never register those events through the RegisterForEventValidation method, becuase it asks for two constant strings (AFAIK): the control's UniqueID and the argument it will be passed with it.
So, I stopped passing arguments to the doPostBack other than the button's UniqueID, and passed the variables I was interested in through other media (cheifly, hidden fields values to global variables inside the Page class).
That solved the problem and made the program work as intended. I wrapped the buttons inside the same update panel than the GridView so as to not generate an AutoPostBack and change the Grid's values without having to refresh.
If anybody is interested in the code, I can provide.