Website:
The Web Site project is compiled on the fly. You end up with a lot more DLL files, which can be a pain. It also gives problems when you have pages or controls in one directory that need to reference pages and controls in another directory since the other directory may not be compiled into the code yet. Another problem can be in publishing.
If Visual Studio isn't told to re-use the same names constantly, it will come up with new names for the DLL files generated by pages all the time. That can lead to having several close copies of DLL files containing the same class name,
which will generate plenty of errors. The Web Site project was introduced with Visual Studio 2005, but it has turned out not to be popular.
Web Application:
The Web Application Project was created as an add-in and now exists as part
of SP 1 for Visual Studio 2005. The main differences are the Web Application Project
was designed to work similarly to the Web projects that shipped with Visual Studio 2003. It will compile the application into a single DLL file at build
time. To update the project, it must be recompiled and the DLL file
published for changes to occur.
Another nice feature of the Web Application
project is it's much easier to exclude files from the project view. In the
Web Site project, each file that you exclude is renamed with an excluded
keyword in the filename. In the Web Application Project, the project just
keeps track of which files to include/exclude from the project view without
renaming them, making things much tidier.
Reference
The article ASP.NET 2.0 - Web Site vs Web Application project also gives reasons on why to use one and not the other. Here is an excerpt of it:
- You need to migrate large Visual Studio .NET 2003 applications to VS
2005? use the Web Application project.
- You want to open and edit any directory as a Web project without
creating a project file? use Web Site
project.
- You need to add pre-build and post-build steps during compilation?
use Web Application project.
- You need to build a Web application using multiple Web
projects? use the Web Application project.
- You want to generate one assembly for each page? use the Web Site project.
- You prefer dynamic compilation and working on pages without building
entire site on each page view? use Web
Site project.
- You prefer single-page code model to code-behind model? use Web Site
project.
Web Application Projects versus Web Site Projects (MSDN) explains the differences between the web site and web application projects. Also, it discusses the configuration to be made in Visual Studio.
Greetings Dan,
I faced a similar problem before with the mess of nested controls, so I found myself eager to help, and I marked this as favourite too because I liked it.
I reproduced the problem as follows:-
Created a user control called Inner:
Inner.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Inner.ascx.cs" Inherits="Inner" %>
<a runat="server" id="linkHref">I'm inner</a>
Inner.ascx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class Inner : System.Web.UI.UserControl
{
public string Url
{
get
{
return this.linkHref.HRef;
}
set
{
this.linkHref.HRef = value;
}
}
}
Created a user control called Outer:
Outer.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Outer.ascx.cs" Inherits="Outer" %>
<%@ Register src="Inner.ascx" tagname="Inner" tagprefix="uc1" %>
<uc1:Inner ID="_Inner" runat="server" />
Outer.ascx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class Outer : System.Web.UI.UserControl
{
[PersistenceMode(PersistenceMode.InnerProperty)]
public Inner Inner
{
get
{
return this._Inner;
}
}
}
Then created a page called Default:
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register src="Outer.ascx" tagname="Outer" tagprefix="uc1" %>
<%@ Reference Control="~/Inner.ascx" %>
<!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 runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<uc1:Outer ID="Outer1" runat="server">
<Inner Url="http://google.com" />
</uc1:Outer>
</div>
</form>
</body>
</html>
With all these, the page "default" runs well.
What I find strange in your code is this line:
public InnerControl Inner
{
//...
set{ _Inner = value; }
}
What's the point of creating a setter for the inner control? I can't understand it. the inner control instance is supposed to be created from the markup in the outer control, and it's this created instance whose html anchor should be manipulated.
If I add these lines to the Inner property in the Outer.ascx.cs
set
{
this._Inner = (ASP.inner_ascx)value;
}
I'll get a null reference exception as in the original case.
I think that the setter instructs ASP.Net page builder to create another Inner control instance and set it using the Inner property. I'm not sure, but if you have time, you can know exactly how this happens by examining the cs files generated by the page builder, they reside in the temporary ASP.Net files.
Best Answer
I asked something similar myself a while ago. See here.
I believe you will have to use an ITemplate as an InnerProperty:
Then override the CreateChildControls method of your control:
What's the harm in using an
ITemplate
You can combine it with your existing markup and write whatever HTML you want within theContent
property.