June 2006 - Posts

I've been reading a lot about custom application design lately, and I have a book proposing using a dictionary or collection for storing properties in business objects.  I wondered about that for a while, and while reading about object design, came across this article:  http://www.codeproject.com/gen/design/AOM_Property.asp.

I guess I'm somewhat torn; on one case I see the lack of type specificity, as well as the potential to not know all of the values assigned (more so in a dictionary setting).  However, I see the power in this, as after reading it, I saw some of my own limitations and excessiveness in my code.  It makes sense to use an attribute collection for properties.

But I also have to wonder whether that will make it worse with all of the boxing and unboxing of values that will occur.  Maybe not so much from a performance perspective, but a design one.  I think that is one of the reasons developers do prefer creating properties in the objects directly.

I have to say that is a better approach in some situations (although I wouldn't implement it in a factory pattern), but there is something in me that makes it feel different or awkward for me, as if it is an unnatural way to do things, even though it may be better........

Posted by bmains | with no comments
Filed under:

Both C# and VB.NET support XML comment notation (/// or ''') in 2005 and, when a project is compiled in Visual Studio 2005, a file is created that contains a complete listing of all comments made for classes, methods, properties, etc.  This is a great feature because it immediately makes available all of the documentation into one file.

One of the things I played around with was the ability to add additional XML tags.  For example, in my Data Access Layer, I added a <storedProcedure> element, which compiled to the XML documentation file as well.  This way, I also knew which stored procedures I was actually using in my data components.  That is a great feature.

Posted by bmains | 1 comment(s)
Filed under:

Precompiling is a new option of the .NET 2.0 framework.  Sites can be precompiled so that whenever a user first enters the web page, the site is already compiled with the changes.  Previously, whenever a 1.1 framework page was first accessed, there was a performance decrease because the page had to be compiled on the initial load.  With precompiling, this performance decrease isn't an issue.

However, you have to keep in mind that you can't change the content for ASPX pages dynamically; instead, you have to recompile everytime you make changes to a compiled file.  This is because precompiled ASPX files no longer store the HTML in the file; rather the file is a "stub" or "marker", noting that the file exists, but the code is retrieved from a DLL.  If you look in a precompiled site's bin folder, you will notice a lot more compiled files and dlls than you do under normal build circumstances.  That is because this usually occurs on the fly.

I created a batch file to do the creation for me, because it involves using the framework's aspnet_compiler executable to do the creation.  This utility uses either the physical (-p) or virtual (-v) path (as well as other options), and the folder to output to as the second parameter.  I also included a remove directory command because precomiling requires a new folder, and as such, my script looks like this:

rd /s /q c:\precompiled_site
<path to 2.0 framework>\aspnet_compiler -v virtualFolder c:\precompiled_site
pause

See this for more details:  http://msdn2.microsoft.com/en-us/library/ms229863.aspx

Posted by bmains | 1 comment(s)
Filed under:
I would like to talk theory for a little bit about friend methods.  There has been some talk over whether you should or should not use friend methods.  If you take a look into the .NET framework API's you are bound to find heavy use of friend methods, properties, and classes.  However, some people have said never to use them.

I see wisdom in both lines of arguments.  Friend functions can be a problem because if you rely on them heavily, it opens the constructors, methods, and properties up to many possible internal access points, which could result in overwriting previous values.  In my own coding experiences, I've seen several times where the use of several friend functions made the code more bogged down through the approach I used, instead of using an alternative approach with public properties/methods instead.  A method in one class called a method in another, and it created sort of a networking scheme of friend function calls, which can become unmanagable.  Instead, a refactored approach made it more manageable.

However, there were times, when being consistent with friend functions, increased the efficiency of the API.  In one example, because of loading data in a consistent way, using a friend function in the class that was having the data loaded made it more manageable when editing code dealing with that class; all data access code was centrally stored in this one object.  Then, the parent object that needs to populate it can call this loading method to load the data.  Any object needing to load the data can also do so, using one method call.

I think friend functions need to be limited in their use, but not eliminated.  When using them, extra care is needed to ensure that it isn't making the code unmanageable and adding extra complexity.  Keep in mind all of the access points that friend functions open your code up to, and try to keep it to a minimal set.  Sometimes, realizing an alternative approach can lead to a better design.
Posted by bmains | with no comments
Filed under:
The new Security Application Block in the Enterprise Library Jan edition authenticates and authorizes users in windows and web applications. In an article I wrote, I tackle authorizing users using the Roles provider to create an IPrincipal object and authorize the user for a specific task.

The security block uses rules-based processing for validating users for specific tasks. A rule specifies which user or role has permissions to it. When you authorize a user, you specify the rule name determining if they have access, and the method returns a boolean value stating that.

It is important to understand the concept of declaring more rules than are necessarily needed. Breaking out rules instead of using one rule for many tasks can make maintenance on an application harder later in the development cycle, especially if you need to add a role for an action for only part of the rule. For instance, if you use one rule for insert, update, and delete actions, but later you want to add a role for insert and update actions, then you need to change your code. Otherwise, if the rules were broken out for each action, this modification is simple.
Posted by bmains | with no comments
Filed under: ,
I develop with Visual Basic 2005 at work and there was a reported problem with the compiler that would throw errors whenever doing simple tasks in Visual Studio .NET. It was a problem because it would frequently happen, and after selecting the do not send error report to Microsoft option, I would lose intellisense support, and much more that makes Visual Studio .NET a great product.

If you have these problems, there is a hotfix available; SP 1 is slated towards the later half of the year, so it would be useful to install the hotfix now. You can find it at: http://support.microsoft.com/kb/915038
Posted by bmains | with no comments
I recently ran across a problem with FindControl in a content page in ASP.NET 2.0. The content page was using findcontrol to dynamically get the reference to a control, but the problem is using the ID no longer works as in ASP.NET 1.1. You have to use the unique ID to get the control, which if you know about the process, is the master page control ID, then parent controls, then your control you want to get. So, if you want to get the control using the control ID, you will have to create a custom FindControl method that iterates through the control collection. Not fun.

For example, here is the ID of a control in a user control, which isn't really easy to get at the name:
ctl00_cphBody_wucEventCalendar_calEvents
Posted by bmains | 2 comment(s)
Filed under:
I have a page where I cache the data, but set the gridview's enableviewstate to false, which means that I load the data on every page load. This makes a section, where I load a lot of data, go faster, because the gridview doesn't have to hold the large viewstate, and the roundtrip is quicker that way. But, I have the data in the page, then I trigger a search. The postback occurs, and the gridview is bound to the old search results, then the button click fires, the new search results are retrieved, then the grid is bound again. I wanted a way to avoid that.

I found that the Request.Form("__eventtarget") has the ID of the control that is responsible for the search. So by checking to see if the ID of the linkbutton fired is in the __eventtarget field, I can avoid initially loading the data in the page load, and only load whenever the linkbutton is clicked.

This even works for linkbuttons in a user control, because the ID looks something like ctl100$wucUserControl$lnkSearch, and if you do a search for:

if (Request.Form["__eventtarget"].Contains(this.lnkSearch.ID))
//skip loading

I get errors when nothing is there, so I usually wrap it around a try catch block to avoid that. If it is found, then I exit the page load event; otherwise, continue processing as normal.
Posted by bmains | with no comments
Filed under:
I was using a strongly-typed dataset in one of my projects when I noticed an error I was getting:

"Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints."

I was checking around and found out that the fields in the DataTable have a NullValue property, which specifies an action; it can be empty, null, or throw an exception. Each one was throw an exception, so I changed that quickly for the null fields. But that didn't solve the problem. I was looking around on the web, when something got me thinking; I double-checked my select query, and it turns out I wasn't returning all the fields as shown in the data table; once I added the missing field to the query, everything was back to normal.

I actually like the Enterprise Library, manually coding the access to the database, to retrieve the data from the database.  I don't like how the datasets are generated, as it may not always easily work in customized situations, and I wanted to be consistent with my data access.  Still, for RAD development, it is a good tool to get things started, if at least temporarily until another release.
Posted by bmains | with no comments
Filed under:
The two controls listed above provide mechanisms to upload files to the web server. With the 2.0 framework, the FileUpload is a server control equivalent to the HtmlInputFile, and provides some additional enhancements to the control. It adds a HasFile property stating if a file has been selected in the upload box, as well as additional file accessing properties directly in the control, instead of referencing PostedFile. I did notice one quirk; the FileName property in FileUpload only contains the name of the file; the FileName property in the PostedFile property contains the entire path.

One other point; these controls do not save their viewstate. LoadPostData always returns false, and the Value property is readonly. You can inherit from the class and override LoadPostData to return true and try to restore the value, but value is readonly. I did read about that it may be possible to set the value through javascript, but in all my attempts, I failed, so I gave up on it.
If you want to create one to restore viewstate, you have to look at that as an option.

Here is a multiple file upload control that I created, which renders multiple upload boxes so a user can upload in bulk. The only problem is this control does not retain its state across postbacks, and as such, you have to create the number of boxes you want first before you browse to the files.
Posted by bmains | with no comments
Filed under:
I was binding to the Membership class, but it didn't come up in the dropdown in the configuration tool for the ObjectDataSource in the designer. So as an alternative, you can type in the TypeName property, set to the System.Web.Security.Membership type.  After that, go back into the configuration tool. You'll be able to get all of the methods in the drop down for the Select, Update, Insert, or Delete methods, so you can use the designer this way instead of doing it manually.
Posted by bmains | with no comments
Filed under:
Here's an article I wrote on Custom EditorPart controls. These editor parts are cool, because they render like any other control, and work dynamically to edit the values of a class that inherits from the WebPart class. Classes that implement IWebPart can't use this functionality.
Posted by bmains | with no comments
Filed under: ,
In my custom pages, I was overriding the ID property of the Page. I wanted to use this to return the name of the page ("default.aspx") to whoever is using it, to make it easier to reference this. But because of this, I got an error "key cannot be null: parameter name value". When I removed this, it fixed this error. So, in case anybody had a similar problem.
Posted by bmains | 2 comment(s)
Filed under:
I was getting selected data from a data component, but I was running into a problem where when the ID was not present (invalid value), and an error is thrown. This is of course correct; however, the ObjectDataSource was calling the method to select the data, even when no valid ID value was provided (this was a master/detail type architecture, where the gridview selects a row, then this ODS is fired with the appropriate ID value; however, on the initial load, no ID value is selected). So I was looking at a way to prevent this, and came across the Selecting event, which fires when trying to select data. I did a quick comparison against the ID, and if not a positive value, cancel the selection. Here's the code:


void ods_Selecting(object sender, ObjectDataSourceSelectingEventArgs e)
{
    if (int.Parse(e.InputParameters["intID"].ToString()) <= 0)         e.Cancel = true;
}
Posted by bmains | with no comments
Filed under:
I was having a problem binding to a business component that I had. I was binding to a business component that returned a datatable with the results to a GridView, but I was getting errors that a property (the connection string key, which I pass dynamically) wasn't being provided, and the data component I use was throwing an error because of it.

That was the correct behavior, because I didn't want the data component having no key to work with. So instead, I was looking around, and found the ObjectCreated event. This event contains an ObjectDataSourceEventArgs event argument that has the instantiated object (through the ObjectInstance property). I could then convert the type to the appropriate type and pass the value, before the binding took place. An example would look something like this:

private void ods_ObjectCreated(object sender, ObjectDataSourceEventArgs e)
{
    if (e.ObjectInstance is MyType)
    {
        ((MyType)e.ObjectInstance).Key = "my key";
    }
}
Posted by bmains | with no comments
Filed under:
More Posts Next page »