I want to get a type of a "BasePage" object that I am creating. Every Page object is based off BasePage. For instance, I have a Login.aspx and in my code-behind and a class that has a method Display:
Display(BasePage page) {
ResourceManager manager = new ResourceManager(page.GetType());
}
In my project structure I have a default resource file and a psuedo-translation resource file. If I set try something like this:
Display(BasePage page) {
ResourceManager manager = new ResourceManager(typeof(Login));
}
it returns the translated page. After some research I found that page.GetType().ToString() returned something to the effect of "ASP_login.aspx" How can I get the actual code behind class type, such that I get an object of type "Login" that is derived from "BasePage"?
Thanks in advance!
If your code-beside looks like this:
public partial class _Login : BasePage
{ /* ... */
}
Then you would get the Type object for it with typeof(_Login). To get the type dynamically, you can find it recursively:
Type GetCodeBehindType()
{ return getCodeBehindTypeRecursive(this.GetType());
}
Type getCodeBehindTypeRecursive(Type t)
{ var baseType = t.BaseType;
if (baseType == typeof(BasePage)) return t;
else return getCodeBehindTypeRecursive(baseType);
}
After some additional research I found that if I call Page.GetType().BaseType it returns the code-behind type of the Aspx page.
page.GetType().BaseType, it has been said before, but let me elaborate as to why.
Aspx pages inherit from their code-behind pages, meaning that the inheritance hierarchy looks like this:
...
Page
BasePage
Login
ASP_Login
Where the top is the parent and the bottom is the child.
This allows your code behind to be accessible from the aspx page, without requiring all of the generated code related to your actual aspx page to be copied into the base class page.
It depends where you're calling Display() from. If you're calling it from the ASPX, then you'llse "ASP_login.aspx". If you're calling it from the code-behind (i.e. the Page_Load() method) you should get the Login page type.
Instead of passing the Page in, you might consider just using the Page property (i.e. this.Page.GetType()) which should always be the current page/codebehind type, if I recall correctly.
I should also make the point that you might consider moving this sort of stuff out of the ASPX/codebehind and into some sort of service. It's generally a good idea to minimize the amount of things you do in a code behind and, instead, push logic into a presenter class and follow the MVP pattern for ASP.NET Web Forms development.
Related
I have a routine which finds all the controls on a page, which I then apply some changes to.
The routine works quite well but I will have to add the chunk of code to every master page and content page to get my results.
I would like to create a single sub routine (which will be in a module) which when called from each page will carry out the work. The only thing I think I need to do to do to make this work is to be able to pass the page name the controls are on to the sub routine to run my routine and have the module make the changes I require to the page I pass to it.
I am sure this is an easy process, but for the life of me I can’t work it out. Can someone help me on how to pass the page name so the routine will apply the changes to that page?
I am using asp.net in Visual Studio 2010, and the code behind is vb.net.
My routine is written in the code behind, not java or aspx. I don’t care if the answer is in C# or vb.net as I can convert if required.
Thanks in advance
Chris
You can send this.Page.UniqueID value as a parameter to the subroutine when you call it from the module.
If you want the current page's class name use:
this.GetType().Name;
If your page inherits from another page, you would use:
this.GetType().BaseType.Name;
What I would do is create a base page that all your pages inherit from and put your FindAllControls() method there.
Here's an example of what that might look like:
using System.Web.UI;
public abstract class BasePage : Page
{
public void FindAllControls()
{
var currentClassName = this.GetType().BaseType.Name;
// Do stuff.
}
}
Then, for example, if you had a Login page, it would look like this:
using System;
public partial class Login : BasePage
{
protected void Page_Load(object sender, EventArgs e)
{
this.FindAllControls();
}
}
This is possibly very lame question and I lack knowledge about ASP.Net. In this case a link to an article explaining would be very welcome.
I'm working on web-site on ASP.NET with C# as codebehind. My current project involves developing few pages with very similar functionality and a many functions are the same. For example
private void PermissionCheck()
{
if (null == Session["UserID"] ||
null == Session["ProjectID"] ||
null == Session["AssetID"] ||
null == Session["ProjectName"])
{
Response.Redirect("~/Login.aspx");
}
}
Would be the same on 2 pages. Some other things are the same as well. I would like to put this into common base class. But there are other functions that don't really belong to pages at all:
private string GetAttachmentTempPath()
{
return Request.PhysicalApplicationPath + WebConfigurationManager.AppSettings.Get("AttachmentsTempFolder");
}
I would like to move this into Attachment class, but to get the physical path of the application, I need to pass in Request object into that method, which is not really nice, as it couples Attachment class with Page.Request object.
Is there any way to move these functions somewhere else without needing to pass Page.Request objects around??
p.s. The appliction is huge, and there is no scope to change the entire architecture.
For your permission thing you could make a base page class:
class BasePage : Page
{
...
protected override OnInit() {
// do check here
}
}
Now you can implement your page like this class MyOtherPage : BasePage { ... }
The OnInit gets executed everytime your MyOtherPage gets loaded.
You can see a complete page lifecycle here: Link
For your other problem: Consider to implement a global available static tool class
Update
A good approach for making things like web.config easier to access is a Singleton. In asp.net a singleton is only created once and lives until the asp worker process gets stopped . So this values are shared across the whole asp.net application. This is also good for storing data in a global context that you dont want to get out of your database or file anytime a user makes a page request (for example a version number or things like that)
Update 2
To access the request without passing it to every function, use this:
HttpContext.Current.Request
Base page is a good option for reusable code in Page level. Other than that for things like configuration values it's good to come up with utility classes specifically for those methods base don there type of operations.
If you need to avoid passing in Page object into these types of utility methods,
HttpContext
class would be handy because you can access many of the ASP.Net object through static members through this class. HttpConext # MSDN
If you have similar functions behind the page, you can use ASP.NET WEb User Control.
You can create the functions in the usercontrol and use the control in the pages where necessary.
Have look at this article about Web User Control in Asp.Net
I'm trying to extend ScriptManager to simplify dealing with resources that have multiple resource files (e.g. more than one script file as well as css). The goal is that I will be able to add a single ScriptReference to Scripts and have it load more than one resource related to that reference name.
What I'm getting stuck on is, how does your basic ScriptManager know what to do with stuff when when using static methods that do not include a Page parameter? For example:
ScriptManager.ScriptResourceMapping.AddDefinition("someName", new
ScriptResourceDefinition { Path="/script/somescript.js"});
This adds a definition to (I guess) whatever the active script manager is for the page that's running when you call it. But unlike the old-school methods, like RegisterClientScriptBlock there is no parameter passed that identifies the page. But this stuff must get stored in the ScriptManager object, no? So how does it know?
I could always get a reference to the active one with this:
ScriptManager.GetCurrent(page);
but ideally, I would create new methods that work exactly like Microsoft's. I can't figure out how I could implement something like
ScriptManager.ScriptResourceMapping.AddDefinition(string name,
ScriptResourceDefinition definition,
ResourceType type)
that could figure out the object instance to add the stuff into without having to add a Page parameter. Somehow they're doing it... how can I?
You get the page reference through (Page)(HttpContext.Current.Handler) even in a static context.
How can I find the name of (default.aspx ) current page or web control in the code behind?
I want to write a superclass that uses this name.
You mean that you want to find the original filename of the object that is currently executed? I.e., from inside a control MyControl you want to retrieve MyControlOnDisk.ascx? In general, this information is lost upon compiling, and moreover, many pages and controls are built on partial classes and the filenames they're from are compiled into a single assembly.
For a page, you can use the following, but only if the page is not internally redirected, is not instantiated as a class from another page, it is not a master page and you're not inside a static method:
string currentPageFileName = new FileInfo(this.Request.Url.LocalPath).Name;
In the case of a control, it is generally not possible as far as I know (it is compiled away), but perhaps someone can shed some light on this.
"i want to write a superclass that use this name "
I assume you mean to write a subclass? If you write a superclass you just create a virtual method and have it implemented in your subclass (the page). If you mean to create a subclass, you can take the classname of the page, which looks like this:
// current page
public partial class MyLovelyPage : System.Web.UI.UserControl
and use it like this to derive from it:
public partial class NewDerivedPage : MyLovelyPage
I would recommend an alternative:
Server.MapPath(Page.AppRelativeVirtualPath)
This works with ASP.Net to get the full path and filename for the current page.
Request.ServerVariables["SCRIPT_NAME"]
if you not use Routing :
string sPath = HttpContext.Current.Request.Url.AbsolutePath;
string[] strarry = sPath.Split('/');
int lengh = strarry.Length;
string sRet = strarry[lengh - 1];
The situation is this:
I have an abstract class used globally that used to reference a Session variable via a public property. We now want to change its behavior to return a property on a master page.
(By simply changing the guts of this particular property, we hope to avoid doing a lot of rewrites)
This is just a snippet of the class:
public abstract class AppSession
{
public static CaseNumber CurrentCaseNo
{
/* OLD METHOD DELETED */
get
{
if (CurrentPage.Master != null)
// property on the master page
return CurrentPage.Master.CurrentCaseNo;
else
throw new Exception("This page has no master page");
}
}
}
Above, "CurrentPage" is not real/valid. I just wrote that there to show context.
Is this even possible?
Thanks!
J
Look at the HttpContext.Current object. I believe it's Handler property will return the currently executing page. It would be easier to read a value stored in the Session that pulling it out of a property since the Session is available off of HttpContext.Current.
Building on David's answer, this can be used statically throughout your application:
Page myPage = System.Web.HttpContext.Current.CurrentHandler as Page;
if( myPage != null )
return ((MyMaster)myPage.Master).CurrentCaseNo;
I think that you would need to work with something that took a "page" object in as a parameter, and from there, you could determine if the page that was passed is your master page. And do what you need from there....
But that adds quite a bit of overhead.
The real question here is what are you trying to avoid? Trying to get rid of session and move to viewstate?