Is it possible to create new ASP.NET directives? - asp.net

You know how ASP.NET pages typically begin with a Page directive setting certain properties and behaviors for the page? Looks like this:
<%# Page Title="Contact Us" Language="C#" MasterPageFile="~/Site.master"
AutoEventWireup="true" CodeFile="ContactUs.aspx.cs" Inherits="ContactUs" %>
The whole list of currently available directives is here:
http://msdn.microsoft.com/en-us/library/t8syafc7.aspx
Does anyone know if it is possible to create new directives?
For example, I'm using reflection to do certain things with pages on the site and I decorate their class declarations with custom attributes. I'd like to know if it's possible to somehow do that even when there isn't a code behind or designer file to find such a class declaration, and all the scripts for the page are in the script tag that's run on the server side.
P.S. I'm aware that I could use the Page directive to set the base class and then also use it to set inherited properties. However, there can be 0 - n of these attributes, so that couldn't be done elegantly.

Related

How to Access PagesSection Property in Code-behind of Asp.NET

I'm in the code behind of a user control. I need to access one of the page's properties (EnableSessionState).
Originally, this would be defined something like this in aspx:
<%# Page Language="C#" EnableSessionState="ReadOnly" %>
However, I want to dynamically change this value in the code behind.
I looked at this answer:
PagesSection pages = WebConfigurationManager.OpenWebConfiguration("").GetSection("system.web/pages") as PagesSection;
pages.EnableSessionState = PagesEnableSessionState.ReadOnly;
Unfortunately, I'm just trying to read the header. Also considered this answer:
PagesSection pagesSection = new PagesSection();
pagesSection.EnableSessionState = PagesEnableSessionState.ReadOnly;
But I'm not trying to read default values, I'm trying to set the actual page's values.
Unfortunately, there is no property like this.Page.PagesSection, so is there another way of going about this?
Since the goal was to modify session state behaviour, according to this blog, it is possible to access using the following line:
Context.SetSessionStateBehavior(SessionStateBehavior.ReadOnly);

Copied page designer file reverting to original class name

I needed to make a new page which was very similar to another so I simply copied it and renamed both the file and the class name within the code.
So far so good.
However, if I make a change to the markup, the designer file in the new page forgets the new class name and reverts to the old one causing compile errors.
It is easy enough to fix but is there some way of making the change stick rather than having to do this each time?
Also, should I have cloned the page a different way?
Well, I thought this was just a feature but when I ran the new page it routed to the old one.
On inspection, the problem was this line:
<%# Page Language="vb" AutoEventWireup="false" Codebehind="WibbleNew.aspx.vb" Inherits="Wibble"%>
I had changed the Codebehind section but not the Inherits, so it should have been:
<%# Page Language="vb" AutoEventWireup="false" Codebehind="WibbleNew.aspx.vb" Inherits="WibbleNew"%>
I did say it had been a while... :-/
You could put the common features in a master page and then just create separate pages for the two sets of differences.
There is a good intro to that here: http://www.w3schools.com/aspnet/aspnet_masterpages.asp

Add common layout in asp.net

This is not an MVC project.
I already created the layout for the site.
I want to add this layout for every page I create. How to add layout for every page?
I tried with the link below but it doesn't work.
<%# Register src="Layout.aspx" tagname="Layout" tagprefix="abc" Inherits="Layout" %>
An ASPX is not intended to be "included as a layout".
I think you are looking for something named "MasterPage" : see this for example : http://www.w3schools.com/ASPNET/aspnet_masterpages.asp , or https://msdn.microsoft.com/en-us/library/fft2ye18%28v=vs.140%29.aspx and all relative pages.
And if you wish to develop some common component for your pages, look for usercontrols (ASCX).

A Base page in ASP.NET

Do you recommend from every web site created in Visual Studio, that you should create a Base page that serves as the parent class?
What are the exact benefits/drawbacks?
If you want to override the way something in ASP.NET works, it can be more efficient to build it into a base class rather than including the code in every page. Two specific instances where I've done this are:
IsPostback
Little-known fact: it's quite feasible to craft a request that, to ASP.NET, looks like a postback but is submitted with a GET request. Who does this? Hackers, that's who. A call to IsPostback in this case will return true, but it shoud really return false. To get round this, build a base class that overrides IsPostBack:
Public Class MyBase
Inherits System.Web.UI.Page
<DebuggerStepThrough()> _
Public Shadows Function IsPostback() As Boolean
'Check the built-in IsPostback and make sure this is a HTTP POST
Return (Page.IsPostBack AndAlso Request.HttpMethod.ToUpper = "POST")
End Function
End Class
Error Handling
In Beginning ASP.NET Security, Blowdart talks about the fact that if you use ASP.NET's error handling to redirect the client to a custom error page, hackers (again) can detect the redirection and flag it as an error that may be exploitable. A more secure pattern is to handle the Page's Error event and do a Server.Transfer (which doesn't send anything to the client). Again, doing this in a base class means you only write the code once:
public partial MyBase : System.Web.UI.Page
{
protected void Page_Error (object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
// Do something with the exception e.g. log it
...
Server.Transfer("~/mycustomerrorpage.aspx");
}
}
Yes, I do.
But please remember that the purpose of a base page is totally different from the purpose of a master page.
Let me explain.
Master pages
are layout elements used to share the same graphical features and part of the webforms behaviour (think a login/logout box with code-behind) across all pages that are associated to the master. Your final page classes will include a reference to the master page so the final result will appear as the master page including your page (check the source code to tell who contains whom)
Base pages
are (abstract? at least not sealed!) classes from which all your pages inherit from the code-behind view. Unless you explicitly and programmatically add controls to the basae page, ie. in the constructor via LoadControl method, all pages will look blank from the very beginning until you add code.
But often they are useful. If you want to override some of the base class methods, you can have the overriden behaviour shared across all pages. Or, you may want to expose application-specific objects to the children pages (a reference to a data access layer, a logger or whatever). An example is overriding UICulture property to retrieve the user-preferred language from cookies.
Both can be combined
Depending on your goals, you may combine master pages with base pages.
I suggest you to always create a base page class, since if your application's requirements change over time and you already created lots of pages, you can try to modify the base class to have the modifications propagated to all pages, according to the level of complexity of them.
Check out masterpages this is their primary purpose.
Here's a link: http://msdn.microsoft.com/en-us/library/wtxbf3hh.aspx
This will serve as the template for your site. You would add a content section that would make up the body of your site. You can reference the master page is your subpages to have a consistent layout, menu, etc. for you site.
Also, like the others have noted. If you are running any commond code, just create a class a reference it from wherever you need it.
It depends on the size and complexity of your project. For small websites with minimal functionality, a base page might be overkill. That said, I would typically use it for site-wide functionality, such as security. I tend to keep functionality in the master pages to a minimum since their primary purpose is to organize your layout and factor out common display areas from you content pages to avoid duplication and ease maintenance.
To create a base page for use in a master page scenario, you could use the following syntax:
Master Page:
<%# Master Language="C#" AutoEventWireup="true" CodeBehind="MyProject.master.cs"
Inherits="MyProject.MasterPages.MyProject" %>
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
Base Page:
<%# Page Title="" Language="C#" MasterPageFile="~/MasterPages/MyProject.Master"
AutoEventWireup="true" CodeBehind="BasePage.aspx.cs"
Inherits="MyProject.BasePage" %>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1"
runat="server">
</asp:Content>
Content Page:
<%# Page Title="MyProject - Home" Language="C#"
MasterPageFile="~/MasterPages/MyProject.Master" AutoEventWireup="true"
CodeFileBaseClass="MyProject.BasePage" CodeFile="Default.aspx.cs"
Inherits="MyProject.Default"
Meta_Description="Code Snippet: Master Page and Base Page"
Meta_Keywords="master, base, content" Theme="Style" %>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1"
runat="server">
</asp:Content>
If you need common functionality on all your pages that belongs to the page class, create a common base class.
If you don't need such common functionality on all your pages, don't create a common base class.
If you can't decide, having a base class isn't going to hurt anybody, so you might as well have one (I'd say you more often end up needing some common functionality than not)

master page menus

I want to create a master page for my already developed project.Since the project contains many forms it is quite difficult to include the master page in each form...Is there any possibilities to include the master page in any other simplest way...
Please give some suggestions..
Thanks in advance...
As far as I know, there is no easy way to do this.
You'll have to manually add the masterpage to the page directive
<%# Page MasterPageFile="~/Masterpage.master" ... %>
add the relevant content sections around your pages markup:
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
</asp:Content>
and remove the <html>, <head>, <body> and <form> tags from every page.
Update
Here is an article (and source code) by Bob Powell describing a way to automatically convert html files to aspx files and add a master page. I'm sure you could adapt it to your needs.
This transition is not an easy one to make, as #geoff indicates. It is possible though if you have enough time and patience. The first step is to take all common elements (layout, menu, header, footer, whatever is common) and develop a master page structure. You'll likely need more than 1 depending on the differing layouts of forms in your application. Develop a user control for each of these common sections and make sure the master pages use these controls. Then systematically go through each page of your site and begin implementing the master pages.
As an assistance mechanism, you'll also probably want to have a page baseclass that is capable of communicating through the master page to the contained user controls. In our group we have a standard for setting a property on UserControls and MasterPages called ParentForm that is of type of our primary base page class, and this property is set during the Init of any page or control so that at any time, the developer has access (through Intellisense) to page itself. This is especially helpful since the parent of most controls is a container whose parent is a container whose parent ... you get the idea. For our controls it's just this.ParentForm.
It will be a long process, but MasterPages were really intended to be a "ground up" architectural decision rather than an "employ later" concept.

Resources