I would like to know how to create an ASP.NET user control that allows for inner content (and how to render the inner content.
As a very simple example, let's say we're creating a control to create a div, so the control would be used as follows:
<%# Page Language="C#" %>
<%# Register TagPrefix="custom" TagName="MyDiv"
Src="~\Controls\MyDiv.ascx" %>
<html>
<head />
<body>
<custom:MyDiv id="Div1" runat="server">
... customizable content here ...
</custom:MyDiv>
</body>
<html>
The control should be agnostic to its inner content - i.e. any asp.net content can be added and will be rendered as per usual, and then surrounded with <div> and </div> tags.
(Note: I'm obviously not trying to make a control to simulate div tags, it's just a simple example.)
It's an interesting question. Before I suggest an answer, I think you should look into Master Pages: http://www.asp.net/web-forms/tutorials/master-pages
If that doesn't provide your solution, and you want to stick with the User Control route, it won't work the way you want to do it.
Related
It seems straightforward enough, and testing it, it actually works:
<title>Default text</title>
In the Masterpage. And:
<%# Page Title="Specific name"...
in the specific page. Or in its codebehind:
Title = "Specific name";
So why am I asking? Because searching for it I've found all sorts of more complicated methods for doing that. (Yes. In Asp.net.)
So is there any drawback to the way I wrote above?
Not sure what you've found but that's how it is normally done.
Master page has the default, with overrides from specific pages.
An alternative (and I'm not specifying it's better) is to use a Content Placeholder.
On Master Page
<title>
<asp:ContentPlaceHolder id="PageTitle" runat="server">Default Title</asp:ContentPlaceHolder>
</title>
On specific page
<asp:Content ContentPlaceHolderID="PageTitle" runat="server">Specific Title</asp:Content>
But the drawback is that it's not as easy to set the title from code-behind.
What you have to know here that the <title></title> can not change from the code behind, or from the page declaration if is NOT inside the header with runat="server" So only if you have like that :
<head runat="server">
<title>Default Title</title>
</head>
you can have it as default, and then change it on pages. If the head is not runat="server" then the code behind can not find it to change it and the default title is shown.
All the rest stands as they are, I also use the same way, a default title on the master page, that I change it from the page if I can, or if not the default title is shown.
How can I include pages, style sheets, or links to them, automatically into my ASP VBscript pages? I read something about 'global' pages, but I am unsure what they mean and how it is that I can accomplish such a thing. I'm sure this is an easy question, but it's of great help to me as I've been writing VBscript for 2 days now! I'm not exactly an expert on HTML in general either, but I feel I have a reasonably good grasp of things. I would appreciate a good detailed example of how a 'global' page plays with my other ASP pages.
I'm setting up my first site...a management site for the main site I intend to build afterward. I want to get all my ducks in a row before moving forward with the public site. Can someone please give me some detailed information on how to include these pages/links automatically (page includes(header/footer), style sheets, etc) globally throughout my site without the need of using <!--#include file.... on each page I make, because that is kind of a pain and I'm sure there is an easier way. If there is, I know you can help! Thanks in advance, I look forward to hearing what options/possibilities are available.
If you insist on using ASP Classic you may find some method for handling masterpage like functionality but it is, to the best of my knowledge, not suppoerted as such by the framework.
[Edit] Given the edit of the original question the method first demonstrated is not so interesting, hence I suggest an alternative method too.
You could make a general ASP-page which serves all traffic to the site. A queryparameter then specifies which subpage should be displayed. Subpages are made as seperate ASP-pages which are executed by the general/master page or by another subpage. A very crude example of this could look like this:
<%
url = Request.QueryString("url") & ""
if url = "/" or url = "" then
subpage = "home.asp"
else
subpage = url & ".asp"
end if
%>
<!DOCTYPE html>
<html>
<head>
<title>Header for all pages</title>
<link rel="stylesheet" href="/css/site.css" />
</head>
<body>
<% Server.Execute(subpage) %>
</body>
</html>
The site should then be addressed in this fashion:
www.domain.com/default.asp?url=/contact
which would load the contact.asp subpage into the masterpage or:
www.domain.com/default.asp?url=/user/1234/profile
to load a user's profilepage (displayed by the profile.asp in the folder user/1234). This last example raises some issues because then every user has to have a folder containing all the asp-files (which is far from optimal) so you might want to employ some interpretation of the url queryparameter to redirect input in a more intelligent way.
Another issue is the fact that subpages are ASP-pages themselves which means someone could reference them directly. This calls for some action to protect those subpages from direct reference. It can be done but this would probably mean including some code => back to square one!
Another disadvantages of this approach is that subpages are rendered in their own context and hence can't access functionality and data from the calling page's context. This means that global data has to be shared in some other way (session, application, database or some other way). Data can't be passed to the subpage either (and no, Server.Execute doesn't allow query-parameters).
The include-way
Personally I think you get the most flexibility by using header/footer includes as demonstrated in my original post and shown below.
One way is to put your general stuff in includes and then includes those bits on each ASP-page. E.g.:
<!-- #include virtual="/includes/header.asp" -->
content goes here
<!-- #include virtual="/includes/footer.asp" -->
And your header.asp could look something like this:
<!DOCTYPE html>
<html>
<head>
<title>Header for all pages</title>
<link rel="stylesheet" href="/css/site.css" />
</head>
<body>
and footer.asp like so:
</body>
</html>
This strategy has some disadvantages. The header is fairly static which could present some problems with SEO; For one the title should fit the pagecontent which is hard to accomplish when the include contains the header-markup. This could be facilitated by some global variables that are set prior to the include-section i.e.:
<%
title = "Title for this page's content"
%>
<!-- #include virtual="/includes/header.asp" -->
content goes here
<!-- #include virtual="/includes/footer.asp" -->
and then in the header like so
<!DOCTYPE html>
<html>
<head>
<title><%=title%></title>
<link rel="stylesheet" href="/css/site.css" />
</head>
<body>
but that already begins to "smell" a little because you set up some expectations for the including page inside the include-file. At least you have to be very disciplined when constructing your pages.
The term you're looking for is Master Page, not Global Page, that may be why you're having a hard time finding what you're looking for on Google. Basically consider a master page a template. You create a master page, then load other pages into it. There are content place holders that you put in the master then populate on your other pages.
So a very basic example would look something like this.
<%# Master Language="VB" CodeFile="general.master.vb" Inherits="master1_general"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<link rel="stylesheet" type="text/css" href="/styles/main.css?v2"/>
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<form id="form1" runat="server">
<asp:ContentPlaceHolder id="body" runat="server">
</asp:ContentPlaceHolder>
</form>
</body>
</html>
Then your individual pages would look like this:
<%# Page Language="VB" MasterPageFile="~/master/general.master" AutoEventWireup="false" CodeFile="base.aspx.vb" Inherits="_Default" title="Opportunities" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
//any additional head stuff specific to this page goes here.
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="body" Runat="Server" >
//your body mark up goes here.
</asp:Content>
Notice how the Master page is actually a web page. Then it has place holders in certain spots. In this one there is a place holder in the head and one in the body. Then on individual pages I identify which master page to use and what data (if any) goes in the place holders. I always include a placeholder in the head so I can load js or resources that specific pages need on that page only.
Then the individual pages are just the content that goes in the placeholders.
This is my first time trying to make a login page. What I want to be able to do is take an existing html and put the login control on that page. I realize I can't take the html and drop asp controls on to it. My question is how do I use the existing HTML layout as the template for my new aspx page?
1) Get the source for the existing page ( View in a browser -> Right Click-> View source -> Select All -> Copy)
2) Create a new aspx page; delete everything after the <%# Page %> directive
3) Paste your HTML source from the HTML page.
4) Switch to design view of the aspx page, and delete whatever you dont need, add your login controls.
Create an empty asp.net project and then copy the HTML into the new page and modify it to work with the controls you are dropping into it.
If you want to persist a layout across multiple pages and I'm not sure that's what you are looking for, then the best thing to do is to store the html for layout in a master page.
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<asp:ContentPlaceHolder id="HeaderContent" runat="server"></asp:ContentPlaceHolder>
</head>
<body>
<div id="wrapper">
<div id="header">//add in html to setup your header</div>
<div id="content"><asp:ContnetPlaceHolder ID="Content"></asp:ContentPlaceHolder></div>
<div id="footer">//add in html to setup the footer</div>
</div>
</body>
</html>
In my current project we have 5 different masterpages, there are some common elements in each and its really annoying making the change in all 5, it kind of defeats the point of masterpages.
I have tried having parent and child master pages but that caused other problems for a different day.
Is there a way to include dynamic content in a masterpage?
I'm looking for something similar to the php and coldfusion include().
You can put user controls (.ASCX) in your master pages. Is this what you were attempting to accomplish?
Like so...
<%# Master Language="C#" AutoEventWireup="true" CodeBehind="WebForms.master.cs"
Inherits="Tunafish.Web.Views.Shared.WebForms" %>
<%# Register Src="~/Content/Controls/SiteNavigation.ascx" TagName="Nav"
TagPrefix="sc" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<asp:ContentPlaceHolder ID="HeadContent" runat="server" />
</head>
<body>
<sc:Nav runat="server" />
Have you looked into User Controls? .ascx
Custom web controls are the way to go:
http://weblogs.asp.net/scottgu/archive/2006/11/26/tip-trick-how-to-register-user-controls-and-custom-controls-in-web-config.aspx
As mxmissile and JMP suggested, user controls are the way to go, but you might want to be thorough in your usage of them. When you include the master page, make sure you add the following markup along with the page declaration:
<%# MasterType
virtualpath="~/myMasterPages/Master.master"
%>
This will allow you to call functions/objects in your master pages so you can make changes to controls or have access from the page itself to various other objects. I have a property in my base usercontrol class called "ParentForm" that is a reference to the page it sits in. For user controls in the master page, I ended up having the same property and in the setter of that property I translate it down to the user controls.
You could set the masterpages to inherit from a class that dynamically inserts content or script to the page OnPreRender in code. It may seem out there but I have had to use this method.
I am working on a web application that has a single master page and several content pages. Each page will have a small sidebar to the right of the main content with some brief content. However, that brief content is specific to the page you are on. I can't decide whether to put that on each individual page, or in the master page in a MultiView with some logic in code-behind to specify which view is shown based on which page you are on.
Which seems more elegant? I'm still fairly new with ASP.NET and I'm trying to get a good feel for proper architecture, etc.
You can create multiple content placeholders in a single masterpage. So in your case I would create two. One for the article's content and one for the sidebar like:
<!-- some html-->
<asp:contentplaceholder id="ArticleContents" runat="server">
</asp:contentplaceholder>
<!-- some more html-->
<asp:contentplaceholder id="ArticleSidebar" runat="server">
</asp:contentplaceholder>
<!-- even more html-->
then you could have the article contents and the sidebar contents both in the same page and place it in the correct spot using something like
<asp:Content ID="article" ContentPlaceHolderID="ArticleContents" Runat="Server">
Your article
</asp:Content>
<asp:Content ID="sidebar" ContentPlaceHolderID="ArticleSidebar" Runat="Server">
Your sidebar
</asp:Content>
If you want some manageability in the case of your site getting larger and needing more of these custom sidebars then I would not put anything beyond standard layout in the master page.
What is wrong with having an additional ContentPlaceHolder in the side bar and just adding the content into Content controls on each content page?
Your approach seems overly complex to me.
You could also put that additional code into a user control (or two). The content page would then include the user control appropriate to that page for the right sidebar.