Recently my team began the process of revising out coding standards document. We are revisiting this issue because the standards were developed when we used VB 6 and ASP 3.0. I have offered my opinions to the team, and I’ll post them here. Comments are welcome.
All,
To throw in my opinion, I would agree with the below proposed changes with the following exceptions:
All pulic, protected, or internal interfaces should use PascalCasing.
All private members should use camelCasing.
All private class members should be prefixed with “_”
“p_”, “m_”, “g_”, should not be used, and Hungarian notation should not be used.
For instance:
namespace GpdsIT.SomeRandomApp {
public class IDBadge {
private Guid _uniqueID;
private string _badgeName = string.Empty;
public Guid UniqueID {
get { return _uniqueID; }
set { _uniqueID = value; }
}
public string Name {
get { return _badgeName; }
set { _badgeName = value; }
}
public IDBadge(string badgeName) {
_uniqueID = Guid.NewGuid();
_badgeName = badgeName;
}
}
}
I’ll refer you to the MSDN Design Guidelines for Class Library Developers at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconNETFrameworkDesignGuidelines.asp.
The Naming Guidelines link has naming convention recommendations that support the above rules, and the other links have very valuable information about .Net best practices.
I’m currently finishing the installation of Windows Server 2003 on my development workstation. I’ve heard and agree with the argument that you should develop with the OS on which your code will be running. For me, it’s ASP.NET. Especially with the bug in the XP large object heap, I’ve decided to make the switch. We’ll see how it goes. I like to profile my code, so I feel a little better doing performance testing on a server OS. A limiting factor is that not all the software I use is supported on Server 2003, but so far all of it works. For instance, MS Virtual PC 2004 isn’t supported, but it works fine. I maintain in image of XP Pro that is the minimum requirements for user workstations, so I can test the UI with that. All the code, however, will run on my server OS. I’ve heard arguments for and against this approach, so we’ll see how it goes. I can always fall back onto Windows XP if I have to. If any readers have experience developing on a server OS (successes or failures), I’d like to read the comments. I’ve heard several opinions, but none of the opinions against this method come from actually trying it. Maybe in a few months I’ll post a follow-up article on how it is going.
I’m am so excited. I have released version 0.9 of my EZWeb framework on GotDotNet. Major beta release. I’ve made content editing part of page administration. Fixed many bugs. Created an extendable user framework. Updgraded to FreeTextBox 2.0.6. Added file and image upload feature. Added SqlFactory class wrapper of the MS Data Access application block for data access in you application. It’s almost worthy of being used as an application framework in a real project. My next release will be version 1.0 stable release. Please offer feedback. I have not included more templates because everyone will want to make their own site look and feel anyway.
EZWeb works out of the box. Set up a virtual directory, give aspnet user write permission to it, and pull it up in the browser. You can start creating your website right away. Extend it with your own user by using ClientUserSample.cs as a guide and inheriting WebPrincipal. Then change web.config to refer to your assembly for the user class.
This is an ASP.NET VS.NET 2003 project in C#.
Noah Coad tell about his NovaBlog tool for one-touch blogging from the desktop. A command-line tool for a true programmer. After all, are all programs written FOR programmers? The command-line NovaBlog can be called from any text editor or integrated into any other program by calling it and passing the post information as arguments. Whether or not the source code will be shared is still pending. C’mon, Noah. Do share!
I have a library, and I use an Interface to define the required members of the clients “User” object in order for the client’s type to work with my library. As long as they implement the members in my interface, everything is fine. My Inferface implements IPrincipal, so it’s a standard .Net Framework user type. It can be used in ASP.NET seamlessly. When coding my library, I don’t know or have access to the client’s type that will implement my interface. How, then, can I get it at runtime and code against it? I have static and instance calls to methods in my interface. The answer: Reflection and runtime-loading of the client’s type. Here’s some code I’m using to do it:
public static Type ClientType
{
get
{
Assembly ClientAssembly;
ClientAssembly = Assembly.Load(ConfigurationSettings.AppSettings[“UserAssemblyName”]);
Type clientType = ClientAssembly.GetType(ConfigurationSettings.AppSettings[“UserTypeName”], true, false);
return clientType;
}
}
This is a static property in my library to encapsulate the getting of the client’s type. The client will have to define in the web.config file the assembly and namespace, and then we’re good. Once I have the type, I can invoke the members using methods of the Type object. I know the members I need to invoke because I’ve defined an interface, so the client’s object MUST have the members I need. Now the client can have their own user object, and once they implement my interface, they are completely interoperable with my library which will make heavy use of their custom type.
I’ve used all of the C# Jump statements. You probably use break, continue, and return on a daily basis. And in your switch statements, you probably use default. But do you use the goto statement? If you are like me, you’ve been conditioned since QBasic to avoid the infamous goto statement. It creates spaghetti code, right? Well, if you use it irresponsibly, it does, but what about nested if statements? How do you jump out of 2 nested if statements? break and continue don’t work. My solution: Use the goto statement.
<snippet>
if(condition 1)
{
statement;
statement;
if(condition 2)
{
statement;
goto endIf;
}
}
statement-that-should not happen if condition 2 is not met;
endIf:; //label to jump to and empty statement included.
</snippet>
You can probably think of several ways to refactor the above in order to avoid the goto statement, but in this case, the goto statement was the best decision, and this is a very valid use of the statement, and it does not create spaghetti code.
To expand on my previous post, here is a reply I received from Dino Esposito about what goes on behind the scenes on a page request:
Hi Jeffrey
1) The runtime figures out the name of the class to serve that page request. If the class can’t be found in any of the loaded assemblies, the source is compiled. If the class is found (means the page’s been compiled already), it checks the timestamp of the class against a value stored in an internal store. If they differ, it assumes the page has been compiled. This happens with ASPX files
2) If you change the CS/VB nothing happens and an explicit compile step is required
3) Changes in inline code trigger the recompile
–Dino
Joe King added to my post about knowing Html and script. I agree with everything he says, and I was mostly targeting ASP.NET beginners (hence the “level 100” tag). For readers who are just getting started in .Net, you will be able to do so much more with ASP.NET with a solid foundation in Html and Script (and CSS).
Recently I converted a DataGrid to a DataList because I decided that I didn’t want my two pieces of data in different table cells. After converting it to a DataList, I ran into an issue setting the Header text and Footer text programmatically. I had my HeaderTemplate with a asp:Literal in there. From my code, I expected to be able to do DataList.Header.FindControl(), but Header isn’t a property, and the HeaderTemplate property is just the interface definition.
1. The control doesn’t even exist until the DataList.DataBind() method is run.
2. Looking at the control tree in the trace, I find that it renders as DataList:_ctl0:myControl for the Header and DataList:_ctl{Count-1}:myControl for the Footer.
3. To make it work, I have to use DataList.Controls[0].FindControl(”myControl”) for the header and DataList.Controls[Count – 1].FindControl(”myControl”).
So what is the reliable way to get the Header and Footer. Especially for the footer, I have to get the last control in the Controls collection. The header and footer should be separate from the rest of the bound list, but that, apparantly, is the case.
I would prefer a more elegant solution and one that is more like the rest of the classes in the .Net Framework. For instance, the Header and Footer should be able to accept and ID property for control naming. Better yet, they should be properties of the DataList, but since they don’t exist until runtime, we should at least be able to FindControl(”HeaderID”) at runtime, so the ID property would solve that.
Another quirk in the ASP.NET controls, but there is a workaround.
To expand on the topic started in my previous post, here is an overview on how ASP.NET compiles and recompiles assemblies.
You all know that when you initially make an .aspx page and run it, the application is started and your stuff is compiled into cached assemblies stored by default in C:WINNTMicrosoft.NETFrameworkv1.1.4322Temporary ASP.NET Files#AppName#. If you keep Win Explorer open to that directory while you restart your app, you’ll see the new temporary files appear as the app is compiled for the first time. Then for every subsequent request, those files don’t change. Then change ANYTHING in an .aspx file (even just one character in the markup). Actually, you don’t have to change anything, just save it again. As soon as you save it, the cached assembly for that page will be invalidated, and when you hit the page with the browser again, it will be recompiled, and you will see new files pop up, and the old ones will have “.delete” appended. On the next app restart, the .delete files will be purged. So to clarify my previous post, ASP.NET does NOT check for changes on every page hit. It checks for a cached assembly and uses it if it exists. When a file is saved, the cached assembly is invalidated, so when the page is requested, it doesn’t find a valid assembly, so it must compile it.
So regarding the previous post, whether you use inline code, code-behind, code-beside, base page inheritence, or a mixture of all of them, the page compilation will have the same behavior, and the request lifecycle will also be the same. There is no performance difference based on the method in which you code.