Tuesday, December 29, 2009

Nested web.config files and connectionStrings (entry has already been added)

When using the Entity Framework (EF) recently, I ran into a situation where I received the following error message:
The entry 'myConnectionstring' has already been added...web.config line: 47
After investigating I found out this was due to my use of web.config files in nested directories. Here is the situation...

I have a reusable EF DAL (data access layer) that is used by several web services on a single web site. Several of these web services are in sub-folders with their own web.config files. This allows me to have custom settings for each service as well as being able to easily xcopy an entire directory and know I have all the correct settings. For the EF I have a connectionStrings key in the config files. In addition to the nested web.config files, I have the top-level config which also has the EF connectionStrings key.

When I tried to access a web service I would get the error above because .NET was merging the web.config files and found duplicate connectionString keys. To fix this I just had to add the following element within the connectionStrings section, directly before my key:
<remove name="myConnectionString" />
To facilitate knowing I can easily xcopy any web service, it is good practice to add this to all the web.config files, even the top-level one.

Sunday, December 27, 2009

XDocument / XElement - Save using a StringWriter as UTF-8 rather than UTF-16

One thing I find myself having to do on frequent projects is to save XML to a text file. I tend to use the .NET XDocument or XElement classes and use the Save() method. Once and a while I need to call Save() using a TextWriter. By default, when I do this the XML is written using a UTF-16 processing instruction as:

<?xml version="1.0" encoding="utf-16"?>

More often than not you want UTF-8; .NET XElement won't even read the UTF-16 contents back in using the Load() method (and things like IE won't be able to view it in the browser). To work around this problem I derive a new StringWriter and override the Encoding method:

public class StringWriterWithEncoding : StringWriter
{
private Encoding mEncoding;
public StringWriterWithEncoding(Encoding encoding)
{
mEncoding = encoding;
}

public override Encoding Encoding
{
get { return mEncoding; }
}
}

Now just use the new class and the XElement.Save() method to write as UTF-8:

XElement xml = XElement.Parse("<root/>");
using (StringWriterWithEncoding writer = new StringWriterWithEncoding(Encoding.UTF8))
{
xml.Save(writer);
Console.WriteLine(writer.ToString());
}

Wednesday, December 16, 2009

The row value(s) updated or deleted either do not make the row unique or they alter multiple rows

I was working with a Microsoft SQL database today (not mine thank goodness) that had duplicate rows; the table had no primary key defined. When I went to go delete the duplicate row (or even change it), I got the error:

The row value(s) updated or deleted either do not make the row unique or they alter multiple rows(2 rows)

It was somewhat hard to figure out how to delete the duplicate row. In the end, I was able to delete it by doing:

SET ROWCOUNT 1
DELETE FROM myTable WHERE statmentToSelectTheDuplicateRow

Another reason why to always define primary keys so you don't even get into this situation.

Saturday, October 24, 2009

Remote Desktop using NLA from XP to Server 2008 R2

I recently had to connect to my Server 2008 R2 computer (only allowing Network Level Authentication (NLA) for RD) from an older XP client running SP3. No luck at first. Turns out that to use NLA from XP SP3, I had to make two registry changes.

I found out how to do this on https://support.soundenterprises.net/index.php?_m=knowledgebase&_a=viewarticle&kbarticleid=221, but I also included that information below just in case the source link disappeared one day.



Enabling Network Level Authentication on Windows XP Service Pack 3 for access to Server 2008 via Remote Desktop

When connecting to a Windows 2008 Server using remote desktop from a Windows XP client running service pack 2 or earlier, you get the following error message:

"The remote computer requires Network Level Authentication, which your computer does not support."

To enable NLA in XP machines; first install XP SP3, then edit the registry settings on the XP client machine to allow NLA.

Next, configure XP for NLA as follows:

1. Click Start, click Run, type regedit, and then press ENTER.
2. In the navigation pane, locate and then click the following registry subkey: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa
3. In the details pane, right-click Security Packages, and then click Modify.
4. In the Value data box, type tspkg. Leave any data that is specific to other SSPs, and then click OK.
5. In the navigation pane, locate and then click the following registry subkey: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders
6. In the details pane, right-click SecurityProviders, and then click Modify.
7. In the Value data box, type credssp.dll. Leave any data that is specific to other SSPs, and then click OK.
8. Exit Registry Editor.
9. Restart the computer.

Thursday, October 1, 2009

Server 2008 R2 / ApplicationPoolIdentity / Databases

I recently set up a new website on a Windows Server 2008 R2 computer running IIS 7.5 and SQL Server 2008. The new site would not run...wouldn't even start (.NET security issus, database login error). After some painful investigation on the issues, I encapsulated the steps to correctly use IIS 7.5's new ApplicationPoolIdentity support and allow access to a SQL Server 2008 database.

Microsoft will continue to cramp down on security and the use of ApplicationPoolIdentity is the default settings for a new website (so I'm blogging this to help others and to remind myself).

To the best of my knowledge, here are the steps to get your site up and running on 2008 R2 (if you have any corrections or feedback, please comment):


1) Using IIS, select “Application Pools”. Right-click the pool to modify and
choose “Advanced Settings”. In the “Process Model” section:
a. Verify “Identify” is set to ApplicationPoolIdentity.
b. Verify “Load User Profile” is set to true.

2) Using IIS, select the site to modify. In the IIS section, double-click
“Authentication”. Next “Edit” the “Anonymous Authentication” name and verify
“Application pool identity” is chosen.

3) Using SQL Studio Management Studio, select “Security”, then “Logins”. Add
“New Login” using:
a. Set “Login name” to “IIS AppPool\yourIISSiteName”.
b. Select “Windows authentication” (don’t worry that this doesn’t resemble a
real account on the computer; click OK).

4) Optional for security flexibility on the site files:
a. Using Windows Explorer, right-click the site directory and choose
“Properties”. Select the “Security” tab and choose “Add”.
b. In the “Enter the object names select” box, enter
“IIS AppPool\yourIISSiteName”. Click OK.
c. Before leaving the “Permissions” dialog, customize the permissions for the
new account (read, write, execute, etc.).

Whew!

Monday, September 14, 2009

Simulated Annealing - Poker Solitaire and C#

I recently revisited the Simulated Annealing heuristic algorithm using C#. This algorithm is traditionally the choice for solving the Traveling Salesman problem, but I wanted to tackle another large combinatorial problem, Poker Solitaire.

For a description of the problem, visit Dr. Dobbs original article at:

http://www.ddj.com/184408203?pgno=16

How do you calculate a result with a solution set of 25 factorial (15,511,210,043,330,983,907,819,520)?

The Visual Studio 2008 solution (see below) provides a console application that repeatable executes a single annealing process, each time trying to optimize a 5x5 matrix of playing cards. The algorithm attempts to lay the cards out to optimize 12 poker hands (5 rows, 5 columns, 2 diagonals).

You can execute the console application using the syntax below, passing it the name of a text file that represents 25 cards for the 5x5 matrix.

C:> SimulatedSolitaire.Console.exe TestData\BestCards.txt

Download the Visual Studio 2008 solution by clicking here.

Wednesday, September 2, 2009

Is "simple" better?

Just thought I'd pass along a lesson that I continue to learn.

A couple of years ago I had the need to know my ever-changing home IP address. Granted there are some free tools like Dynamic DNS and others that do this, but I had some special requirements that the IP had to be placed on another server for special reasons.

When I wrote the code, I created a service that ran on my home server. I used a C# interface so that I could "one day" move other types of data from my home PC to a server. I also had to have Visual Studio create the service installer and manually install the service. I created my Visual Studio solution with nicely decoupoled projects (assemblies). I was a genius.

Recently I had to change some stuff in that piece of code. The more I thought about it (and tried to remember all the code parts), I realized had I just taken a pure TDD (test-driven development) approach I could have done it much simpler. I then sat down and wrote a simple console app main() with about 4 lines of code to call a web page with a magical query parameter that did everything I needed. A quick job creation in Windows Task Manager and things were now running nicely.

Much less code and more importantly, much easier to maintain and make sense of. I know we all hear often (and I preach it as well) that we are to develop "extensible" code, but the reality of it is that probably 90% of the code we write will never even need to be extended. Given that, a TDD attribute is warranted in many cases (if not all of them).

I'm still learning that "simple is better" a lot of the time.

Wednesday, August 26, 2009

Prevent XSS attacks

I found this link very helpful in understanding and providing a good set of rules for protecting against Cross Site Scripting (XSS) attacks.

http://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet

Tuesday, May 26, 2009

jQuery 1.3 Cheat Sheet

Looking for a handy cheat sheet of jQuery objects and methods? Here is a pretty good two page guide in PDF format.

jQuery 1.3 cheat sheet (2 pages, 8.5" x 11")

Sunday, May 24, 2009

How to install MVC 1.0 on a web server

Eventually you are probably going to want to install MVC on a web server. Assuming you do not have Visual Studio on that server, the command to install the MVC installation package is (all on a single command line):

msiexec /i AspNetMVC1.msi /q /l*v mvc.log MVC_SERVER_INSTALL="YES"

You will need to execute this command in an elevated command prompt window.

Wednesday, May 13, 2009

Learn jquery

Tired of your websites looking years old? Want a bit of that "Web 2.0" look-n-feel?

I highly recommend web developers learn jquery. The overhead of the included JavaScript (15K) and the learning curve are both so minimal that there shouldn't be an excuse for not using it.

There are not a lot of books out there on jquery yet (at least not around May 2009), but I would recommend this one.

Learning jQuery 1.3.

It's a pretty good book. The index is bad, but the coverage of jquery in the book should be well worth the read.

Thursday, April 16, 2009

Web developers should know CSS

I speak from experience when I say that web developers should understand the basics of cascading style sheets (CSS). Granted, when I first looked at CSS and tried using it for page layouts a few years ago, I couldn't understand why anyone would use CSS for layouts when we all used tables instead*.

Well, years later I'm convinced that tables are for presenting tabular data, not page layouts.

Developers don't have to be CSS gurus, but they should understand what a "div" really is and how a "float" style attribute works. They need to understand the "boxing model" and how IE handles it differently than do other browsers. CSS is much more than just applying different colors and text attributes.

If you want to take your web development skills up a notch, I recommend the following book I purchased a few years back. It is short, concise, and easy to read. Plus, as far as books go, it's pretty cheap.

CSS Mastery from Amazon

Update: A major advantage to knowing CSS is that it will make the adoption of tools such as jquery much easier!

*About the only time I favor a table layout is when I have to bottom-align tabular data and don't want to set a fixed height for content.

Tuesday, March 17, 2009

Windows Explorer - Setting default size and location

Want to set the default size and window location for Windows Explorer on Vista or later?

I've got a new monitor that is larger than my old one. When I would open Windows Explorer the first thing I would always do is resize it to larger size.

I found out you can set the default Explorer size and windows location by simply holding the SHIFT key down when closing the window. Presto!

Sunday, March 8, 2009

Catch (Exception e): Right or wrong?

I've long heard that you shouldn't throw a type Exception in C#. I try to always throw a type derived from Exception.

In addition, I've also read many brief snippets over the years that says you shouldn't write C# code like:

catch(Exception e)
{
...
}

I recently read the best explanation of this in Microsoft's MSDN Magazine (Feb. 2009). The article is entitled Handling Corrupted State Exceptions and would highly recommend those programming in C# to read the full article. It also provides details about how exception handling will change a bit in .NET 4.0.

A read well worth it!

http://msdn.microsoft.com/en-us/magazine/dd419661.aspx

Tuesday, February 17, 2009

ASP.NET CodeBehind vs. CodeFile

I use Visual Studio 2008. Once and a while I get a .NET error that causes me to modify the @Page directive from CodeBehind to CodeFile, or visa-versa.

Folks tend to give all types of lengthy explanations on when to use one vs. the other. Here is a quick explanation...

.NET Web Sites ---> Use CodeFile
.NET Web Apps ---> Use CodeBehind

Done. Any questions?

Tuesday, February 3, 2009

Remove / Uninstall old devices (network card)

I've run into this twice during the past month so I figured I had better post something about it.

Once and a while I remove something like a network or graphics card from a computer. If I do this while the computer is off, then the next time the computer is turned on, the old device is still there, sometimes hidden. Attempts to install a replacement device may either fail because of "not enough resources" or something else like a PCI slot conflict.

First, before uninstalling a device, use the device manager and perform an Uninstall. If you do that, the information below won't be needed. But if you are like me and remove device while computers are off (normally old ones sitting in closets), you may need to do the following...

Start the computer and open a console window (may want to run with Admin privs for Vista or later operating systems).

Set the following environment variable:

set devmgr_show_nonpresent_devices=1

Now open the device manager via the console window (must be done via the console window since this is where the new environment variable exists).

devmgmt.msc

On the View menu, enable "Show Hidden Devices" then find the old/removed device and uninstall it.

For best results, reboot!

Saturday, January 31, 2009

Obtaining computer SID and Processor ID using C#

Sometimes you have to track a unique identifier for an application (e.g. license key registration). Here are two small C# methods to get the Windows SID (Security ID) and the motherboard processor ID (may be more than one).

using System;
using System.Linq;
using System.Management;
using System.Security.Principal;

namespace ConsoleTest
{
class Program
{
static void Main(string[] args)
{
new Program().Run(args);
}

private void Run(string[] args)
{
string sid = UserSecurityId();
Console.WriteLine("The SID is: {0}", sid);

string[] processorIds = ComputerProcessorId();
foreach (string id in processorIds)
{
Console.WriteLine("Processor ID: {0}", id);
}
}

public string UserSecurityId()
{
return WindowsIdentity.GetCurrent().User.AccountDomainSid.ToString();
}

public string[] ComputerProcessorId()
{
return new ManagementObjectSearcher("Select * from Win32_Processor")
.Get()
.OfType<ManagementObject>()
.Select(o => o["ProcessorID"].ToString())
.ToArray();
}
}
}

Sunday, January 25, 2009

TFS Lightweight Scrum Template Graphic

Here is an 17" x 11" graphic of the TFS Lightweight Scrum template. It is pretty much the same as the one on the codeplex site (which is terrible quality). The scaling of the graphic is such that you can place it on 8.5" x 11" paper as well.

Enjoy.

Click here for graphic.

Sunday, January 18, 2009

Converting Office 2007 Excel to XML using C#

Don't want Office 2007 installed on your web server to access Excel 2007 content?

Here is a Visual Studio C# solution that demonstrates how to read an Excel 2007 workbook, converting it to XML. You don't need Office 2007 installed in order to do this! Once Excel content is in XML format you can process it easier using transformations tools or other language code.

The solution code uses .NET 3.5 XML support and LINQ. The solution also contains an example console application that will take an Excel 2007 file name on the command-line and convert it to XML via the console. Everything should run out-of-the-box using an example Excel 2007 file that is included; just run the example application and accept the default file name to read.

The quickest way to learn how to use the ExcelReader class, and its options, is to examine the brief Program.cs file in PCarver.OfficeXml.ExampleExcel project. You an register for events to transform cell contents and ignore certain rows (see example code).

Download only the binary files for converting Excel to XML:

Click here for binaries/executables

Download the full Visual Studio Solution:

Click here for Visual Studio 2008 Solution

If you have any bug fixes or nice enhancements, please post a comment and let me know.

Information from Microsoft on these formats is found at:

http://msdn.microsoft.com/en-us/library/aa338205.aspx.

Can't RDP? How to enable / disable virtual machine firewall for Azure VM

Oh no!  I accidentally blocked the RDP port on an Azure virtual machine which resulted in not being able to log into the VM anymore.  I did ...