Call function from code behind in Global.asax - asp.net

How can i access a control or function from asp page (code behind) in Global.asax?
i use below code for background task, this code check for new emails every 60 seconds and i want to update a label that show new email's count in default.aspx
void Application_Start(object sender, EventArgs e)
{
AddTask("CheckEmails", 10);
}
private void AddTask(string name, int seconds)
{
OnCacheRemove = new CacheItemRemovedCallback(CacheItemRemoved);
HttpRuntime.Cache.Insert(name, seconds, null, DateTime.Now.AddSeconds(seconds), Cache.NoSlidingExpiration,
CacheItemPriority.NotRemovable, OnCacheRemove);
}//addTask
public void CacheItemRemoved(string k, object v, CacheItemRemovedReason r)
{
//Check New Emails and update label from .aspx
AddTask(k, Convert.ToInt32(v));
}//CacheItemRemoved

Create a seperate class for common function, put it in app_code folder, then access this function from Default.aspx and global.asax....

why do you to do this. Kindly provide some more information.
Though you can create an object of Default page and call it's function.
But still if that is not related to the page then only it is good to use.
Edit 1
You don't need it to call from application start.
You can call this function on your page load(which is called after login page).
You can check for the existing value in the cache with the same key.
If it exist then don't modify the cache
Else Put your values in the cache.

Related

Context is null in the global.asax file

I have global.asax file, and I use this two functions to update cache value every 15 seconds by this code:
protected void Application_Start(object sender,EventArgs e)
{
Context.Cache.Insert("value","some value",null,DateTime.Now.AddSeconds(15),Cache.NoSlidingExpiration,CacheItemProirirt.Default,new CacheItemRemovedCallback(updating));
}
private void updating(string key,object value,CacheItemRemoveReason reason)
{
Context.Cache.Insert("value","updated value",null,DateTime.Now.AddSeconds(15),Cache.NoSlidingExpiration,CacheItemProirirt.Default,new CacheItemRemovedCallback(updating));
}
but it give me an NullReferenceException, and the context is null, please why I can't use context at the "updating" function?
Application_Start doesn't have any context.
The first event that does is Begin_Request.
Application_Start occurs when the particular website gets fired up for the first time, or after been recycled.
To keep the cache item renewed I suggest you do that in the Begin_Request, where you check if it's there, and if not, initiate it again.
This way it's only use memory while the site is being hit, otherwise not.

ASP.NET Session and Page Life Cycle

Let's say that in an ASP.NET .aspx page I have the Page Load method and another method for a button click event.
In the Page Load method I'm checking if the user is logged in by checking the Session. Whether he is or not, I'm storing the result in a Global Variable.
Boolean isGuest = false;
protected void Page_Load(object sender, EventArgs e) {
if(Session["id"]==null)
isGuest = true;
else
isGuest = false;
}
Let's say 20 minutes have passed, and I don't know if the Session has terminated or not, and then I click a Button, the event goes like this:
protected void Button_Click(object sender, EventArgs e) {
if(isGuest==false)
//do something
else
// do another thing
}
My Question is : When I'm clicking the button, does ASP.NET go through the Page_Load method again (check isGuest again) or it simply executes what's inside the Button_Click method, means, it uses a Boolean isGuest that could be false, but in reality the session is terminated, means it should be true.
Page_Load is triggered always before the control events.
Have a look: ASP.NET Page Life Cycle Overview
Side-note: If you want to do things only on the first load and not on every postback you have to check the IsPostBack property.
You can:
Define your own class with the UserID, and other profile properties;
Add that class to session in the global.asax session started event Session["NameReferingToYourClass"] = new YourClass();
Set a member variable to your session object early in the page life cycle mYourClass = Session["NameReferingToYourClass"] casted if you need to;
Then you can make any changes to your class anywhere in the code your member variable is available;
Save back your class with all the changes into session on the Page.Unload(..){ Session["NameReferingToYourClass"] = mYourClass.
This way you are using your class properties in your code, including UserId, pretty much like a windows application, there will be no mentioning of session anywhere else in your code.

User ID initialization on Master Page?

I have a site with multiple pages, not necessarily heirarchical. I want to query the user's identity (using AD...) whenever the user first enters the site, and create session state variables for the convenience of other pages as needed. A user could possibly enter the site without going through the default.aspx page, so I thought I'd put the code in the Master Page's code-behind.
On the assumption this is a good idea, versus some sort of static class that maintains this information, I started setting it up, but found the Master Page code-behind doesn't always seem to get fired when I enter the site. Is this a debugging phenomenon, or am I right, and the Master Page is the wrong place to put this code...?
I would recommend using the Global.asax class. You'll need to add it to your web app if it's not already there. Once you have it, you can then use the various events (session start and end, app start and end and error) to implement business logic particular to what you need exactly.
I tend to monkey around with the logged in user in the Application_PreRequestHandlerExecute event of the global.asax. This will allow you to look at the User Principle (eg - User.Identity.Name) to see who is logged in (or if they're not logged in) and do what you need to (such as set Session information for the user, etc.).
Here's a tidbit of code I've got on one .NET web app that uses the Global.asax for storing user data in the Session.
protected void Application_PreRequestHandlerExecute(Object sender, EventArgs e) {
if (Context.Handler is IRequiresSessionState || Context.Handler is IReadOnlySessionState) {
SetUserItem();
}
}
private void SetUserItem() {
if (Session["UserItem"] == null)
Server.Execute("~/SetSessionUserObj.aspx", true);
}
... and then the SetSessionUserObj.aspx.cs
protected void Page_Load(object sender, EventArgs e) {
string ID = User.Identity.Name;
MyUser myUser = new MyUser();
UserItem userItem = myUser.GetUserItemByID(ID);
if (userItem != null) {
Session["UserItem"] = userItem;
}
}
This is just one manner that you can go about accessing a user's identity in the global.asax. You don't necessarily have to go about doing a Server.Execute to set user data (I just did it for other reasons that fall outside the scope of this question).
Good luck.

Ajax Control Toolkit AsyncFileUploader Control and viewstate/session Issue

in my project i need to upload files so i decided to use the uploader provided by asp.net ajax controls AsyncFileUPloader control.
there are four blocks. every block contains two such uploaders
so i decided to utilize the power of asp.net web user controls.
i wrapped the required form fields in my user control called DesignUploader.ascx
now i have to put the four instances of this control on my aspx page
please refer the snap below
my problem starts here i have to insert the fileurl to the database and each of the block generates unique id and id value changes after uploading the file to the server. i noticed that viewstate does not work for me in case of asyncfileuploader it clears the viewstate because it does the secret postback to the server behind the scenes. now only option left for me is to use session but when user uploads the files in two blocks one after another then filepath from second/third consecutive blocks overwrite my session. i don't know how many blocks user can use to upload the designs he may use 1 only or he may use all four.
There would be a final submit button in the bottom of the page on click of which i have to insert data to database.
so when i tried to save the data to database the session stores the value of the recently uploaded file path for all the records my problem lies here
i don't know if i was able to describe my problem in correct manner or not please excuse me if it is not clear and post comment if required.
Note: I can not change the UI because client insists for this only :(
any quick work around would be appreciated much
Thanks
Devjosh
I believe you saving file path to session in a wrong way and it's impossible to recognize where is an error without code.
All the way, in my opinion better don't persist file path in session but use client side for that purpose instead. You can add two hidden fields to DesignUploader.ascx control and set their values in UploadedComplete event handler.
public partial class DesignUploader : System.Web.UI.UserControl
{
private static readonly string AppDataPath = HttpContext.Current.Server.MapPath("~/App_Data/");
public string FirstFilePath
{
get
{
return Server.UrlDecode( FirstFilePathHiddenField.Value);
}
}
public string SecondFilePath
{
get
{
return Server.UrlDecode(SecondFilePathHiddenField.Value);
}
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
FirstFileUpload.UploadedComplete += FirstFileUpload_UploadedComplete;
SecondileUpload.UploadedComplete += SecondileUpload_UploadedComplete;
}
void FirstFileUpload_UploadedComplete(object sender, AjaxControlToolkit.AsyncFileUploadEventArgs e)
{
var fullPath = Path.Combine(AppDataPath, Path.GetFileName(e.FileName));
FirstFileUpload.SaveAs(fullPath);
SaveFilePathToHiddenField(FirstFilePathHiddenField.ClientID, fullPath);
}
void SecondileUpload_UploadedComplete(object sender, AjaxControlToolkit.AsyncFileUploadEventArgs e)
{
var fullPath = Path.Combine(AppDataPath, Path.GetFileName(e.FileName));
SecondileUpload.SaveAs(fullPath);
SaveFilePathToHiddenField(SecondFilePathHiddenField.ClientID, fullPath);
}
private void SaveFilePathToHiddenField(string fieldId, string pathValue)
{
var script = string.Format("top.$get('{0}').value = '{1}';", fieldId, Server.UrlEncode(pathValue));
ScriptManager.RegisterStartupScript(this, this.GetType(), "setPath", script, true);
}
}

How do you stop a page_load event from running if the page is refreshed

Each time my webpage is loaded it runs a routine in the page_load event of the page behind which increments a viewcount by 1.
The problem I have is that the routine runs even if use refresh to reload the page.
How do I stop this routine from running if the page has been viewed by a particular user in their current session?
I thought I could use:
If Not Page.IsPostBack Then
(run the routine)
but it does not seem to work.
Do I need to use session state or cookies etc.?
The If Not Page.IsPostback will only help if the user clicks a button on that page. If the user just refreshes the page (like using F5) it won't work.
The problem is
do you want to add to the counter if the user comes back to the page after he's been to another page on your site (i.e. homepage -> productpage -> homepage) or not.
You could use a Dictionary and store it in the user's Session. The Dictionary would be a Dictionary of type Dictionary<string, int>. When the user visits the page, you retrieve the dictionary and see if there is already an entry for the current page + querystring (the string Key).
if not, add it. Then depending on whether you want to increment the count for that page if the user revisits the page after first going to another page increment the counter (or not).
you can check if the user's came from another url by using: Request.UrlReferrer
You could record whether the user has visited the page within the session. You could just place a bool within the session under the page path. This way it'll scope to the individual user and it'll work for the duration of their session.
To record that the user has visited the page you could do the following:
HttpContext.Current.Session[pagePath] = true;
and to get whether the user has visited the page you could do this:
bool hasUserVisitedPage = (bool)HttpContext.Current.Session[pagePath];
Here's how it would come together within your page load:
protected void Page_Load(object sender, EventArgs e)
{
//set the default for whether the user visited the page
bool hasUserVisitedPage = false;
//get the path of the page
string pagePath = HttpContext.Current.Request.Url.LocalPath;
//find out if the user visited the page by looking in the session
try { hasUserVisitedPage = (bool)HttpContext.Current.Session[pagePath]; }
//we don't care if the value wasn't present (and therefore didn't cast)
catch {}
//if the user hasn't visited the page before
if (!hasUserVisitedPage )
{
//record that the page has now been visited
HttpContext.Current.Session[pagePath] = true;
//put the rest of your load logic here...
}
}
If you want to incorporate this technique on multiple pages I'd encapsulate this functionality into a helper class so you don't keep repeating yourself.
public static class PageHelper
{
public static bool hasPageBeenViewed()
{
//set the default for whether the user visited the page
bool hasUserVisitedPage = false;
//get the path of the page
string pagePath = HttpContext.Current.Request.Url.LocalPath;
//find out if the user visited the page by looking in the session
try { hasUserVisitedPage = (bool)HttpContext.Current.Session[pagePath]; }
//we don't care if the value wasn't present (and therefore didn't cast)
catch {}
//if the user hasn't visited the page before
if (!hasUserVisitedPage )
{
//record that the page has now been visited
HttpContext.Current.Session[pagePath] = true;
}
return hasUserVisitedPage;
}
}
Then it'd greatly simplify the load logic to the following:
(It would give you the added benefit of the logic being in a central location, which would be very handy if you needed to change it)
protected void Page_Load(object sender, EventArgs e)
{
//if the user hasn't visited the page before
if (!PageHelper.hasPageBeenViewed())
{
//put the rest of your load logic here...
}
}

Resources