Ajaxpro methods get global page variable to be reinitialized? - asp.net

I have a problem with ajaxpro methods. In the .cs file I defined some global variable for my page, something like:
public partial class Admin : System.Web.UI.Page
{
public int localidMember = 9;
protected void Page_Load(object sender, EventArgs e)
{
AjaxPro.Utility.RegisterTypeForAjax(typeof(Admin));
if (HttpContext.Current.Session["HomeOwn_ID"] != null)
{
localidMember = Convert.ToInt32(HttpContext.Current.Session["HomeOwn_ID"].ToString());
}
}
[AjaxPro.AjaxMethod(AjaxPro.HttpSessionStateRequirement.ReadWrite)]
public string LoadInbox()
{
// I need to use the variable localidMember and expected that it will have the value that I have set to pageload.., but it didnt. The variable is reinitialized to 9... Anyone have any ideas what's going on... Thanks so much !
}
}

I think you can't do it; because, in AjaxPro, you can't deal with control properties.

AjaxMethod will have its own Context. Hence, localidMember will not be accessible inside it. You may consider passing it as a parameter.

Related

C# property not working

Dont understand why its not working.. im using the property to set the Activelogin to true then getting the value in another page to certify that the user is has access.
namespace Ibrax_1
{
public partial class loginPage : System.Web.UI.Page
{
public bool activelogin;
public bool Activelogin
{
get
{
return activelogin;
}
set
{
activelogin = value;
}
}
.
.
.
Activelogin = true; // here in a method im setting the value to true.
and im getting value here:
namespace Ibrax_1
{
public partial class Program : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
CheckAvailablePrograms();
}
private void CheckAvailablePrograms()
{
loginPage lp = new loginPage();
if (lp.Activelogin) //here im getting the value but its false
{
am i doing anything wrong?
You're creating a new instance:
loginPage lp = new loginPage();
That new instance will have every property set to its default value. For boolean, that's false.
If you're setting it to true somewhere else, then it won't matter since you're not looking at that instance.
It's like drawing on a piece of paper and then taking another paper and wondering why there's no drawing on it. You can't expect there to be a drawing unless you're looking at the same piece of paper.
So you need to save the instance of object somewhere so you can use it again in the CheckAvailablePrograms method. As Alex Kudryashev mentioned, you could save it as a Session variable, although it's not the only way. You can read more about the Session object here if you wish: https://msdn.microsoft.com/en-us/library/ms178581.aspx

Server.TransferRequest does not get correct page

we are using HttpModule for switching aspx pages..
But if large number of client try to hit same time then people get wrong page on screen... I am not sure if something wrong in my code due to Server.TransferRequest.
Can any one give any suggestion?
public class SwitchMasterModule : IHttpModule, IRequiresSessionState
{
public void Init(HttpApplication context)
{
context.BeginRequest += Context_BeginRequest;
}
void Context_BeginRequest(object sender, EventArgs e)
{
var AppId = SiteSettings.ApplicationId().ToString();
if (HttpContext.Current.Request.CurrentExecutionFilePath.Equals("/default.aspx", StringComparison.InvariantCultureIgnoreCase))
{
HttpContext.Current.Server.TransferRequest(string.Format("~/Templates/{0}/default.aspx", AppId), true);
}
}
}
Moved from comment to answer.
It might be that SiteSettings.ApplicationId() returns incorrect value.
I don't know what the origin of the SiteSettings class is, but if it's not absolutely thread-safe, you could easily wind up with one user accessing the ApplicationId value appropriate for another user.

Application object cannot be used in ASP.NET web page

How to use Application object in the web page?
I thought it should be something like Session object.
But when I use Application, it shows the Reference like
System.Net.Mime.MediaTypeNames.Application
Obviously, it's not the one I'm looking for.
Has it been discarded in .NET 4?
If yes, what should I use to replace the Application object.
Are you referring to this one
Page.Application Property
Gets the HttpApplicationState object for the current Web request.
<%
this.Application["test"] = "some value";
%>
inside a WebForm should work. And in the code behind it's the same story:
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
this.Application["test"] = "some value";
}
}
The Application (HttpApplicationState) property is very much there.
Seems you have some references that are causing the confusion.
In your CS code on a Page you should be able to use it
this.Application["key"] = myObject;
It should work if you try to access it from an ASP.NET page. Application is a property of Page that returns the HttpApplicationState.
protected void Page_Load(object sender, EventArgs e)
{
if(Page.Application["Foo"] != null)
{
// ...
}
}
If you want to access it from a static context, you can use HttpContext.Current:
if (HttpContext.Current.Application["Foo"] != null){ }

Force Method to Run During Event

Is there a way to force methods to be accessible only during certain events during the page life cycle. For example, I have a extension to System.Web.UI.Page that adds a PrependTitle method.
I also have a masterpage that embeds another masterpage. The first masterpage sets the base title (Google), the next masterpage prepends the title (Calendar), and a page also prepends the title (21 May 2011).
The result should be:
21 May 2011 :: Calendar :: Google
And this is the case when the PrependTitle is run during the Page_Init event. However, when the method is run during Page_Load the following the results:
Google
So, that brings me to the question: How can it be enforced that a method only be accessible during specified life cycle events?
// The Method Mentioned
public static class PageExtensions
{
public static void PrependTitle(this Page page, string newTitle)
{
page.Title = newTitle + " " + Global.TITLE_DELIMITER + " " + page.Title;
}
}
I think this can be done similar to the following. The general idea is declare the method as private, declare the ones that should have access to it as sealed
class AppsBasePage : Page
{
abstract void PrependTitle(string title);
}
class PageWithTitlePrepended : AppsBasePage
{
private void PrependTitle(string title)
{
Title = String.Format("{0} {1} {2}", newTitle, Global.TITLE_DELIMITER, Title);
}
protected sealed override void Page_Init(object sender, EventArgs e)
{
PrependTitle("This is a title")
}
}
class ActualPageInApp: PageWithTitlePrepended
{
override void Page_Load(object s, EventArgs e)
{
// can't access PrependTitle here
}
}
This solves your question in bold, but I'm not convinced this situation is what is causing your problem with PrependTitle specifically. I think more code / context would be needed to solve your actual problem
If you want to brute force ensure that the method is being called from Init, you can inspect the call stack. Something like this:
public static bool CalledFromInit()
{
//Grab the current Stack Trace and loop through each frame
foreach(var callFrame in new StackTrace().GetFrames())
{
//Get the method in which the frame is executing
var method = callFrame.GetMethod();
//Check if the method is Control.OnInit (or any other method you want to test for)
if(method.DeclaringType == typeof(Control) && method.Name == "OnInit")
//If so, return right away
return true;
}
//Otherwise, we didn't find the method in the callstack
return false;
}
Then you would use it like:
public static void PrependTitle(this Page page, string newTitle)
{
//If we aren't called from Init, do something
if (!CalledFromInit())
{
//We could either return to silently ignore the problem
return;
//Or we could throw an exception to let the developer know they
// did something wrong
throw new ApplicationException("Invalid call to PrependTitle");
}
//Do the normally processing
page.Title = newTitle + " " + Global.TITLE_DELIMITER + " " + page.Title;
}
However, I'd caution that the stack trace isn't the most reliable thing. In release, code could get optimized such that the Control.OnInit method is inlined so your code wouldn't be able to see it in the call stack. You could wrap this check in an #if DEBUG block so it only executes during development. Depending on your use case, it might be good enough to catch this problem while in DEBUG and not bother doing the check in RELEASE. But that's up to you.
Another option...building on Tommy Hinrichs answer, if all your pages inherit from a base class, you'll be able to do it a bit more reliably. I'd suggest something like this:
public abstract class BasePage : Page
{
private bool _executingInit;
protected internal override void OnPreInit(EventArgs e)
{
_executingInit = true;
base.OnPreInit(e);
}
protected internal override void OnInitComplete(EventArgs e)
{
base.OnInitComplete(e);
_executingInit = true;
}
public void PrependTitle(string newTitle)
{
if (!_executingInit)
throw new ApplicationException("Invalid call to PrependTitle.");
Title = newTitle + " " + Global.TITLE_DELIMITER + " " + Title;
}
}
That way, PrependTitle will throw an exception unless it's called between PreInit and InitComplete (which sounds like exactly what you want).
As one last option, you could be sneaky and use reflection to access the Control.ControlState property (which is a confusing name because it's not related to Control State - the thing similar to View State). That property tracks the Control as it goes throw its lifecycle - and it has the following values:
internal enum ControlState
{
Constructed,
FrameworkInitialized,
ChildrenInitialized,
Initialized,
ViewStateLoaded,
Loaded,
PreRendered
}
You'll notice that Enum is internal. So is the Control.ControlState property. But with Reflection, you could use that - and you could even use it from an extension method that is external to the Page.
Hope one of those ways will work for you!
Your best bet is probably to use the Handles Keyword to attach the method to the event.
You might have to create a subclass of System.Web.UI.Page to ensure this is enforced.
It seems that the issue is in the prependTitle method, it should append the text to the page title not replace it.
Just call the PrependTitle method in the page_load of each mashterpage and page and append the text to the title.

How do I share a function that uses "Response" or "Request" in ASP.NET?

I'd like to have a utility function that conditionally updates my request and response across several pages in my site.
Using a standard .CS class doesn't seem to give me access to these objects. How can I (generall speaking) create a utility function that checks for a cookie and update it across multiple pages?
You can always get at these things via
System.Web.HttpContext.Current.Request
System.Web.HttpContext.Current.Response
HttpContext Class and the Current Property
Encapsulates all HTTP-specific information about an individual HTTP request.
And to manage some cookie value throughout your site I would suggest either create a BasePage class that all of your Pages inherited from and do the checks there:
public class BasePage : System.Web.UI.Page
{
protected override void OnPreRender(EventArgs e)
{
UpdateCookie();
base.OnPreRender(e);
}
}
do the same in your MasterPage:
public class SiteMasterPage : MasterPage
{
protected override void OnPreRender(EventArgs e)
{
UpdateCookie();
base.OnPreRender(e);
}
}
public static void UpdateCookie()
{
HttpContext context = System.Web.HttpContext.Current;
HttpCookie cookie = context.Response.Cookies.Get("Update")
?? new HttpCookie("Update");
int value = 0;
int.TryParse(cookie.Value, out value);
value++;
cookie.Expires = DateTime.Now.AddDays(30);
cookie.Value = value.ToString();
context.Response.Cookies.Set(cookie);
}
use HttpContext.Current.Request and HttpContext.Current.Response
Use the fully qualified namespace:
System.Web.HttpContext.Current.Request
System.Web.HttpContext.Current.Response
-- or --
using System.Web.HttpContext.Current;
Then you should be able to access Request/Response throughout your class.
There are several ways to do this. Other have mentioned doing this with System.Web.HttpContext.Current, but I'd think (guessing from what I think your intent is) that doing this on a method that runs on load on your master pages is a better idea.

Resources