Rants Tagged with “.NET”
I found it very interesting in a little test that the Flags attribute doesn't seem to change the way that the CLR numbers Enumerations. So that this enumeration:
public enum UnFoo
{
Foo,
Bar,
Quux,
Foobar
}
this code ends up not working as i'd expect:
Foo f = Foo.Foo | Foo.Bar | Foo.Quux;
Console.WriteLine(f.ToString());
this results in:
Foobar
This happens because Foo = 0, Bar = 1, Quux = 2, Foobar = 3, and Foo | Bar | Quux | Foobar = 3. So if you use a [Flags], make sure and number the enum properly:
[Flags]
public enum Foo
{
Foo = 1,
Bar = 2,
Quux = 4,
Foobar = 8
}
Another interesting thing is that I like that Enum.ToString() and Enum.Parse() do the right thing with Flaged enumerations:
Foo f = Foo.Foo | Foo.Bar | Foo.Quux;
Foo pf = (Foo) Enum.Parse(typeof(Foo), f.ToString());
if (f == pf) Console.WriteLine("They equal!");
It's cool that when you -OR- flagged numerations together that the Enum.ToString() turns it into a common delimited list. How cool is that?
I've spent much of the last three days with a client helping them figure out their domain model for their new system. What's been a delight is using the VS 2005 Class Diagram to capture the ideas. Its been very easy to throw up on a projector and describe the relationships between the data. While we're actually not using it to design the system, it was much easier to use the Class Diagram in VS 2005 than to fire up either
Enterprise Architect (which I like a lot for UML/Database work) or Visio. Two Thumbs Up!
I have been struggling and playing with RAD'ing some quick and dirty pages for the
ASP.NET 2.0 conversion of this site. They are Admin pages so they aren't hit often. Quick and dirty seemed to be the perfect solution. I did run into some speed bumps, but now that I understand what they wanted from me, they are working great! I am a big fan of the GridView/FormView/DetailsView controls. Check them out if you get a chance.
My article on upgrading tips for your Typed DataSets is up on DevSource. Take a look!
This new property (*not* event), allows you to wire up clientside code to be executed before the server-side onclick is handled. In the old days we had to do this manually. For example, this is how you would hook up a simple confirmation dialog:
<script language="jscript" type="text/jscript">
<!--
function deleteConfirmation(event)
{
if (!window.confirm("Are you sure?"))
{
window.event.returnValue = false;
}
}
-->
</script>
<asp:LinkButton ID="deleteButton"
runat="server"
CausesValidation="false"
CommandName="Delete"
OnClick="deleteButton_Click"
OnClientClick="deleteConfirmation()"
Text="Delete">
</asp:LinkButton> This allows you to cancel the server-side event if the user says nope! Cool!
This probably isn't entirely correct since I am just looking at the output (e.g. the database rows) to determine this. For each object in profile (i.e. Users), there is a single row in the aspnet_Profile table. This table is made up like so:
CREATE TABLE [aspnet_Profile] (
[UserId] [uniqueidentifier] NOT NULL,
[PropertyNames] [ntext] NOT NULL ,
[PropertyValuesString] [ntext] NOT NULL ,
[PropertyValuesBinary] [image] NOT NULL ,
[LastUpdatedDate] [datetime] NOT NULL ) The three middle columns are used to store the properties and their values. PropertyNames stores a list of properties with hints on how to retrieve it from the String or Binary column. For example:
IsClient:S:0:4:Parent:B:0:-1:LogoUrl:S:4:39:Expired:B:0:-1:Row:B:0:-1:CssUrl:S:43:28:Services:S:71:239: Each section of this string is the metadata about the property:
- First is the name of a property. This needs to map directly to the property names in the web.config file.
- Then the place its to be stored (S = String, B = Binary). Note that the placement in String or Binary form is based on the datatype or the serialization format. XML Serialization ends up in Strings and binary serialization ends up in the binary area. It seems that numbers also end up in binary format.
- Start Position. For a string it's where in the string to start looking for that value. Understand that this will change as the size of the property changes. Using -1 in a Binary stored property seems to indicate that it is not stored at all. For example, the IsClient is a Boolean, but is stored as a string here, but Expired is also a boolean, but since it has a -1 we know it isn't actually stored.
- Length. If the start position is -1, there will be no length. Otherwise this is used to substring out the actual data in the string and binary fields.
As you would expect, the string field may be a mix of XML serialized data and string data. For example, the string field here is stored like so:
Truehttp://wildermuth.com/images/adoguylogo.gifhttp://wildermuth.com/adoguy.css
<?xml version="1.0" encoding="utf-16"?>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>Cell Manager</string>
<string>Cell Manager</string>
</ArrayOfString>
You'll notice that the first four characters are the word "True" which corresponds to the PropertyNames "IsClient:S:0:4:". Likewise I have a property called Services which is the XML Serialized piece at the end that corresponds to "Services:S:71:239:".
So far I like the profile stuff and luckily it is using the common provider model because the one glaring weakness here is searching. Finding all Users with a specific Property value is going to be very very difficult. My plan is to write my own provider that is a specialization of the SqlProfileProvider but normalizing the data into a PropertyName and Value table. I have not dug deep into the ramifications as it has to do with Groups or custom serialized types, but I don't think they will get in the way.
If anyone has any comment on this, I am very open to hear what you have to say.
I am working on a portal project with ASP.NET 2.0 and I am loving it. Lots of stuff is in the box that I need. The project is using VB.NET so I wanted to make sure that everything was Option Explcit On and Option Strict On...but since it is a Web Application, the normal property pages are nowhere to be found (unless I am missing it). If I create any other project type (I think), I can look at the project property pages and see the Compile tab:

Why are web apps treated so differently these days? Can anyone explain how I missed this?
In Visual Studio 2005, when you create a Typed DataSet, it automatically creates TableAdapters for you. These are interesting objects that use a DataAdapter internally to make a more cohesive data access layer. It will certainly help the RAD developers get started. I am not so sure about how they will work long-term though.
One of the more interesting things that these new Typed DataSets do is store a link to connection information in the Typed DataSet. These seems to be used for the TableAdapters to do their open's with. Problem seems to be that if you migrate a Typed DataSet from 1.1, there is no way to insert this connection information. Even if you do, the designer in Beta 2 doesn't allow you to attach TableAdapters to your existing Typed DataSet. This means that if you want to use TableAdapters you will need to re-do your Typed DataSets entirely.
I just finished an article talking about about some of these migration issues. I'll post a link when it gets published.
Not sure how I missed this before. I was very impressed by this discussion of the issues around Typed DataSets. Yeah, sure he agrees with most of my opinions...but I like hearing that as well as dissenting opinions.
I was reading this article which is mostly about Oracle's grid database support, but what surprised me was this
link that talks about
Microsoft's partnership to include the CLR in 10g? This i've got to check out.