How do I access a page class from another class. For example I have:
public partial class MyPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{ }
}
Why can I not access it from another class in App_Code folder?
public class MyClass
{
public MyClass() {}
public void DoSomething(object o)
{
// The following line won't compile.
MyPage page = o as MyPage;
}
}
I just figured it out (thanks to Fujiy) that for some reason this is the case with website project, but is not a problem with web application project in VS. If anyone has any clues as to why, please share your thoughts. Thank you :)
I see nothing wrong with your code as posted, most likely you've got a namespace problem.
edit: gah, just noticed that you mentioned this was a website project. It's been a while since I deigned to start one of those :) but I believe this stems from the fact that App_Code is run-time compiled. It would take a better man than me to explain why that creates the problem, but long story short I'd just avoid website projects in general.
You can do this, afaik:
System.Web.UI.Page page = System.Web.HttpContext.Current.Handler as System.Web.UI.Page;
Be careful where you call that though, because obviously at different points in your code the page won't be available. For example, Application_Start in global.asax.
Related
I'm using a public LoginContext class to manage user logins in my web app.
Unfortunately, even though I have the LoginContext class declared publicly, my partial class Login at Login.aspx.cs can't seem to access it.
My code is as follows:
// ~/App_Code/LoginContext.cs
namespace stman
{
public class LoginContext
{
}
}
// ~/Login.aspx.cs
namespace stman
{
public partial class Login : System.Web.UI.Page
{
protected void btnLogin_Click(object sender, EventArgs e)
{
LoginContext log = new LoginContext(); // error is here
}
}
}
The error that comes up on the line where I instantiate LoginContext reads as follows:
The type or namespace name 'LoginContext' could not be found (are you missing a using directive or an assembly reference?)
When I try to generate a new class for LoginContext, it goes into the web app's root folder where it can no longer access the public Database class that I need in LoginContext.
I have no idea what's causing all of these problems, but based on what I've learned over the last 18 months doing this professionally, they shouldn't exist right now...
Can anyone help clear things up here? Specifically I'd like to know:
What I'm doing wrong
Why it's wrong
Who can I fix it?
Thanks in advance!
EDIT
I've had a look and it seems neither the Database class in ~/App_Code/Database.cs or the LoginContext class in ~/App_Code/LoginContext.cs are accessible to the page - or any page in the website.
In LoginContext.cs properties, marked it as BuildAction = Compile.
You can achieve this behaviour when these classes are located in different projects.
If this is true then you should use full path to the class starting from the project name
ProjectName.stman.LoginContext
try using constructor
namespace stman
{
// Database is a class that handles the sql queries and such
public class LoginContext : Database
{
public LoginContext () : base("Name=LoginContext")
{
}
}
}
From what I read from the App_Code behavior may be different in web site projects and web application. I wonder what kind of project you're working on? One possible solution would be to make this project in web application project, this Link can help you to make this project:
Source
I am trying to inherite a base global.asax class to create my custom global.asax class. But my custome inherited global class does not work properly. Its Application_Start wont been called.
Anyone knows whey?
public class BaseGlobal : HttpApplication
{
protected void Application_Start(Object sender, EventArgs e)
{
log4net.Config.XmlConfigurator.Configure();
Logger.Warn("Portal Started"); //I can find it log file
}
......
}
public class MyGlobal : BaseGlobal
{
new protected void Application_Start(Object sender, EventArgs e)
{
base.Application_Start(sender,e);
Logger.Warn("Portal Started 2"); // Can not find it in log file
}
}
<%# Application Codebehind="Global.asax.cs" Inherits="Membership_ABC.MyGlobal" Language="C#" %>
In the log file, I could not find "Portal started 2" but just "Portal Started".
Any ideas?
On startup of an application, the runtime takes the HttpApplication descendant that is pointed out by the Global.asax file, and creates an instance of it. The runtime does not know or care how the class got to be descended from HttpApplication, it just cares that it is, in fact a descendant.
After that it start calling method on it, treating it as a regular HttpApplication object. Since the new modifier effectively breaks the inheritance chain (it's just a new method that happens to share the old methods name) it is not called, but instead the method of the parent class is called. Basically you have this situation (pseudocode):
HttpApplication httpApp = new MyGlobal();
httpApp.Application_Start(..)
// ^^^ calls BaseGlobal.Application_Start(..)
//because the is not an unbroken chain from HttpApplication to MyGlobal
This is an example and consequence of the Brittle Base Class problem, a topic about which Eric Lippert has written in depth.
The solution is to declare the function virtual in the base class and then override it in the child class.
But as you can't edit base class to declare the Application_Start method virtual, it won't work :
Is it possible to override a non-virtual method?
The accepted answer gives an example that matches your case.
I created a empty web part, then created a usercontrol, in UserControl.ascx.cs, I wrote like that:
namespace tasks_email.ControlTemplates.tasks_email
{
public partial class UserControl1 : UserControl
{
public tasks_email WebPart { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
then it said:"tasks_email.Controltemplates.tasks_email" is a 'namesspace' but is used like a 'type'
Can any body tell me where the problem is and give me some suggestion?
If you want to create a webpart with a user control inside of it you can just use the "Visual web part" template in visual studio. It will create a webpart, and a user control, and add the user control to the webpart all for you, and even package the whole thing into one collapsible component in solution explorer. It's quite convenient. Doing all of that work yourself (for every new webpart) is just a pain.
namespace tasks_email.ControlTemplates.tasks_email
Here you declare tasks_email as a namespace.
public tasks_email WebPart { get; set; }
Here you declare a member called WebPart, with a type tasks_email. That's not a type - you've already said it's a namespace. I can't guess what you really meant.
Did you try "namespace tasks_email.ControlTemplates"? Because the way you do it, you use tasks_email like a type indeed ; and not as a namespace
I have a code behind file of an aspx file that looks like this:
public partial class Pages_MyPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
.....
}
protected int MyMethod()
{
.....
}
[WebMethod]
public static int MyPageMethod()
{
int x = MyMethod();
return x;
}
}
When I'm sending an ajax POST to MyPageMethod, I can't access MyMethod. What's the way around this issue.
Thanks for your suggestions.
MyMethod will also need to be static.
Think about what your trying to do here -
MyMethod belongs to a specific instance of a class.
MyPageMethod belongs to the class itself.
If your running code inside MyPageMethod, how could you possibly know how to call methods on some other instance of the object. The instance methods may as well not exist at that point in code.
If you are trying to mutate some portion of the page's data from javascript, you have a deep misunderstanding of how asp.net pages work.
At the point javascript is running in the browser, your page object is gone. The server finished the page load and discarded it. On the next post back it will create a new instance, and run through the page life cycle once again.
If you need to access page level state, you will have to store it in a place that is acceptable between post backs, the Session object for instance, with System.Web.HttpContext.Current
WebMethods are static methods because they don't get a full Page.
They can only call other static methods
If I override the System.Web.UI.Page constructor, as shown, when does DoSomething() get called in terms of the page lifecycle? I can't seem to find this documented anywhere.
namespace NameSpace1
{
public partial class MyClass : System.Web.UI.Page
{
public MyClass()
{
DoSomething();
}
protected void Page_Load(object sender, EventArgs e)
{
}
}
}
For reference, here is the ASP.NET Page Lifecycle Overview:
http://msdn.microsoft.com/en-us/library/ms178472.aspx
Turns out the best answer was right in the MSDN article. I just had to look carefully at the diagram. Construct is the very first event in the Page life cycle (comes before PreInit, Init, Load, etc).
Diagram http://img156.imageshack.us/img156/9246/lifecyclen.jpg
DoSomething(); will be called before member methods. That's not about Page Lifecycle actually. It's about classes and instances. ASP.NET creates an instance of MyClass. (Contructor is executed). After that any other member methods can be called.
To answer your question, an instance is created at step 10:
http://msdn.microsoft.com/en-us/library/ms178473.aspx
Scroll down to "The request is processed by the HttpApplication pipeline."