Tuesday, November 18, 2008
List does not exist error when creating an alert from workflow
posted on Tuesday, November 18, 2008 9:59:47 AM (US Mountain Standard Time, UTC-07:00)  #    Comments [0]
 Sunday, September 21, 2008

Reflection in .Net is fairly commonplace and I've written it into dozens of applications.  Tonight I found a new case that I had not yet encountered: Creating a type that has a generic template parameter such as MyType<T>.

Without reflection, you would simply say: MyType<string> = new MyType<string>();.  But it is a bit more complicated creating the class dynamically at runtime, albeit very doable.

I found some helpful information online, but I really wish someone had just posted the following:

Activator.CreateInstance(Type.GetType(typeName).MakeGenericType(typeof(string)));

Let's deconstruct. 

- Activator.CreateInstance() creates an object from a type definition.  There are several ways of creating an object on the fly; this is only one of them.  You will need to add a reference to System.Reflection.

- Type.GetType(typeName) creates an object from a string definition of a type.  Again, many ways of doing this, but in this example, typeName = "namespace.namespace.className`1, fully-qualified assembly name", e.g. "NFC.Web.CustomType`1, NFC.Web".  Of course, your type name will be different, just make sure to use the fully-qualified class name and assembly name, seperated by a comma.

Note the red-highlighted code above; a generic class string must contain the `1 to indicate that it is a parameterized class.  If you had three generic parameters, you would mark it as `3 and so on.

- .MakeGenericType(params) - the crux of this solution.  Retrieves a type as a generic with the specified list of arguments.  In this example, we know the template argument and use typeof(x) to return its Type, but you could easily pass any (valid) type to this method.  In addition, as this method takes a params[], you can pass as many different template types into it.

 

- Tim Medora

 

posted on Sunday, September 21, 2008 8:40:45 PM (US Mountain Standard Time, UTC-07:00)  #    Comments [0]
 Saturday, August 02, 2008

Tonight I had a few orphaned sessions to a remote machine that were not being enumerated by Terminal Services Manager or a remote connection (from Computer Management).  I almost gave up and drove to the physical machine, but I found this trick online first.

Here's a handy way to view and manage sessions from the command prompt.

To List All Sessions

Start->Run->cmd

query session /server:xxx.xxx.xxx.xxx

To End a Session

Start->Run->cmd

reset session 1 /server:xxx.xxx.xxx.xxx

Note that "1" represents a session id.  You can see all available sessions from the previous "query" command.  Insert the correct number to terminate it.

Once you know these few commands, its actually quicker to manage remote sessions from the command prompt.

- Tim Medora

posted on Saturday, August 02, 2008 8:19:22 PM (US Mountain Standard Time, UTC-07:00)  #    Comments [0]
 Friday, July 25, 2008

Little tip I thought I'd share...as of the date of this posting (7/2008), when building connection strings to access a MaxDB instance, the password must be changed to all uppercase.

For anyone who's wondering, it is possible to connect to MaxDB with ASP.Net/C#.  Use the System.Data.Odbc library and a DSN to connect with only a few lines of code.

- Tim Medora

 

posted on Friday, July 25, 2008 1:19:54 PM (US Mountain Standard Time, UTC-07:00)  #    Comments [0]
 Monday, May 26, 2008
Today I was happily coding a .Net 3.5/SQL Server 2005 web application when things came to a grinding halt with the error:

A severe error occurred on the current command.  The results, if any, should be discarded.

I googled the error (of course), but found a dozen different answers and many of them required installing service packs or hotfixes.  While I'm not opposed to that, I knew that it shouldn't be necessary.

I'm sure there are many causes for this error, but here was mine:

BEGIN TRANSACTION;

BEGIN TRY

    IF( @UserId < 1 ) BEGIN

        IF( (SELECT count(UserId) FROM [User] WHERE Email = @Email) > 0) BEGIN
            SET @Status = 1;
            RETURN;

        END

...

See the problem? I'm returning without committing or rolling back my transaction.  While this is a stupid mistake on my part, the error message is quite ambiguous, but thankfully the solution is simple.  Before returning, insert cleanup GOTO cleanup such as:

BEGIN TRANSACTION;

BEGIN TRY

    IF( @UserId < 1 ) BEGIN

        IF( (SELECT count(UserId) FROM [User] WHERE Email = @Email) > 0) BEGIN
            SET @Status = 1;
            GOTO NoSuccessReturn;

        END

...


NoSuccessReturn:
    IF( @@TRANCOUNT > 0 )BEGIN   
        ROLLBACK TRANSACTION;
    END

    RETURN;


Hope this helps someone!

--Tim Medora


posted on Monday, May 26, 2008 2:50:51 PM (US Mountain Standard Time, UTC-07:00)  #    Comments [0]
 Monday, May 05, 2008

Most ASP.Net developers quickly learn that web.config file settings percolate from the top down.  This is commonly used to provide global configuration for a single web application, but it's pretty easy to forget that web.config settings can be inherited across different virtual directories.

For example:

1) Create a website in IIS.
2) Create a virtual directory for a second site underneath the IIS website.
3) Reference a type in the web.config for site #1, such as in a HttpHandler block.
4) Unless the second site has the type referenced in #3 (or it is in the GAC), second site will now immediately throw an exception, "Cannot load type xxx.xxx.xxx".

In web.config #1
<
httpHandlers>
   <add verb="GET" path="*.css.ashx" type="NFC.PublicWeb.UILogic.PathResolver,NFC.PublicWeb"/>
</httpHandlers>

This issue is caused because every virtual directory underneath the top-level website is inheriting settings from the top-most web.config.  Many of these inherited settings would go unnoticed, but as soon as the child virtual directory hits something it can't handle, it immediately throws a show-stopping (as all config errors are) exception.

Quick Solution?
Wrap application specific blocks of code in the LOCATION tag.  Obviously this must be used judiciously, but it's a useful fix to a sneaky problem.

<location path="." inheritInChildApplications="false">
   <
system.web>
      <httpHandlers>
         <add verb="GET" path="*.css.ashx" type="NFC.PublicWeb.UILogic.PathResolver,NFC.PublicWeb"/>
      </httpHandlers>
   </system.web>
</location>

For a detailed discussion of this topic, see this useful article on www.aspdotnetfaq.com.

posted on Monday, May 05, 2008 7:38:57 PM (US Mountain Standard Time, UTC-07:00)  #    Comments [0]
 Friday, May 02, 2008

Check out this brief whitepaper by Chris Szabo on a more elegant way of determining if the data encapsulated by an object is dirty or not.

Typical practice is to always save the object, dirty or not, which can be wasteful in a high-traffic scenario.  Alternatively, many developers maintain an IsDirty flag, which does the job, but isn't that elegant.  It also doesn't account for data that has "changed" but might actually be the same, such as when a user enters a value into a field that is bound to an object, and then undoes the operation.

http://www.netfusioncorporation.com/Downloads/2008/Intelligent%20Data%20Persistence.pdf

- Tim Medora

posted on Friday, May 02, 2008 4:13:36 PM (US Mountain Standard Time, UTC-07:00)  #    Comments [0]
 Friday, April 18, 2008

Actually, it's been more than a year... alot more.  But a year ago Processor Magazine interviewed me for my opinion on Windows Vista.

http://www.processor.com/editorial/article.asp?article=articles%2Fp2915%2F20p15%2F20p15.asp

I'm sure everyone is dying to see what I had to say.

A year later, I'm pretty much of the same opinion... I've survived and haven't had any major problems.  Throw a powerful computer at it, and it isn't half bad.

- Tim Medora

posted on Friday, April 18, 2008 11:44:26 AM (US Mountain Standard Time, UTC-07:00)  #    Comments [0]