This article is intended to give you a practical recipe for creating a simple Web Control and extending Visual Studio with support for the control. The control itself is a basic Country Code drop down list such as you would find on many profile entry pages.
Instead of the cut and paste model of ASP, you are presented, by Visual Studio, with the much more elegant Web Control. The Web Control will allow you to write the Country Code dropdown list once, add it to the Toolbox and include it in any of your pages or applications by simply dragging its icon from the Toolbox to the Design View.
Before we start, download the source code of this article here.
1.1. Preliminaries
Topics: Custom Web Controls, Visual Studio Design View, Visual Studio Toolbox
Level: Basic-Intermediate
Language: ASP.NET, C# (C-Sharp)
Required Software: Visual Studio 2003, IIS with .NET Framework 1.1
1.2. Goals
When you have finished this article, you should have an iconic representation of a Country Code DropDownList Web Control in the Toolbox for use in your projects. The Web Control will encapsulate the mundane function of capturing an ISO 3166-1 Country Code and will expose its SelectedItem Text and Value as well as some design time properties for controlling the Design View rendering of the control.
2. Web Control Library
In order to maximize the reusability of the custom Web Control, you need a convenient location for it. There are a couple of reasons for using a Web Control Library for this purpose:
* It makes it easy to add a reference to the control in new projects.
* It gives you a place to find related controls and maintain their code.
I am sure that there are a number of other good reasons, but these will suffice for your discussion.
2.1. New Project
Click the IDE menu item: File=>New=>Project or just click the New Project button from the Start Page. Select Visual C# Projects from the folders on the left. Select Web Control Library from the Templates window. Type a descriptive name into the Name field, something like wclProfileControls. Change the location if you don’t like it. Click OK and take a look at all of the files that the Project wizard has created for you. In particular, you will be focusing most of your attention on the .cs file that contains the code for the web control.
3. Web Control
The Project Wizard has created a template of a Web Control that you will modify and enhance. The name of the .cs file that you start working with is WebCustomControl1.cs.
3.1. Rename .cs File
First things first, WebCustomControl1.cs is not a very good and informative name. Let’s change it to something more applicable.
3.1.1. Solution Explorer
In the Solution Explorer, expand the wclProfileControls Project (or whatever you named your project). Right Click on WebCustomControl1.cs and Click Rename. Name it wcCountryCodeDropDownList.cs or something else that you find to be indicative of its purpose. You will notice that the design view tab now shows wcCountryCodeDropDownList.cs.
3.2. Rename the Web Control Class
While the filename has been changed to wcCountryCodeDropDownList, the name of the class is a generic – WebCustomControl1, not descriptive and not helpful, you will change that as well.
3.2.1. Class View
Find the Class View window, usually in the top right window as a tab behind the Solution Explorer. If you cannot see the window anywhere, click the IDE menu item: View=>Class View. Expand the wclProfileControls Project by clicking the plus sign to the left of the name. Expand the wclProfileControls Namespace below the Project. Right Click on the WebCustomControl1 Class. Click Properties. Find the Properties window, usually the bottom right window. If you cannot see the window anywhere, click the IDE menu item: View=>Properties Window. Make sure that WebCustomControl1 CodeClass is showing in the dropdown list at the top of the properties window. Below that, you will see a Misc property. Expand it. Click the text field to the right of (Name). Type in CountryCodeDropDownList or whatever you feel would be indicative of the control. You will see the changes once the focus changes from the text field, i.e.. Press enter, tab, click on another window, whatever.
3.2.2. Code View
The change of name is not complete until you replace the name WebCustomControl1 in the Comments and ToolBoxData prolog and that means that you need to edit the .cs file directly.
Click over to the wcCountryCodeDropDownList.cs Code View. Type Ctrl-H to bring up the Replace dialog, or from the IDE main menu – select Edit=>Find and Replace=>Replace. Type WebCustomControl1 into the ‘Find what’ edit box. Type CountryCodeDropDownList into the ‘Replace with’ edit box. Click the Replace All button – should result in 3 occurrence(s) replaced.
3.3. Add Functionality to the Web Control
Most of the custom functionality that you will be adding will be realized through code changes to the Web Control’s .cs file and in particular to the class definition:
public class CountryCodeDropDownList : System.Web.UI.WebControls.WebControl { // your code will be added here ... // you will be modifying the Render method below, as well /// <summary> /// Render this control to the output parameter specified. /// </summary> /// <param name="output"> The HTML writer to write out to </param> protected override void Render(HtmlTextWriter output) { output.Write(Text); } }
3.3.1. CreateChildControls
You are going to override the CreateChildControls Method to add and populate your DropDownList with ListItems. I have taken the easy way out and created an array of strings and a for loop to add items. Feel free to do it your way. The constructor below does not include the full ISO 3166-1 list of country codes. The referenced project files, available to download, at the top of the article, contain the complete Method.
protected override void CreateChildControls() { //This is a partial list, the project files contain a complete list //Country codes are as specified in ISO 3166-1 //for more information, or to obtain an official list, visit the iso site: //http://www.iso.org/iso/en/prods-services/iso3166ma/index.html string [] codes = { "United Kingdom","GB", "United States","US", "United States Minor Outlying Islands","UM", "Virgin Islands, British","VG", "Virgin Islands, U.S.","VI", }; DropDownList ddlCountryCodes = new DropDownList(); for(int i = 0; i < codes.Length; i+=2) { ddlCountryCodes.Items.Add(new ListItem(codes[i], codes[i + 1])); } ddlCountryCodes.SelectedIndexChanged += new EventHandler(this.ddlCountryCodes_selectedIndexChanged); this.Controls.Add(ddlCountryCodes); }
3.3.2. SelectedIndexChange Event
In order to support changes made to your control you will implement an event handler, but it's just a no-op. You can do stuff in here, but it's not necessary for this project.
private void ddlCountryCodes_selectedIndexChanged(Object sender, EventArgs e) { //no need to really do anything here }
3.3.3. Remove Unnecessary Code
Before you add properties, remove these lines from the beginning of the class definition:
private string text; [Bindable(true), Category("Appearance"), DefaultValue("")] public string Text { get { return text; } set { text = value; } }
Also remove the Render Method:
/// <summary> /// Render this control to the output parameter specified. /// </summary> /// <param name="output"> The HTML writer to write out to </param> protected override void Render(HtmlTextWriter output) { output.Write(Text); }
3.3.4. Expose Some Existing Properties
The Text and Value properties of the DropDownList's SelectedItem are properties that you will want access to in your applications, so you will expose them by adding a couple of public Properties.
3.3.4.1. Value
You want to expose the Value of the currently selected item in the DropDownList.
public string Value { get { this.EnsureChildControls(); return ((DropDownList)Controls[0]).SelectedItem.Value; } set { ((DropDownList)Controls[0]).SelectedItem.Value = value; } }
3.3.4.2. Text
You also want to expose the Text of the currently selected item in the DropDownList.
public string Text { get { this.EnsureChildControls(); return ((DropDownList)Controls[0]).SelectedItem.Text; } set { ((DropDownList)Controls[0]).SelectedItem.Text = value; } }
3.3.5. Add Some New Properties
You are going to add some Design View Properties. These are properties that will effect the Design View of the Web Control.
3.3.5.1. RenderHTML Design View Property
The RenderHTML Property will be used later to control what is rendered in Design View. The implementation of this property consists of a private string and public property. The string will be used when you create a ControlDesigner derived Class in the overridden GetDesignTimeHtml() method.
// //strRender is set to a simple select with Country Code DropDownList to display // in Design View. I included the other option, since it's the longest option // and represents how wide the control will actually be // private string strRender = "<select name><option value="">Country Code DropDownList</option><option value="UM"> United States Minor Outlying Islands</option></select>"; public string RenderHTML { get { return strRender; } set { strRender = value; } }
3.3.5.2. NoRenderHTML Design View Property
The NoRenderHTML Property will be used later to control what is rendered in Design View when the Design View thinks that there will not be anything rendered at run time. This control will always render at runtime, by it's very nature. However, there are times when you will want to create controls that don't, for instance, a label control. It is convenient to add a "This control will not be rendered (visible) at runtime with the current settings" render string and you will add it here, simply to provide a consistent template to work from for future controls. The implementation of this property consists of a private string and public property. The string will be used when you create a ControlDesigner derived Class in the overridden GetEmptyDesignTimeHtml() method.
private string strNoRender = "Not Visible at Runtime with Current Settings"; public string NoRenderHTML { get { return strNoRender; } set { strNoRender = value; } }
3.3.5.3. Property Grid Extensions
The Property Grid is the Visual Studio Property Window and you can control how the Web Control is represented in it, when you view its properties. This is accomplished by a square bracketed prolog immediately prior to the public Properties themselves.
Add a Property Grid control prolog to each of the new Properties (The RenderHTML Property is shown, use the same procedure for the NoRenderHTML, Text and Value Properties).
[ Bindable(true), Category("Custom"), DefaultValue(""), Description("Set the Design View Render HTML String") ] public string RenderHTML { ... }
The prolog will add a Custom Category to the Property Grid and add the property RenderHTML to the Grid. If you select the RenderHTML property in the Property Grid, it will display the Description, "Set the Design View Render HTML String", in the Description Box below the Properties as a sort of help text.
4. Custom Designer
The Custom Designer Class is where you will control what gets displayed in Design View for the Web Control. You will leverage Microsoft's System.Web.UI.Design.ControlDesigner. All you are going to do is override the two methods GetDesignTimeHtml and GetEmptyDesignTimeHtml.
4.1. System.Design Assembly
In order to use the System.Web.UI.Design.ControlDesigner Microsoft class, you will need to add a reference to the assembly to the project.
4.1.1. Add Reference
In the Solution Explorer, Right Click the wclProfileControls Project(or whatever you named your project). Click Add Reference. Or Select the IDE menu item: Project=>Add Reference. Select the .NET tab, Scroll down to System.Design.dll, Click the Select button and Click the OK button to add the reference to the Project.
4.2. New Class
In the Solution Explorer, Right Click the wclProfileControls Project (or whatever you named your project). Select Add. Select Add Class. An Add New Item dialog will pop up with Class preselected (if not, select Class). The name class.cs will be pre filled into the Name text box. Change the name to something more meaningful, such as CountryCodeControlDesigner.cs and Click Open.
4.2.1. Derive from System.Web.UI.Design.ControlDesigner
It is all about leverage, the ControlDesigner will provide a lot of base functionality that you will use. In order to acquire the leverage, change the class definition to derive the class from ControlDesigner:
public class CountryCodeControlDesigner : System.Web.UI.Design.ControlDesigner
4.2.2. GetDesignTimeHtml()
This method is overridden to allow you to change the way the control is rendered in Design View. Add the following to the Class Definition (just after the Constructor):
public override string GetDesignTimeHtml() { //cast the underlying Component to a CountryCodeDropDownList //so that you have access to the design time Property - RenderHTML CountryCodeDropDownList dl = (CountryCodeDropDownList) Component; return dl.RenderHTML; }
4.2.3. GetEmptyDesignTimeHtml()
This method is overridden to allow you to change the way the control is rendered in Design View when it thinks that nothing will be rendered at runtime. It is included here for completeness. This control will always be rendered at runtime. However, if you created a control composed of a Label and did not supply any Text at design time, it is possible that it would be empty at run time. Since this is specified, it will be clear when you look at the control in design view that this is the case. Add the following just after the GetDesignTimeHtml method:
protected override string GetEmptyDesignTimeHtml() { //cast the underlying Component to a CountryCodeDropDownList //so that you have access to the design time Property - NoRenderHTML CountryCodeDropDownList dl = (CountryCodeDropDownList) Component; return CreatePlaceHolderDesignTimeHtml(dl.NoRenderHTML); }
GetEmptyDesignTimeHtml is a protected override and not public like its cousin GetDesignTimeHtml, but it is, so be careful copying and pasting.
5. Designer Attribute
The Designer Attribute is a part of the prolog to the Web Control class definition and tells Visual Studio about the ControlDesigner that is used for the control. It is the link between the Web Control and the Designer. Edit the prolog that appears just before the class definition, CountryCodeDropDownList, in wcCountryCodeDropDownList.cs and add a Designer Attribute.
[ DefaultProperty("Text"), ToolboxData("<{0}:CountryCodeDropDownList runat=server>{0}:CountryCodeDropDownList>"), Designer("wclProfileControls.CountryCodeControlDesigner, wclProfileControls") ] public class CountryCodeDropDownList : System.Web.UI.WebControls.WebControl { ... }
6. Icon
Adding an Icon to the project is completely optional. In order to add an icon to the project, you first have to have an icon. The icon must be 16 pixels by 16 pixels and no more than 16 bit color. I downloaded a free 32x32x16 icon from the web and resized it to 16x16 in PaintShop Pro. Do what you must. Once you have an icon, copy it into the Project directory and name it CountryCodeDropDownList.bmp. The filename for the icon is the same as the name of the Web Control Class.
Here is the icon that I have chosen:
6.1. Solution Explorer
In the Solution Explorer, Right Click the wclProfileControls Project (or whatever you named your project). Select Add. Select Add Existing Item. Change the Files of Type Dropdown List to "All Files" (you may need to scroll down in the list) and Browse to the CountryCodeDropDownList.bmp file and select it. Click Open to add it to the project.
Right Click the CountryCodeDropDownList.bmp file in the Solution Explorer and Select Properties. Click the word Content in Build Action and Select Embedded Resource from the Dropdown List (the down arrow to the right of the word Content).
7. Build the Web Control Library
This is a good checkpoint for building the Web Control Library.
7.1. Solution Explorer
In the Solution Explorer, Right Click on the wclProfileControls Project and Select Build. You should not get any errors and the output will be similar to this:
------ Build started: Project: wclProfileControls, Configuration: Debug .NET ------ Preparing resources... Updating references... Performing main compilation... The project is up-to-date. Building satellite assemblies... ---------------------- Done ---------------------- Build: 1 succeeded, 0 failed, 0 skipped
8. ASP .NET Web Application
The Web Control is complete and is ready to be consumed by an Application. You will create a simple Web Project to exercise the Web Control.
8.1. New Project
Create a new Project within the Solution for the Web Application.
8.1.1. Solution Explorer
In the Solution Explorer, Right Click the Solution wclProfileControls (top level, not the Project). Select Add. Select New Project. Select Visual C# Projects from the folders on the left. Select ASP .NET Web Application from the Templates window. Change the location to something like http://localhost/ccTest. Click OK and take a look at all of the files that the Project wizard has created for you. In particular, you will be focusing most of your attention on the .aspx and .aspx.cs files.
8.2. Rename .aspx File
Change the generated WebForm1.aspx to default.aspx.
8.2.1. Solution Explorer
In the Solution Explorer, expand the ccTest Project(or whatever you named your project). Right Click on WebForm1.aspx and Click Rename. Name it default.aspx. You will notice that the design view tab now shows default.aspx and that the WebForm1.aspx.cs file has automatically been renamed default.aspx.cs.
8.2.2. Code View
The change of name is not complete until you replace the name WebForm1 in the code itself.
First, make sure that you only have default.aspx (HTML View) and possibly default.aspx.cs open in the Designer. Then, open default.aspx.cs in Code View by Right Clicking on default.aspx and selecting View Code. Check the Option on the Search Panel that says All open documents and Replace all occurences of WebForm1 with wf_ccTest. There should be a grand total of 4 occurences in the 2 files.
8.3. FlowLayout Positioning
Visual Studio defaults to GridLayout for .aspx files. Change it to FlowLayout. The difference is that GridLayout uses absolution pixel positioning (Grid) and FlowLayout uses relative positioning (Flow, things get put next to each other). To change the layout, Click over to the HTML view of default.aspx and change the MS_POSITIONING body attribute to FlowLayout:
<body MS_POSITIONING="FlowLayout">
8.4. Add Web Control to the Toolbox
Now it is time to add the Web Control, that you created earlier, to the Toolbox.
8.4.1. Design View
Click back to the Design View of the default.aspx file.
8.4.2. Toolbox
Find the Toolbox, usually to the left of the workspace. If you cannot see the window anywhere it might be unpinned. If this is the case, you will see a button labeled Toolbox somewhere on screen, simply click it and it will expand. If you want it to stay expanded, you will need to pin it by clicking on the push-pin at the top right of the window. If you cannot see the window or the button anywhere, Click the IDE menu item: View=>Toolbox.
8.4.2.1. My User Controls
The My User Controls Toolbox Tab is where you are going to add the newly created control. To do so, Click on the My User Controls Tab. Right Click in the empty area below the name and Select Add/Remove Items... The Customize Toolbox dialog will appear. Make sure that the .NET Framework Components Tab is selected and Click the Browse... button on the bottom right. Navigate to your project directory - typically in My Documents\Visual Studio Projects\wclProfileControls\bin\debug, which is accessible by the My Projects button to the left of the folder list. Select the dll, wclProfileControls.dll Click the Open Button, this will create an entry in the .NET Framework Components Tab that will be preselected - CountryCodeDropDownList. Click the OK Button to generate an icon and text for a CountryCodeDropDownList control in the Toolbox.
8.5. Using the Web Control
If you used the icon from the project files I generated, you will see a World Map icon next to the Caption CountryCodeDropDownList in the Toolbox, otherwise you will see the default Gear icon - that is fine. It is ready to use. In order to add the control to your Web Project, simply switch to Design View for default.aspx and double click the item in the Toolbox. Alternatively, you can drag it from the Toolbox to the Design View. The IDE will automatically add the correct references to the Project for you to be able to access the Web Control.
8.5.1. Programmatic Access
The Control is only useful because it allows you to drag and drop it into your application and have it do it's country code selection magic, giving you back the Text/Value pair of it's selected item when it gets submitted.
8.5.1.1. Label
Add a label to the form for displaying the values of the DropDownList after the form is submitted. I know kludgy, write me with improvements.
Click just after the DropDownList control in Design View and Press Enter to drop down a line. Drag an ASP Label control from the Web Forms Tab of the Toolbox to the default.aspx Design View. Right Click the Label and view its Properties in the Property Grid. Change the Id to lblKludge and delete its Text.
8.5.1.2. Submit Button
Add a submit button to the form.
Click just after the Label control in Design View and Press Enter to drop down a line. Drag an ASP Button control from the Web Forms Tab of the Toolbox to the default.aspx Design View. Right Click the Button and view its Properties in the Property Grid. Change its text to Submit. No need to write a handler for it, it will automatically submit the form.
8.5.1.3. Page_Load
To actually access the values of the DropDownList from the Web Form, add the following to default.aspx.cs in the Page_Load method:
this.lblKludge.Text = this.CountryCodeDropDownList1.Text + ", " +this.CountryCodeDropDownList1.Value;
8.5.1.4. PreRender Event Handler
First you need to add this line of code to the InitializeComponent Method:
this.PreRender +=new EventHandler(WebForm1_PreRender);
Next you need to create the PreRender Event Handler, add these lines:
private void WebForm1_PreRender(object sender, EventArgs e) { this.lblKludge.Text = this.CountryCodeDropDownList1.Text + ", " +this.CountryCodeDropDownList1.Value; }
8.6. Startup Project
Set the ccTest Project as the Startup Project.
8.6.1. Solution Explorer
In the Solution Explorer, Right Click on the ccTest Project and Select Set as Startup Project.
8.7. Execute Web Form
Run the Web Form from Visual Studio and marvel at your ingenuity.
Click the IDE menu item: Debug=>Start or Click the Play VCR Button to the left of the Solution Configurations DropDownList (usually says Debug or Release)
This is a very simple application that is intended to serve as a testing platform for the Web Control. To test that it is performing properly, simply change the selection of the DropDownList and click the Submit Button. The Label will change to reflect your choice. I leave it as an exercize for the reader to trap the SelectedIndexChanged Event of the DropDownList and modify the Label in that method.
8.8. Browse
Please spend an hour or so, poking around all the code that Microsoft gratuitously generated for you. There is a lot of cruft and if you are intermediate-advanced, you should be able to recognize it as such. Questions to ask yourself, are; Why is it there? Can I leverage the fact that it's there? Should I remove it?
9. Next Steps
Some other things that you may want to do with your Web Control, that you either did not cover or covered minimally are:
Extend Property Grid Support
Specify a Default XML Tag for the Web Control
Specify a TagPrefix
Add Intellisense Support
Package the Web Control for Deployment
More information on many of these topics is included with the MSDN Library. Just open up help in Visual Studio and navigate to the topic:
MSDN Library/.NET Development/Visual Studio .NET/Product Documentation/Visual Basic and Visual C#/Programming with Components
If you think tree walking the MSDN Library is painful, searching is just as bad. I highly recommend that you become proficient with Google, or better yet, Copernic.
10. Conclusion
The Design Time environment of Visual Studio .NET is powerful yet mysterious, poorly documented yet accessible, attractive yet aggravating - a true study in contrasts. If you start down the road of extending the Design View further, be prepared for headaches galore, but it will be worth it if you can master it. Very few developers tap into these features and if you resell your components or even work in a large company where other developers will consume your work, you will stand out from the crowd.
I hope that you have enjoyed reading this article and if you have worked through the recipe, I hope your Web Control turned out well. Let me know if there are errors or omissions and I will try to update the Recipe.
11. Resources
F1 and Shift-F1 should be your first line of defense
Copernic Agent Basic (free) is the most powerful search engine I have ever used
Google is the place on the web where you will have the most luck
GotDotNet remains a decent place to visit
CodeProject is a great resource
Microsoft MSDN .NET Framework Home Page Too often, this is a last resort
Download the source
Email the author Will Senn
12. Acknowledgements
Thanks to my Wife for putting up with my 40+ hour focus on writing this.
Thanks to Randy Geyer for assisting me with some of the trickier bits of the IDE.
Kudos to Susan Warren of Microsoft ASP.NET Team fame for her work with Custom Controls.
GotDotNet for the Microsoft ASP.NET QuickStarts Tutorial
If you would like to see your thoughts or experiences with technology published, please consider writing an article for OSNews.
An excellent introduction into creating custom controls in aspx solutions. I’d like to see more of these available as learning points – asp.net is kind of a different mindset to php.
8.3. FlowLayout Positioning
Visual Studio defaults to GridLayout for .aspx files. Change it to FlowLayout. The difference is that GridLayout uses absolution pixel positioning (Grid) and FlowLayout uses relative positioning (Flow, things get put next to each other). To change the layout, Click over to the HTML view of default.aspx and change the MS_POSITIONING body attribute to FlowLayout:
<body MS_POSITIONING=”FlowLayout”>
This is really important for cross browser compatibility. GridLayout is a PITA. It doesn’t work in most browsers and is only reliable in IE. It attempts to turn a web page into a form type design. To me, it feels like a way to help move program designers to web design. Switching to FlowLayout is much better.
Then again, all HTML/CSS support in VS.net/ASP.net is pretty horrid in general.
It’s amazing to see how much work is involved in creating a custom control for the web. It is a real weakness of applying a programming model to the web, when clearly a plain text/scripting combination is much better.
I’ve done a couple of controls this week, and I wish I could use PHP. Something I could do in a 1/2 hour in PHP turns into a 4-8 hour charade with ASP.Net/C#. To do this control in PHP is much faster and easier. Microsoft has made it way too complex.
This article is well written and will help a lot of people.
“It doesn’t work in most browsers and is only reliable in IE” – typical for MS, 1. they think that W3C isn’t for them and 2. they “oblige” Win users to stick with IE (or just not have things working) – … again one step to maintain the monopoly
and i agree PHP is more adequate, it also uses less ressources than the overloaded .NET framework
and i agree PHP is more adequate, it also uses less resources than the overloaded .NET framework
Still I think ASP.Net might have some advantages over PHP, such as full OO, JIT compiling, code-behind, etc, doesn’t it? I suppose this pays off some eventual extra cost one might have to put more “server resources” available.
I’ve used both ASP.net and PHP (as well as Cold Fusion, old ASP and whatever the customers had on their sites) and I would prefer ASP.Net over anything else any day, the productivity I got with .Net is simply amazing. Actually it’s the first time in many, _many_ years that I saw something from MS and I thought “Gee this is very good!”. ASP + COM was miserable.
But maybe it’s just me, I don’t wanna “convert” anyone or start flame wars.
About the GridLayout thing: I hope they get rid of it on VS.Net 2005, I’m yet to see anyone who uses that.
> advantages over PHP, such as full OO, …
If you need this all then write a CGI script. It has less overhead as the previous poster (presumably) meant.
Wow. I can’t believe people are seriously comparing PHP to this. I’ll admit that I was a PHP programmer back in high school. Then I taught myself J2EE and enterprise-scale web application design patterns. Now PHP seems a horrid kludge useful only for creating simple personal web pages.
I haven’t done any ASP.NET programming, but industry seems to hold it in the same regard as J2EE. This custom control idea seems analogous to custom tags in JSP. There is nothing like it in PHP. Suppose you want to validate input coming from your custom control. You can probably (again, I don’t know ASP.NET) attach validation code to the control. Then your other developers can use that control anywhere on the website just by dragging and dropping it in. In PHP, you would have to encapsulate rendering the control and validating the control in separate functions and call those functions directly on the web page, placing the validation call at the top and the rendering somewhere in the body, and you would have to remember to copy and paste both of those every time. MVC is nigh near impossible in PHP.
As for CGI having less overhead than ASP.NET, you’ve got to be kidding. It has a smaller fixed cost, sure, but the per-request hit is humongous as you have to fork another process every time. You will not find enterprise web development jobs using PHP or CGI because of poor scalability both in terms of development and in terms of handling requests. See http://www.onjava.com/pub/a/onjava/2003/06/04/nukes.html for a case study.
My main issue with VS is that, behind the scenes it likes to add a whole lot of extra things (extra files/folders& FP extensions) to your website which may or may not be necessary.
You can run ASP.Net fine with just aspx/cs files and maybe a “in” dir for your .net DLLs. Even if you add a config (asax) file or two things are still pretty tight.
Admittedly I prefer a simpler structure because it is easier for me (and my little brain) to keep track of exactly what is going on and troubleshoot. Also I suspect it makes the site more portable.
Having said that I do think the interface & debugging capabilities are excellent.
My .02 – ymmv
E.
I think MS also recognizes things are a bit overkill. On the next version of VS.Net they’ll make things a bit easier, they learned a thing or two with ASP.Net Web Matrix, I suppose…
For example it won’t be necessary anymore to create project files, solutions, etc, you just put the aspx files in a folder and that’s it, like it used to be with ASP.
My 2 øre anyway
Visual Studio 2003:
Go to Solution Explorer and Select your project. Click “Copy Project” icon (in Solution Explorer). Select “Only files needed to run this application” and Click OK. Set path to where you want your project deployed and.. that’s it. Complicated?
You will not find enterprise web development jobs using PHP or CGI because of poor scalability both in terms of development and in terms of handling requests. See http://www.onjava.com/pub/a/onjava/2003/06/04/nukes.html for a case study.
Don’t base the speed of PHP on a single, overly complex, completely bloated, slow, etc…. CMS like postnuke. I have to deal with slow Java based web apps all the time, does that mean Java is slow? No, it means the programmers behind the programs didn’t do a very good job. I have seen ASP.Net apps ported to PHP that run 4-5 times faster. So not only do you gain speed, but you can also loose the server farm and the load balancers it took to run the ASP app. Again, this might just have been a poorly written ASP app. Also, I wonder if Yahoo using PHP would count as an “enterprise web development job”. I never used ASP.Net but I used ASP all the time before I moved to a Unix/NetWare shop. The beauty of PHP is its simplicity. Use it for fast and easy procedural apps, or create a nice framework to work off of, you can do both, with the same language. You can’t take the complexity out of ASP or Java.
Keith
Scalability with PHP is hard. As I understand it, Yahoo! uses a C++ backend to do much of the work and uses PHP in the presentation tier. PHP doesn’t even have connection pooling, so using it below the presentation tier seems to be a bad idea. Also, http://dada.perl.it/shootout/craps.html shows that Java is 35% faster at performing logic once you’ve gotten the data.
I agree that PHP is fine for simple personal web page type stuff, but for larger web applications, J2EE has established frameworks based on proven design patterns that increase productivity for development teams, and you can use it for everything above the data-server tier.
Yeah, I know it was long and detailed – but it was meant to be comprehensive – a beginner’s tutorial. The intermediate folks will have to scan the easy stuff to get to the meat.
Thanks,
Will
You said it! FlowLayout is the only way to tame cross browser layouts. Not only that but once, MS starts putting absolute positions all over the place the HTML starts to look like spaghetti.
Thanks,
Will
Well, not really… The bulk of the work was in hooking up the custom control to the design view, not in actually making a user control.
You are correct .NET will scale very well in enterprise situations if not in a mom & pop web site. Code behind is absolute genius.
regarding FlowLayout, enough cannot be said – and Grid’s the default? what were they thinking?
Will
One thing you can always do is use UltraEdit/Textpad and the command line compiler to create your code files and only use Studio for debugging… I’m going to write an article on Web Services with Notepad that details the minimum necessary to write a web service from scratch using tools provided by the framework itself without requiring VS. Pretty much any project can be written without relying on Studio (it’s just quicker/easier once you figure out the cruft from the meat).
Later,
Will
Yes I agree! In fact I use Homesite & TextPad (love that columnar copying/pasting) and have been trying my hand at creating Dlls in Sharpdevelop. I do like the technology. I’m excited about the cross platform possibilities. Apache/Mono/Linux anyone?
Gonzo mentioned earlier that I could easily deploy only the working files. I’ll have to check that out. The only issue I have with that though is that the differences between my dev and live environments then becomes greater increasing potential for errors. Also I kinda like to keep my dev stuff clean too..
Thanks for the article btw.
E.
The only issue I have with that though is that the differences between my dev and live environments then becomes greater increasing potential for errors.
Or decreasing it perhaps?
Look, you develop on your dev machine and test it there too. Then you deploy it to your test server and test it there. Once it works, deploy it to your main server and that’s it. Isn’t that the whole point of having separated dev and production boxes – so that you can deploy only well-tested application to your production server?
Thanks for the compliment. I am excited about the mono front as well, although the documentation is seriously slim for running it in a windows environment – in linux it apparently works pretty well. In Windows – hmmm… I had to copy mscorlib.dll to C:installlib to get it to run (apparently it was hard coded in mono – and then gtksharp – ow! I’m sad to say I had to give up on getting that to work in windows…
Will
Yes I agree! In fact I use Homesite & TextPad (love that columnar copying/pasting)
You can do columnar selection on VS.Net too, just hold the ALT key.
columnar selection, sure.. but what about, hex mode, wordwrap off, view in browser, send in email, line folding, sort, convert formats, upcase, lowcase, mixcase, on and on and on? I like VS, but it’s editor is very, very weak (other than intellisense and code folding).
On another related note, one thing that I wish the VS environment supported is the full gamut of file selection from the context menu – ie. when you right click on myWebservice.asmx, you would be able to edit the .asmx in text mode, design mode, and the .asmx.cs code behind file by selection – as it is you can’t even get to the text mode of the .asmx file without explicitly opening it in source(text) mode…. The navigation between all of these different views/formats is very clunky – I hope it improves in 2005…
will
– Hex mode? never needed that lately, but maybe it’s just me.
– wordwrap: you have it (check tools/options/text editor).
– view in browser: for me “run” works good enough, but you also find this option on the context menu
– line folding: it’s there
– send in email: well the email client is sitting there on the taskbar already
– upcase, lowercase: there
– view file in text mode: right click, “open with…”, select notepad…actually you could do that for an hex editor too
Anyway..you know you can creates macros for the missing stuff, right?
Rodrigo,
Sure it’s ‘there’… somewhere… or I could ‘write a macro’ – or in UltraEdit, just press the button or key to do it. I think we aren’t talking about the same things, though – you are talking in terms of Code editing only, I’m talking about all code related editing. For example, let’s say you are reading a string from the database and writing it to xml – you log the string that you are writing to xml in a text log file – another program is reading the xml and complaining that it’s invalid xml at character 92, line 40. You bring up the log file in VS – looks fine – what’s going on? No telling, bring up UltraEdit and look at the line – looks fine, what’s going on? Click Hex and lo and behold some snark has added an emdash (non-ascii character that looks like an ascii ‘-‘) to the data in the database.
You are correct that if you dig deeply enough into the capabilities of Studio’s editing facilities, that it’s got a lot of the same functionality – it’s just not nearly as accessible and carries a ton of overhead – takes it forever to start up – less than a sec for UE or Textpad. I’m not trying to start a flamewar here, either. I use VS’s editor for writing code – like I said intellisense is great, but as all around editor – forget it…
Will
OK sorry if I got it wrong, it seemed to me that you were saying these features didn’t exist at all.
Having said that, I agree that VS.Net is far from perfect (for example the CSS editor inside vs.net sux big time, I keep using the one bundled with Homesite instead) but then again I haven’t find a perfect editor.
Anyway, I didn’t want to start any kind of flamewar, if I consider “language wars” stupid, what to say about “editor wars”!
-R
Language and editor wars aside, it takes me twice as long and costs 10 times as much to develop, manage and host in VS.Net/ASP.Net/C#.
In the real world, that hurts a lot. People don’t have the budget these days for sites which cost thoussands of dollars/pounds.
I am a MCSD but I develop using Textpad, Postgres, PHP and OpenBSD…
I get what you’re saying in principle, but in practice – where are you calculating the ‘cost’?
Developing in ASP.NET/C# actually don’t have to cost a red cent (other than effort) – the SDK is free. Studio is expensive, yes, but it’s not required to develop apps. Postgres works well enough with .NET, although MySQL offers a driver that will (in theory) outperform it using ADO.NET.
The Server is where I calculate most of the ‘cost’ and it’s not radically expensive to host a website with IIS, these days.
On the twice as fast using other tools comment, that’s been your experience I take it? VS.NET most definitely supports RAD and applications from simple mom and pop ecommerce sites to complex search, catalog and financial websites can be rapidly constructed using it. Experience is the best teacher… For example, Multi-tiered architectures are cool to read about and can entertain a group of Comp-Sci students, but are rarely required in the majority of ‘real world’ situations – at least to the degree that they are hyped. The concept is sound and should be strived for at times, but generally an interface, database, and logic are what’s required to service a small-medium size website. How much separation there is, is a matter of no small consideration. However, unless you are developing an enterprise solution – less is more. The default codebehind separation of interface from logic is sufficient. The logic and data objects can be hand written by a proficient developer without introducing an additional hierarchy of classes, separated by more file boundaries. I guess what I’m saying is that I can write a Web Application in .NET that reads some data from a DB, joining a couple of tables, convert that to XML and send it to another process, tell the user what’s going on and whatnot in a single pair of .aspx and .aspx.cs files, using a text editor and the command line compiler – not radically different from any web development platform…
I would agree that there’s a lot more room for abuse on the cost front in .NET, but it doesn’t have to be that way.
Later,
Will