Please provide feedback to the Whidbey Team – level 000
The MSDN Product Feedback Center is looking for feedback. Please provided feedback concerning how Whidbey can be made better before RTM. If you are using it, please log bugs and suggestions.
Jeffrey Palermo, Microsoft MVP, Author, Speaker, Clear Measure Chief Architect, Azure DevOps Expert
The MSDN Product Feedback Center is looking for feedback. Please provided feedback concerning how Whidbey can be made better before RTM. If you are using it, please log bugs and suggestions.
Earlier, I blogged about using controls that are embedded in unusual places in the control tree of the DataGrid. For instance, putting a LinkButton for adding a new record in the header or footer of the DataGrid. You have to manually manipulate the Controls collection to do this.
Another issue is what if you put that LinkButton in the same column as the Edit, update, cancel, delete buttons? If you want to restrict editing of the data, a step on the UI would be to hide that entire column. Seems pretty straight-forward, but how do you get a reference to that column? I searched, and the only way I found was to reference it by the index in the Columns collection:
dgd.Columns[7].Visible = false;
That works well, but it bit me in the butt when I tried to maintain that code. Down the road it became necessary to add two columns to that DataGrid. Then, you guessed it! A nice, little bug in my code. Usually I’m able to avoid the debugger in VS by writing modular code and using the heck out of the ASP.NET Trace feature (great for code maintenance), but this was an issue that actually required a breakpoint. Once inside the code, it was very clear what was happening. I changed the index to the new index of the edit column, and my problem was fixed (until next time), but isn’t there a more maintainable way to do this? What happens when another developer needs to modify my application. Yeah, I document the heck out of it, but why can’t the Columns collection support column name identifiers as well. I know the answer (CollectionBase), but it would be nice.
For now, I’ll have several lines of comments above that code.
I recently downloaded and used Lutz Roeder’s Reflector program, and it is a pretty sweet tool. VS 2005 Beta 1 has the class browser just like VS 2003, but the disassembler is what make Lutz’s tool so useful.
The disassembler takes the compiled MSIL and converts it back into its best guess of C# or VB or Delphi (you can also view the IL). Using that guessed code (which is VERY accurate), you can find out how a method was implemented. It can be used on .Net Framework types as well.
It saved me a lot of time just today. I knew I need to use a certain object in a predefined assembly, but I didn’t know how the class was intended to be created. There was a constructor with parameters for all the things that needed to be populated, but I didn’t know all that information. Using the disassembler on another class in that assembly that used the object in question, I was able to see that a completely different object is in charge of instantiating my said object. Now, I can easily creat my mystery object, and Lutz has saved me time. Thanks!
In .Net 1.0 and 1.1, we got used to creating a private constructor if we wanted to prevent someone from creating an instance of our class. If we did not define a constructor, the default constructor was compiled for use, and the user could create an empty instance. So we prevented this by creating the private constructor. In C# we have classes, but in VB, there are classes and then modules which can contain only static (Shared) methods. In .Net v2.0 Beta 1, C# can have the static keyword applied to classes to prevent them from having instances. Now, I’ve deleted my private contructor and applied the static keyword! There’s not going back now!
For those of you who use FxCop, beware of version 2.0. Actually, look forward to version 2.0 and jump for joy, but it would benefit you to learn about version 2.0 now so that you can prepare to move to the next version. I’ve migrated some v1.1 code I wrote last year to v2.0 Beta 1. I had run FxCop on my assembly last year, and I decided to follow all the Microsoft Recommended conventions. That included NOT using the default overload of the .ToString() method. Instead, I was supposed to use the overload that specifies an IFormatProvider, so for most of my code, I used ToString(CultureInfo.InvariantCulture), and now in VS 2005 Beta 1, I am getting warnings:
Warning 3 ‘System.Enum.ToString(System.IFormatProvider)’ is obsolete: ‘The provider argument is not used. Please use ToString().’ C:. . .Visual StudioProjects. . File.cs 617 64
I thought it was a pain to specify CultureInfo.InvariantCulture for every call, but I went along with it. I guess the MS people decided to agree with me. 🙂
I’m actually glad about this change. Seems like most v2.0 changes are for the better. . . . but I still take issue with not having a concrete assembly in web site projects – we need a way to configure what the dynamically compiled assembly will be called.
I invite you to visit the VS 2005 Beta 1 Developer Center. You can submit suggestions and bugs to the VS 2005 team. I’ve submitted several bugs already and made a suggestion. Two of my bugs have been validated, and another was a duplicate. Hopefully my bugs will be fixed in the Beta 2. Either way, I’ve done MY part to ensure that the IDE I USE is the best it can be.
The web.config file in ASP.NET enables configuration of the entire ASP.NET application. It is a file that is part of just about every ASP.NET application, yet I see many developer who roll their own configuration schemes beside the web.config file instead of making use of the functionality already built in. Yes, some may use the appSettings section and then just retrieve a value from a key, but web.config can do so much more than that! Here is a sample of how easy it is to add your own configuration section, thereby partitioning a section of configuration items away from the others:
<configuration>
<configSections>
<sectionGroup name=”MyCompany.MyApp.MyNamespace”>
<section name=”SomeClassesConfig”
type=“MyCompany.MyApp.MyConfigHandler“,MyCompany.MyApp” />
</sectionGroup>
</configSections>
<MyCompany.MyApp.MyNamespace>
<SomeClassesConfig>
<add key=”myKey” value=”myValue” />
</SomeClassesConfig>
</MyCompany.MyApp.MyNamespace>
</configuration>
Then, in your code, you just have a class, MyCompany.MyApp.MyConfigHandler that inherits from System.Configuration.NameValueSectionHandler, and that’s all it takes. If you don’t make your own ConfigHandler, then you have to specify the strong name in your type=”” attribute, and not only is that painful, but when you migrate this code to .Net 2.0 and beyond, you will have to modify every place where you gave a strong name. If you make a superclass of it, then when you migrate the superclass, you’re golden.
To get to these values in your code, you just use a NameValueCollection that you can get from calling:
ConfigurationSettings.GetConfig(“MyCompany.MyApp.MyNamespace/SomeClassesConfig“);
Does that look like an XPath expression to you?
You can further extend the web.config file with your own ConfigHandler that has nested XML elements instead of just a key and a value. You could store complete object information in the web.config (if the data rarely changes). Remember that every change of the web.config forces a restart on that directory and its children.
Coming up in May of next year, .Net 2.0 will have the APIs to modify .config files programmatically. Check out the Beta 1 to use this functionality right now.
Two months ago, I blogged about installing Server 2k3 on my development laptop. I’m following up with that post to say that everything has gone just fine. Every XP driver worked perfectly on my Dell Lattitude D600. Everything has been perfect. Very stable, very fast, and I can profile my applications and have confidence that the results will be better than if I profiled them on an XP box. Besides. XP .Net CLR 1.1 has a bug in the Large Object Heap that throws stuff off.
I can now recommend using Server 2k3 as a development platform for web applications.
This post is to share a backwards compatibility bug in v2.0 Beta 1. I ran into this bug when porting a project of mine. This wasn’t the only issue, but here it is. Run this page under v1.1 and click the button to your heart’s content:
<%@ Page%>
<HTML>
<HEAD>
<title>WebForm1</title>
</HEAD>
<body>
<form id=”Form1″ method=”post” runat=”server”>
<asp:Button id=”Button1″ runat=”server” Text=”Button” OnClick=”Button1_Click”></asp:Button>
</form>
</body>
</HTML>
<script runat=”server”>
private void Button1_Click(object sender, System.EventArgs e)
{
Server.Transfer(Request.Path, true);
}
</script>
Now, run this page under v2.0. You will click the button, and your computer will never return the page. It will lock up. But really it’s not. Your computer is in an infinite loop. This is because the second parameter of Server.Transfer has been changed.
It’s nice that Microsoft added functionality, but we really just need another overload. Leave the method like v1.1 because this broke my project, so I’m sure it will break some other projects. Add an overload to accept a third parameter as a boolean which dictates whether to preserve the form values:
Server.Transfer(Request.Path, true, false);
I would use the above so that my querystring would be preserved but the form values would not.
Tim Sneath posted a great piece of information today. I ran into this issue exactly:
I installed Whidbey and then Yukon. Yukon setup kept complaining that there was already a conflicting version of Yukon on the box (I had MSDE Express), but that wasn’t it. Tim points out that Yukon has a slightly new version of the .Net framework, so what I need to do is uninstall v2.0 (not VS), and then Yukon will install fine. Great job Tim. I was stumped.
By the way, I saw a demo of stored procedures in .Net languages, and I’d like to clear up something:
In Yukon, there is no way to get or modify data without using TSQL. Yes, stored procedures can be written in any .Net language, but stored procedures are just executable bits of logic. Manipulating rowsets in the database still requires TSQL calls, but any calculations, validation, etc can be coded in the .Net language. That being said, is there a reason to code stored procedures in .Net? Not for me (yet). I make it a habit NOT to write logic in my Sprocs. I manipulate data rowsets, and that’s it, so if I have to use TSQL to manipulate rowsets, then I’m right where I am now.
Also, what about the issue of database migration, or switching databases. If you write database sprocs in .Net, you can never switch databases. What if you develop a product with Yukon. You’ll never be able to implement it with SQL Server 2000, and 2000 will be around for a long, long time because it suits the needs of so many businesses.
I’m probably coming across as a pessimist, but that’s not my intent. I just know it’s inevitable that somebody will devleop an entire application on Yukon’s CLR and then wonder why their database box is so damn slow. At least, it’ll be good material for The Daily WTF.